blob: 4cc658ab963cadd3992e20dfd37b51116e464763 [file] [log] [blame]
<!doctype html><html lang=en class=no-js><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name=generator content="Hugo 0.102.3"><link rel=canonical type=text/html href=/docs/guides/><link rel=alternate type=application/rss+xml href=/docs/guides/index.xml><meta name=robots content="noindex, nofollow"><link rel="shortcut icon" href=/favicons/favicon.ico><link rel=apple-touch-icon href=/favicons/apple-touch-icon-180x180.png sizes=180x180><link rel=icon type=image/png href=/favicons/favicon-16x16.png sizes=16x16><link rel=icon type=image/png href=/favicons/favicon-32x32.png sizes=32x32><link rel=icon type=image/png href=/favicons/android-36x36.png sizes=36x36><link rel=icon type=image/png href=/favicons/android-48x48.png sizes=48x48><link rel=icon type=image/png href=/favicons/android-72x72.png sizes=72x72><link rel=icon type=image/png href=/favicons/android-96x96.png sizes=96x96><link rel=icon type=image/png href=/favicons/android-144x144.png sizes=144x144><link rel=icon type=image/png href=/favicons/android-192x192.png sizes=192x192><title>GUIDES | HugeGraph</title><meta name=description content><meta property="og:title" content="GUIDES"><meta property="og:description" content="Apache HugeGraph site"><meta property="og:type" content="website"><meta property="og:url" content="/docs/guides/"><meta property="og:site_name" content="HugeGraph"><meta itemprop=name content="GUIDES"><meta itemprop=description content="Apache HugeGraph site"><meta name=twitter:card content="summary"><meta name=twitter:title content="GUIDES"><meta name=twitter:description content="Apache HugeGraph site"><link rel=preload href=/scss/main.min.14ea575cb35d93d46ff8681b2334f40fd46243c100c5c39f5a841b931fae2d40.css as=style><link href=/scss/main.min.14ea575cb35d93d46ff8681b2334f40fd46243c100c5c39f5a841b931fae2d40.css rel=stylesheet integrity><script src=https://code.jquery.com/jquery-3.5.1.min.js integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin=anonymous></script>
<link rel=stylesheet href=/css/prism.css><script type=application/javascript>var doNotTrack=!1;doNotTrack||(window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)},ga.l=+new Date,ga("create","UA-00000000-0","auto"),ga("send","pageview"))</script><script async src=https://www.google-analytics.com/analytics.js></script></head><body class=td-section><header><nav class="js-navbar-scroll navbar navbar-expand navbar-dark flex-column flex-md-row td-navbar"><a class=navbar-brand href=/><span class=navbar-logo><svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16"><defs><style>.cls-1{fill:none;stroke:#fff;stroke-miterlimit:10;stroke-width:.5px;opacity:.3}.cls-2{fill:#229efa}.cls-3{fill:#9948f7}.cls-4{fill:#33bc7a}.cls-5{fill:url(#未命名的渐变_3)}.cls-6{fill:url(#未命名的渐变_13)}.cls-7{fill:url(#未命名的渐变_11)}</style><linearGradient id="未命名的渐变_3" x1="6.16" y1="14.63" x2="6.16" y2="6.01" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#2e3192"/><stop offset="0" stop-color="#229efa"/><stop offset=".44" stop-color="#239cf8"/><stop offset=".6" stop-color="#2795f2"/><stop offset=".71" stop-color="#2d8ae8"/><stop offset=".81" stop-color="#3679d9"/><stop offset=".89" stop-color="#4263c6"/><stop offset=".95" stop-color="#5048af"/><stop offset="1" stop-color="#5c319b"/></linearGradient><linearGradient id="未命名的渐变_13" x1="10.75" y1="8.2" x2="4.49" y2="1.94" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#991146"/><stop offset="0" stop-color="#326b4e"/><stop offset=".02" stop-color="#3a685c"/><stop offset=".07" stop-color="#506180"/><stop offset=".13" stop-color="#645aa0"/><stop offset=".19" stop-color="#7554bc"/><stop offset=".26" stop-color="#8250d2"/><stop offset=".35" stop-color="#8d4ce3"/><stop offset=".45" stop-color="#944aee"/><stop offset=".6" stop-color="#9848f5"/><stop offset="1" stop-color="#9948f7"/></linearGradient><linearGradient id="未命名的渐变_11" x1="15.34" y1="6.67" x2="7.88" y2="10.98" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#33bc7a"/><stop offset=".45" stop-color="#32ba7a"/><stop offset=".61" stop-color="#2fb37c"/><stop offset=".73" stop-color="#29a87e"/><stop offset=".82" stop-color="#219782"/><stop offset=".9" stop-color="#168186"/><stop offset=".97" stop-color="#09668b"/><stop offset="1" stop-color="#03598e"/></linearGradient></defs><title>logo</title><rect class="cls-1" x="-143.14" y="-373.46" width="597.8" height="424.44"/><circle class="cls-2" cx="12.02" cy="1.83" r="1.33"/><circle class="cls-3" cx="12.02" cy="14.17" r="1.33"/><circle class="cls-4" cx="1.33" cy="8" r="1.33"/><path class="cls-5" d="M7.91 10h0a2.65 2.65.0 01-.23-3.74A1.75 1.75.0 017.91 6h0A2.66 2.66.0 014.4 6h0a1.81 1.81.0 01.24.24A2.65 2.65.0 014.4 10h0a2.62 2.62.0 00-.89 2 2.65 2.65.0 104.4-2z"/><path class="cls-6" d="M12.19 5.49a2.78 2.78.0 01-.5.11A2.64 2.64.0 018.76 3.5h0a2.65 2.65.0 10-2.6 3.17A2.6 2.6.0 007 6.53H7a2.65 2.65.0 013.44 2 2.94 2.94.0 010-.51 2.65 2.65.0 011.75-2.53z"/><path class="cls-7" d="M13 5.35a2.64 2.64.0 00-2.59 2.12h0a3 3 0 01-.08.32A2.65 2.65.0 017.54 9.58a2.86 2.86.0 00.37.41h0a2.63 2.63.0 01.9 2 2.84 2.84.0 01-.05.51 2.64 2.64.0 013.12-2.06l.32.08h0a2.6 2.6.0 00.84.14 2.65 2.65.0 100-5.3z"/></svg></span><span class=font-weight-bold>HugeGraph</span></a><div class="td-navbar-nav-scroll ml-md-auto" id=main_navbar><ul class="navbar-nav mt-2 mt-lg-0"><li class="nav-item mr-4 mb-2 mb-lg-0"><a class=nav-link href=/docs/><i class='fas fa-book pr-2'></i><span>Documentation</span></a></li><li class="nav-item mr-4 mb-2 mb-lg-0"><a class=nav-link href=https://github.com/apache/incubator-hugegraph target=_blank><i class='fab fa-github pr-2'></i><span>GitHub</span></a></li><li class="nav-item mr-4 mb-2 mb-lg-0"><a class=nav-link href=/docs/download/download/><i class='fas fa-download pr-2'></i><span>Download</span></a></li><li class="nav-item mr-4 mb-2 mb-lg-0"><a class=nav-link href=/community/><span>Community</span></a></li><li class="nav-item dropdown mr-4 d-none d-lg-block"><a class="nav-link dropdown-toggle" href=# id=navbarDropdown role=button data-toggle=dropdown aria-haspopup=true aria-expanded=false>English</a><div class=dropdown-menu aria-labelledby=navbarDropdownMenuLink><a class=dropdown-item href=/cn/docs/guides/>中文</a></div></li></ul></div><div class="navbar-nav d-none d-lg-block"></div></nav></header><div class="container-fluid td-outer"><div class=td-main><div class="row flex-xl-nowrap"><main class="col-12 col-md-9 col-xl-8 pl-md-5" role=main><div class=td-content><div class="pageinfo pageinfo-primary d-print-none"><p>This is the multi-page printable view of this section.
<a href=# onclick="return print(),!1">Click here to print</a>.</p><p><a href=/docs/guides/>Return to the regular view of this page</a>.</p></div><h1 class=title>GUIDES</h1><ul><li>1: <a href=#pg-dcb89d888ea6f4146ace522d76fe2776>HugeGraph Architecture Overview</a></li><li>2: <a href=#pg-3d0f9ef831ef5d7d11acfb09140359fa>HugeGraph Design Concepts</a></li><li>3: <a href=#pg-96a920d19e01666d95eded506d502ab4>HugeGraph Plugin mechanism and plug-in extension process</a></li><li>4: <a href=#pg-2c9db416c8d78f898d52c91ec12535d4>Backup and Restore</a></li><li>5: <a href=#pg-3465b699399f48689cdc6b5e59a10d69>FAQ</a></li><li>6: <a href=#pg-d54c862d45861ca39a945d90325e3909>Security Report</a></li></ul><div class=content></div></div><div class=td-content><h1 id=pg-dcb89d888ea6f4146ace522d76fe2776>1 - HugeGraph Architecture Overview</h1><h3 id=1-overview>1 Overview</h3><p>As a general-purpose graph database product, HugeGraph needs to possess basic graph database functionality. HugeGraph supports two types of graph computation: OLTP and OLAP. For OLTP, it implements the <a href=https://tinkerpop.apache.org>Apache TinkerPop3</a> framework and supports the <a href=https://tinkerpop.apache.org/gremlin.html>Gremlin</a> and <a href=https://en.wikipedia.org/wiki/Cypher>Cypher</a> query languages. It comes with a complete application toolchain and provides a plugin-based backend storage driver framework.</p><p>Below is the overall architecture diagram of HugeGraph:</p><div style=text-align:center><img src=/docs/images/design/architectural-revised.png alt=image></div><p>HugeGraph consists of three layers of functionality: the application layer, the graph engine layer, and the storage layer.</p><ul><li>Application Layer:<ul><li><a href=/docs/quickstart/hugegraph-hubble/>Hubble</a>: An all-in-one visual analytics platform that covers the entire process of data modeling, rapid data import, online and offline analysis of data, and unified management of graphs. It provides a guided workflow for operating graph applications.</li><li><a href=/docs/quickstart/hugegraph-loader/>Loader</a>: A data import component that can transform data from various sources into vertices and edges and bulk import them into the graph database.</li><li><a href=/docs/quickstart/hugegraph-tools/>Tools</a>: Command-line tools for deploying, managing, and backing up/restoring data in HugeGraph.</li><li><a href=/docs/quickstart/hugegraph-computer/>Computer</a>: A distributed graph processing system (OLAP) that implements <a href=https://kowshik.github.io/JPregel/pregel_paper.pdf>Pregel</a>. It can run on Kubernetes.</li><li><a href=/docs/quickstart/hugegraph-client/>Client</a>: HugeGraph client written in Java. Users can use the client to operate HugeGraph using Java code. Support for other languages such as Python, Go, and C++ may be provided in the future.</li></ul></li><li><a href=/docs/quickstart/hugegraph-server/>Graph Engine Layer</a>:<ul><li>REST Server: Provides a RESTful API for querying graph/schema information, supports the <a href=https://tinkerpop.apache.org/gremlin.html>Gremlin</a> and <a href=https://en.wikipedia.org/wiki/Cypher>Cypher</a> query languages, and offers APIs for service monitoring and operations.</li><li>Graph Engine: Supports both OLTP and OLAP graph computation types, with OLTP implementing the <a href=https://tinkerpop.apache.org>Apache TinkerPop3</a> framework.</li><li>Backend Interface: Implements the storage of graph data to the backend.</li></ul></li><li>Storage Layer:<ul><li>Storage Backend: Supports multiple built-in storage backends (RocksDB/MySQL/HBase/&mldr;) and allows users to extend custom backends without modifying the existing source code.</li></ul></li></ul></div><div class=td-content style=page-break-before:always><h1 id=pg-3d0f9ef831ef5d7d11acfb09140359fa>2 - HugeGraph Design Concepts</h1><h3 id=1-property-graph>1. Property Graph</h3><p>There are two common graph data representation models, namely the RDF (Resource Description Framework) model and the Property Graph (Property Graph) model.
Both RDF and Property Graph are the most basic and well-known graph representation modes, and both can represent entity-relationship modeling of various graphs.
RDF is a W3C standard, while Property Graph is an industry standard and is widely supported by graph database vendors. HugeGraph currently uses Property Graph.</p><p>The storage concept model corresponding to HugeGraph is also designed with reference to Property Graph. For specific examples, see the figure below:
( This figure is outdated for the old version design, please ignore it and update it later )</p><p><img src=/docs/images/design/PropertyGraph.png alt=image></p><p>Inside HugeGraph, each vertex/edge is identified by a unique VertexId/EdgeId, and the attributes are stored inside the corresponding vertex/edge.
The relationship/mapping between vertices is stored through edges.</p><p>When the vertex attribute value is stored by edge pointer, if you want to update a vertex-specific attribute value, you can directly write it by overwriting.
The disadvantage is that the VertexId is redundantly stored; if you want to update the attribute of the relationship, you need to use the read-and-modify method ,
read all attributes first, modify some attributes, and then write to the storage system, the update efficiency is low. According to experience, there are more
requirements for modifying vertex attributes, but less for edge attributes. For example, calculations such as PageRank and Graph Cluster require frequent
modification of vertex attribute values.</p><h3 id=2-graph-partition-scheme>2. Graph Partition Scheme</h3><p>For distributed graph databases, there are two partition storage methods for graphs: Edge Cut and Vertex Cut, as shown in the following figure. When using the
Edge Cut method to store graphs, any vertex will only appear on one machine, while edges may be distributed on different machines. This storage method may lead
to multiple storage of edges. When using the Vertex Cut method to store graphs, any edge will only appear on one machine, and each same point may be distributed
to different machines. This storage method may result in multiple storage of vertices.</p><p><img src=/docs/images/design/GraphCut.png alt=image></p><p>The EdgeCut partition scheme can support high-performance insert and update operations, while the VertexCut partition scheme is more suitable for static graph query
analysis, so EdgeCut is suitable for OLTP graph query, and VertexCut is more suitable for OLAP graph query. HugeGraph currently adopts the partition scheme of EdgeCut.</p><h3 id=3-vertexid-strategy>3. VertexId Strategy</h3><p>Vertex of HugeGraph supports three ID strategies. Different VertexLabels in the same graph database can use different Id strategies. Currently, the Id strategies
supported by HugeGraph are:</p><ul><li>Automatic generation (AUTOMATIC): Use the Snowflake algorithm to automatically generate a globally unique Id, Long type;</li><li>Primary Key (PRIMARY_KEY): Generate Id through VertexLabel+PrimaryKeyValues, String type;</li><li>Custom (CUSTOMIZE_STRING|CUSTOMIZE_NUMBER): User-defined Id, which is divided into two types: String and Long, and you need to ensure the uniqueness of the Id yourself;</li></ul><p>The default Id policy is AUTOMATIC, if the user calls the primaryKeys() method and sets the correct PrimaryKeys, the PRIMARY_KEY policy is automatically enabled.
After enabling the PRIMARY_KEY strategy, HugeGraph can implement data deduplication based on PrimaryKeys.</p><ol><li>AUTOMATIC ID Policy</li></ol><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java><span style=display:flex><span><span style=color:#000>schema</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>vertexLabel</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#4e9a06>&#34;person&#34;</span><span style=color:#ce5c00;font-weight:700>)</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>useAutomaticId</span><span style=color:#ce5c00;font-weight:700>()</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>properties</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#4e9a06>&#34;name&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;age&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;city&#34;</span><span style=color:#ce5c00;font-weight:700>)</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>create</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span><span style=color:#000>graph</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>addVertex</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>T</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>label</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;person&#34;</span><span style=color:#ce5c00;font-weight:700>,</span><span style=color:#4e9a06>&#34;name&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;marko&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;age&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#000>18</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;city&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;Beijing&#34;</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span></code></pre></div><ol start=2><li>PRIMARY_KEY ID policy</li></ol><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java><span style=display:flex><span><span style=color:#000>schema</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>vertexLabel</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#4e9a06>&#34;person&#34;</span><span style=color:#ce5c00;font-weight:700>)</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>usePrimaryKeyId</span><span style=color:#ce5c00;font-weight:700>()</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>properties</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#4e9a06>&#34;name&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;age&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;city&#34;</span><span style=color:#ce5c00;font-weight:700>)</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>primaryKeys</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#4e9a06>&#34;name&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;age&#34;</span><span style=color:#ce5c00;font-weight:700>)</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>create</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span><span style=color:#000>graph</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>addVertex</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>T</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>label</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;person&#34;</span><span style=color:#ce5c00;font-weight:700>,</span><span style=color:#4e9a06>&#34;name&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;marko&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;age&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#000>18</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;city&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;Beijing&#34;</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span></code></pre></div><ol start=3><li>CUSTOMIZE_STRING ID Policy</li></ol><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java><span style=display:flex><span><span style=color:#000>schema</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>vertexLabel</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#4e9a06>&#34;person&#34;</span><span style=color:#ce5c00;font-weight:700>)</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>useCustomizeStringId</span><span style=color:#ce5c00;font-weight:700>()</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>properties</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#4e9a06>&#34;name&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;age&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;city&#34;</span><span style=color:#ce5c00;font-weight:700>)</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>create</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span><span style=color:#000>graph</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>addVertex</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>T</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>label</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;person&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#000>T</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>id</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;123456&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;name&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;marko&#34;</span><span style=color:#ce5c00;font-weight:700>,</span><span style=color:#4e9a06>&#34;age&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#000>18</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;city&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;Beijing&#34;</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span></code></pre></div><ol start=4><li>CUSTOMIZE_NUMBER ID Policy</li></ol><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java><span style=display:flex><span><span style=color:#000>schema</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>vertexLabel</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#4e9a06>&#34;person&#34;</span><span style=color:#ce5c00;font-weight:700>)</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>useCustomizeNumberId</span><span style=color:#ce5c00;font-weight:700>()</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>properties</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#4e9a06>&#34;name&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;age&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;city&#34;</span><span style=color:#ce5c00;font-weight:700>)</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>create</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span><span style=color:#000>graph</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>addVertex</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>T</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>label</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;person&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#000>T</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>id</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#000>123456</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;name&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;marko&#34;</span><span style=color:#ce5c00;font-weight:700>,</span><span style=color:#4e9a06>&#34;age&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#000>18</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;city&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;Beijing&#34;</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span></code></pre></div><p>If users need Vertex deduplication, there are three options:</p><ol><li>Adopt PRIMARY_KEY strategy, automatic overwriting, suitable for batch insertion of large amount of data, users cannot know whether overwriting has occurred</li><li>Adopt AUTOMATIC strategy, read-and-modify, suitable for small data insertion, users can clearly know whether overwriting occurs</li><li>Using the CUSTOMIZE_STRING or CUSTOMIZE_NUMBER strategy, the user guarantees the uniqueness</li></ol><h3 id=4-edgeid-policy>4. EdgeId policy</h3><p>The EdgeId of HugeGraph is composed of <code>srcVertexId</code> + <code>edgeLabel</code> + <code>sortKey</code> + <code>tgtVertexId</code>. Among them <code>sortKey</code> is an important concept of HugeGraph.
There are two reasons for adding Edge sortKeyas the unique ID of Edge:</p><ol><li>If there are multiple edges of the same Label between two vertices, they can be sortKeydistinguished by</li><li>For SuperNode nodes, it can be sortKeysorted and truncated by.</li></ol><p>Since EdgeId is composed of <code>srcVertexId</code> + <code>edgeLabel</code> + <code>sortKey</code> + <code>tgtVertexId</code>, HugeGraph will automatically overwrite when the same Edge is inserted
multiple times to achieve deduplication. It should be noted that the properties of Edge will also be overwritten in the batch insert mode.</p><p>In addition, because HugeGraph&rsquo;s EdgeId adopts an automatic deduplication strategy, HugeGraph considers that there is only one edge in the case of self-loop
(a vertex has an edge pointing to itself). The graph has two edges.</p><blockquote><p>The edges of HugeGraph only support directed edges, and undirected edges can be realized by creating two edges, Out and In.</p></blockquote><h3 id=5-hugegraph-transaction-overview>5. HugeGraph transaction overview</h3><h5 id=tinkerpop-transaction-overview>TinkerPop transaction overview</h5><p>A TinkerPop transaction refers to a unit of work that performs operations on the database. A set of operations within a transaction either succeeds or all fail. For a detailed introduction, please refer to the official documentation of TinkerPop: <a href=http://tinkerpop.apache.org/docs/current/reference/#transactions>http://tinkerpop.apache.org/docs/current/reference/#transactions</a>:http://tinkerpop.apache.org/docs/current/reference/#transactions</p><h5 id=tinkerpop-transaction-overview-1>TinkerPop transaction overview</h5><ul><li>open open transaction</li><li>commit commit transaction</li><li>rollback rollback transaction</li><li>close closes the transaction</li></ul><h5 id=tinkerpop-transaction-specification>TinkerPop transaction specification</h5><ul><li>The transaction must be explicitly committed before it can take effect (the modification operation can only be seen by the query in this transaction if it is not committed)</li><li>A transaction must be opened before it can be committed or rolled back</li><li>If the transaction setting is automatically turned on, there is no need to explicitly turn it on (the default method), if it is set to be turned on manually, it must be turned on explicitly</li><li>When the transaction is closed, you can set three modes: automatic commit, automatic rollback (default mode), manual (explicit shutdown is prohibited), etc.</li><li>The transaction must be closed after committing or rolling back</li><li>The transaction must be open after the query</li><li>Transactions (non-threaded tx) must be thread-isolated, and multi-threaded operations on the same transaction do not affect each other</li></ul><p>For more transaction specification use cases, see: <a href=https://github.com/apache/tinkerpop/blob/master/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/TransactionTest.java>Transaction Test</a></p><h5 id=hugegraph-transaction-implementation>HugeGraph transaction implementation</h5><ul><li>All operations in a transaction either succeed or fail</li><li>A transaction can only read what has been committed by another transaction (Read committed)</li><li>All uncommitted operations can be queried in this transaction, including:<ul><li>Adding a vertex can query the vertex</li><li>Delete a vertex to filter out the vertex</li><li>Deleting a vertex can filter out the related edges of the vertex</li><li>Adding an edge can query the edge</li><li>Delete edge can filter out the edge</li><li>Adding/modifying (vertex, edge) attributes can take effect when querying</li><li>Delete (vertex, edge) attributes can take effect at query time</li></ul></li><li>All uncommitted operations become invalid after the transaction is rolled back, including:<ul><li>Adding and deleting vertices and edges</li><li>Addition/modification, deletion of attributes</li></ul></li></ul><p>Example: One transaction cannot read another transaction&rsquo;s uncommitted content</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java><span style=display:flex><span> <span style=color:#204a87;font-weight:700>static</span> <span style=color:#204a87;font-weight:700>void</span> <span style=color:#000>testUncommittedTx</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#204a87;font-weight:700>final</span> <span style=color:#000>HugeGraph</span> <span style=color:#000>graph</span><span style=color:#ce5c00;font-weight:700>)</span> <span style=color:#204a87;font-weight:700>throws</span> <span style=color:#000>InterruptedException</span> <span style=color:#ce5c00;font-weight:700>{</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>final</span> <span style=color:#000>CountDownLatch</span> <span style=color:#000>latchUncommit</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#204a87;font-weight:700>new</span> <span style=color:#000>CountDownLatch</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>1</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>final</span> <span style=color:#000>CountDownLatch</span> <span style=color:#000>latchRollback</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#204a87;font-weight:700>new</span> <span style=color:#000>CountDownLatch</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>1</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#000>Thread</span> <span style=color:#000>thread</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#204a87;font-weight:700>new</span> <span style=color:#000>Thread</span><span style=color:#ce5c00;font-weight:700>(()</span> <span style=color:#ce5c00;font-weight:700>-&gt;</span> <span style=color:#ce5c00;font-weight:700>{</span>
</span></span><span style=display:flex><span> <span style=color:#8f5902;font-style:italic>// this is a new transaction in the new thread
</span></span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic></span> <span style=color:#000>graph</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>tx</span><span style=color:#ce5c00;font-weight:700>().</span><span style=color:#c4a000>open</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#000>System</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>out</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>println</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#4e9a06>&#34;current transaction operations&#34;</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#000>Vertex</span> <span style=color:#000>james</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#000>graph</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>addVertex</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>T</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>label</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;author&#34;</span><span style=color:#ce5c00;font-weight:700>,</span>
</span></span><span style=display:flex><span> <span style=color:#4e9a06>&#34;id&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#000>1</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;name&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;James Gosling&#34;</span><span style=color:#ce5c00;font-weight:700>,</span>
</span></span><span style=display:flex><span> <span style=color:#4e9a06>&#34;age&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#000>62</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;lived&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;Canadian&#34;</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span> <span style=color:#000>Vertex</span> <span style=color:#000>java</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#000>graph</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>addVertex</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>T</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>label</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;language&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;name&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#4e9a06>&#34;java&#34;</span><span style=color:#ce5c00;font-weight:700>,</span>
</span></span><span style=display:flex><span> <span style=color:#4e9a06>&#34;versions&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#000>Arrays</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>asList</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>6</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#000>7</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#000>8</span><span style=color:#ce5c00;font-weight:700>));</span>
</span></span><span style=display:flex><span> <span style=color:#000>james</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>addEdge</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#4e9a06>&#34;created&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#000>java</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#8f5902;font-style:italic>// we can query the uncommitted records in the current transaction
</span></span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic></span> <span style=color:#000>System</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>out</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>println</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#4e9a06>&#34;current transaction assert&#34;</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>assert</span> <span style=color:#000>graph</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>vertices</span><span style=color:#ce5c00;font-weight:700>().</span><span style=color:#c4a000>hasNext</span><span style=color:#ce5c00;font-weight:700>()</span> <span style=color:#ce5c00;font-weight:700>==</span> <span style=color:#204a87;font-weight:700>true</span><span style=color:#ce5c00;font-weight:700>;</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>assert</span> <span style=color:#000>graph</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>edges</span><span style=color:#ce5c00;font-weight:700>().</span><span style=color:#c4a000>hasNext</span><span style=color:#ce5c00;font-weight:700>()</span> <span style=color:#ce5c00;font-weight:700>==</span> <span style=color:#204a87;font-weight:700>true</span><span style=color:#ce5c00;font-weight:700>;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#000>latchUncommit</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>countDown</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>try</span> <span style=color:#ce5c00;font-weight:700>{</span>
</span></span><span style=display:flex><span> <span style=color:#000>latchRollback</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>await</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>}</span> <span style=color:#204a87;font-weight:700>catch</span> <span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>InterruptedException</span> <span style=color:#000>e</span><span style=color:#ce5c00;font-weight:700>)</span> <span style=color:#ce5c00;font-weight:700>{</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>throw</span> <span style=color:#204a87;font-weight:700>new</span> <span style=color:#000>RuntimeException</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>e</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>}</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#000>System</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>out</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>println</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#4e9a06>&#34;current transaction rollback&#34;</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span> <span style=color:#000>graph</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>tx</span><span style=color:#ce5c00;font-weight:700>().</span><span style=color:#c4a000>rollback</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>});</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#000>thread</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>start</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#8f5902;font-style:italic>// query none result in other transaction when not commit()
</span></span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic></span> <span style=color:#000>latchUncommit</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>await</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span> <span style=color:#000>System</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>out</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>println</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#4e9a06>&#34;other transaction assert for uncommitted&#34;</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>assert</span> <span style=color:#ce5c00;font-weight:700>!</span><span style=color:#000>graph</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>vertices</span><span style=color:#ce5c00;font-weight:700>().</span><span style=color:#c4a000>hasNext</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>assert</span> <span style=color:#ce5c00;font-weight:700>!</span><span style=color:#000>graph</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>edges</span><span style=color:#ce5c00;font-weight:700>().</span><span style=color:#c4a000>hasNext</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#000>latchRollback</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>countDown</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span> <span style=color:#000>thread</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>join</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#8f5902;font-style:italic>// query none result in other transaction after rollback()
</span></span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic></span> <span style=color:#000>System</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>out</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>println</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#4e9a06>&#34;other transaction assert for rollback&#34;</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>assert</span> <span style=color:#ce5c00;font-weight:700>!</span><span style=color:#000>graph</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>vertices</span><span style=color:#ce5c00;font-weight:700>().</span><span style=color:#c4a000>hasNext</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>assert</span> <span style=color:#ce5c00;font-weight:700>!</span><span style=color:#000>graph</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>edges</span><span style=color:#ce5c00;font-weight:700>().</span><span style=color:#c4a000>hasNext</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>}</span>
</span></span></code></pre></div><h5 id=principle-of-transaction-realization>Principle of transaction realization</h5><ul><li>The server internally realizes isolation by binding transactions to threads (ThreadLocal)</li><li>The uncommitted content of this transaction overwrites the old data in chronological order for this transaction to query the latest version of data</li><li>The bottom layer relies on the back-end database to ensure transaction atomicity (for example, the batch interface of Cassandra/RocksDB guarantees atomicity)</li></ul><h6 id=notice>Notice</h6><blockquote><p>The RESTful API does not expose the transaction interface for the time being</p></blockquote><blockquote><p>TinkerPop API allows open transactions, which are automatically closed when the request is completed (Gremlin Server forces close)</p></blockquote></div><div class=td-content style=page-break-before:always><h1 id=pg-96a920d19e01666d95eded506d502ab4>3 - HugeGraph Plugin mechanism and plug-in extension process</h1><h3 id=background>Background</h3><ol><li>HugeGraph is not only open source and open, but also simple and easy to use. General users can easily add plug-in extension functions without changing the source code.</li><li>HugeGraph supports a variety of built-in storage backends, and also allows users to extend custom backends without changing the existing source code.</li><li>HugeGraph supports full-text search. The full-text search function involves word segmentation in various languages. Currently, there are 8 built-in Chinese word
breakers, and it also allows users to expand custom word breakers without changing the existing source code.</li></ol><h3 id=scalable-dimension>Scalable dimension</h3><p>Currently, the plug-in method provides extensions in the following dimensions:</p><ul><li>backend storage</li><li>serializer</li><li>Custom configuration items</li><li>tokenizer</li></ul><h3 id=plug-in-implementation-mechanism>Plug-in implementation mechanism</h3><ol><li>HugeGraph provides a plug-in interface HugeGraphPlugin, which supports plug-in through the Java SPI mechanism</li><li>HugeGraph provides four extension registration functions: registerOptions(), registerBackend(), registerSerializer(),registerAnalyzer()</li><li>The plug-in implementer implements the corresponding Options, Backend, Serializer or Analyzer interface</li><li>The plug-in implementer implements register()the method of the HugeGraphPlugin interface, registers the specific
implementation class listed in the above point 3 in this method, and packs it into a jar package</li><li>The plug-in user puts the jar package in the HugeGraph Server installation directory plugins, modifies the relevant
configuration items to the plug-in custom value, and restarts to take effect</li></ol><h3 id=plug-in-implementation-process-example>Plug-in implementation process example</h3><h4 id=1-create-a-new-maven-project>1 Create a new maven project</h4><h5 id=11-name-the-project-name-hugegraph-plugin-demo>1.1 Name the project name: hugegraph-plugin-demo</h5><h5 id=12-add-hugegraph-core-jar-package-dependencies>1.2 Add <code>hugegraph-core</code> Jar package dependencies</h5><p>The details of maven pom.xml are as follows:</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-xml data-lang=xml><span style=display:flex><span><span style=color:#8f5902;font-style:italic>&lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&gt;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>&lt;project</span> <span style=color:#c4a000>xmlns=</span><span style=color:#4e9a06>&#34;http://maven.apache.org/POM/4.0.0&#34;</span>
</span></span><span style=display:flex><span> <span style=color:#c4a000>xmlns:xsi=</span><span style=color:#4e9a06>&#34;http://www.w3.org/2001/XMLSchema-instance&#34;</span>
</span></span><span style=display:flex><span> <span style=color:#c4a000>xsi:schemaLocation=</span><span style=color:#4e9a06>&#34;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&#34;</span><span style=color:#204a87;font-weight:700>&gt;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>&lt;modelVersion&gt;</span>4.0.0<span style=color:#204a87;font-weight:700>&lt;/modelVersion&gt;</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>&lt;groupId&gt;</span>org.apache.hugegraph<span style=color:#204a87;font-weight:700>&lt;/groupId&gt;</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>&lt;artifactId&gt;</span>hugegraph-plugin-demo<span style=color:#204a87;font-weight:700>&lt;/artifactId&gt;</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>&lt;version&gt;</span>1.0.0<span style=color:#204a87;font-weight:700>&lt;/version&gt;</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>&lt;packaging&gt;</span>jar<span style=color:#204a87;font-weight:700>&lt;/packaging&gt;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>&lt;name&gt;</span>hugegraph-plugin-demo<span style=color:#204a87;font-weight:700>&lt;/name&gt;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>&lt;dependencies&gt;</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>&lt;dependency&gt;</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>&lt;groupId&gt;</span>org.apache.hugegraph<span style=color:#204a87;font-weight:700>&lt;/groupId&gt;</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>&lt;artifactId&gt;</span>hugegraph-core<span style=color:#204a87;font-weight:700>&lt;/artifactId&gt;</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>&lt;version&gt;</span>${project.version}<span style=color:#204a87;font-weight:700>&lt;/version&gt;</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>&lt;/dependency&gt;</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>&lt;/dependencies&gt;</span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>&lt;/project&gt;</span>
</span></span></code></pre></div><h4 id=2-realize-extended-functions>2 Realize extended functions</h4><h5 id=21-extending-a-custom-backend>2.1 Extending a custom backend</h5><h6 id=211--implement-the-interface-backendstoreprovider>2.1.1 Implement the interface BackendStoreProvider</h6><ul><li>Realizable interfaces: <code>org.apache.hugegraph.backend.store.BackendStoreProvider</code></li><li>Or inherit an abstract class:<code>org.apache.hugegraph.backend.store.AbstractBackendStoreProvider</code></li></ul><p>Take the RocksDB backend RocksDBStoreProvider as an example:</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java><span style=display:flex><span><span style=color:#204a87;font-weight:700>public</span> <span style=color:#204a87;font-weight:700>class</span> <span style=color:#000>RocksDBStoreProvider</span> <span style=color:#204a87;font-weight:700>extends</span> <span style=color:#000>AbstractBackendStoreProvider</span> <span style=color:#ce5c00;font-weight:700>{</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>protected</span> <span style=color:#000>String</span> <span style=color:#000>database</span><span style=color:#ce5c00;font-weight:700>()</span> <span style=color:#ce5c00;font-weight:700>{</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>return</span> <span style=color:#204a87;font-weight:700>this</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>graph</span><span style=color:#ce5c00;font-weight:700>().</span><span style=color:#c4a000>toLowerCase</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>}</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#5c35cc;font-weight:700>@Override</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>protected</span> <span style=color:#000>BackendStore</span> <span style=color:#000>newSchemaStore</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>String</span> <span style=color:#000>store</span><span style=color:#ce5c00;font-weight:700>)</span> <span style=color:#ce5c00;font-weight:700>{</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>return</span> <span style=color:#204a87;font-weight:700>new</span> <span style=color:#000>RocksDBSchemaStore</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#204a87;font-weight:700>this</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#204a87;font-weight:700>this</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>database</span><span style=color:#ce5c00;font-weight:700>(),</span> <span style=color:#000>store</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>}</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#5c35cc;font-weight:700>@Override</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>protected</span> <span style=color:#000>BackendStore</span> <span style=color:#000>newGraphStore</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>String</span> <span style=color:#000>store</span><span style=color:#ce5c00;font-weight:700>)</span> <span style=color:#ce5c00;font-weight:700>{</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>return</span> <span style=color:#204a87;font-weight:700>new</span> <span style=color:#000>RocksDBGraphStore</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#204a87;font-weight:700>this</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#204a87;font-weight:700>this</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>database</span><span style=color:#ce5c00;font-weight:700>(),</span> <span style=color:#000>store</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>}</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#5c35cc;font-weight:700>@Override</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>String</span> <span style=color:#000>type</span><span style=color:#ce5c00;font-weight:700>()</span> <span style=color:#ce5c00;font-weight:700>{</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>return</span> <span style=color:#4e9a06>&#34;rocksdb&#34;</span><span style=color:#ce5c00;font-weight:700>;</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>}</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#5c35cc;font-weight:700>@Override</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>String</span> <span style=color:#000>version</span><span style=color:#ce5c00;font-weight:700>()</span> <span style=color:#ce5c00;font-weight:700>{</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>return</span> <span style=color:#4e9a06>&#34;1.0&#34;</span><span style=color:#ce5c00;font-weight:700>;</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>}</span>
</span></span><span style=display:flex><span><span style=color:#ce5c00;font-weight:700>}</span>
</span></span></code></pre></div><h6 id=212-implement-interface-backendstore>2.1.2 Implement interface BackendStore</h6><p>The BackendStore interface is defined as follows:</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java><span style=display:flex><span><span style=color:#204a87;font-weight:700>public</span> <span style=color:#204a87;font-weight:700>interface</span> <span style=color:#000>BackendStore</span> <span style=color:#ce5c00;font-weight:700>{</span>
</span></span><span style=display:flex><span> <span style=color:#8f5902;font-style:italic>// Store name
</span></span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic></span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>String</span> <span style=color:#000>store</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#8f5902;font-style:italic>// Database name
</span></span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic></span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>String</span> <span style=color:#000>database</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#8f5902;font-style:italic>// Get the parent provider
</span></span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic></span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>BackendStoreProvider</span> <span style=color:#000>provider</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#8f5902;font-style:italic>// Open/close database
</span></span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic></span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#204a87;font-weight:700>void</span> <span style=color:#000>open</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>HugeConfig</span> <span style=color:#000>config</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#204a87;font-weight:700>void</span> <span style=color:#000>close</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#8f5902;font-style:italic>// Initialize/clear database
</span></span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic></span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#204a87;font-weight:700>void</span> <span style=color:#000>init</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#204a87;font-weight:700>void</span> <span style=color:#000>clear</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#8f5902;font-style:italic>// Add/delete data
</span></span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic></span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#204a87;font-weight:700>void</span> <span style=color:#000>mutate</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>BackendMutation</span> <span style=color:#000>mutation</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#8f5902;font-style:italic>// Query data
</span></span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic></span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>Iterator</span><span style=color:#ce5c00;font-weight:700>&lt;</span><span style=color:#000>BackendEntry</span><span style=color:#ce5c00;font-weight:700>&gt;</span> <span style=color:#000>query</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>Query</span> <span style=color:#000>query</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#8f5902;font-style:italic>// Transaction
</span></span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic></span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#204a87;font-weight:700>void</span> <span style=color:#000>beginTx</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#204a87;font-weight:700>void</span> <span style=color:#000>commitTx</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#204a87;font-weight:700>void</span> <span style=color:#000>rollbackTx</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#8f5902;font-style:italic>// Get metadata by key
</span></span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic></span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#ce5c00;font-weight:700>&lt;</span><span style=color:#000>R</span><span style=color:#ce5c00;font-weight:700>&gt;</span> <span style=color:#000>R</span> <span style=color:#000>metadata</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>HugeType</span> <span style=color:#000>type</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#000>String</span> <span style=color:#000>meta</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#000>Object</span><span style=color:#ce5c00;font-weight:700>[]</span> <span style=color:#000>args</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#8f5902;font-style:italic>// Backend features
</span></span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic></span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>BackendFeatures</span> <span style=color:#000>features</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#8f5902;font-style:italic>// Generate an id for a specific type
</span></span></span><span style=display:flex><span><span style=color:#8f5902;font-style:italic></span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>Id</span> <span style=color:#000>nextId</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>HugeType</span> <span style=color:#000>type</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span><span style=color:#ce5c00;font-weight:700>}</span>
</span></span></code></pre></div><h6 id=213-extending-custom-serializers>2.1.3 Extending custom serializers</h6><p>The serializer must inherit the abstract class: <code>org.apache.hugegraph.backend.serializer.AbstractSerializer</code>
( <code>implements GraphSerializer, SchemaSerializer</code>) The main interface is defined as follows:</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java><span style=display:flex><span><span style=color:#204a87;font-weight:700>public</span> <span style=color:#204a87;font-weight:700>interface</span> <span style=color:#000>GraphSerializer</span> <span style=color:#ce5c00;font-weight:700>{</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>BackendEntry</span> <span style=color:#000>writeVertex</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>HugeVertex</span> <span style=color:#000>vertex</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>BackendEntry</span> <span style=color:#000>writeVertexProperty</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>HugeVertexProperty</span><span style=color:#ce5c00;font-weight:700>&lt;?&gt;</span> <span style=color:#000>prop</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>HugeVertex</span> <span style=color:#000>readVertex</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>HugeGraph</span> <span style=color:#000>graph</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#000>BackendEntry</span> <span style=color:#000>entry</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>BackendEntry</span> <span style=color:#000>writeEdge</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>HugeEdge</span> <span style=color:#000>edge</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>BackendEntry</span> <span style=color:#000>writeEdgeProperty</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>HugeEdgeProperty</span><span style=color:#ce5c00;font-weight:700>&lt;?&gt;</span> <span style=color:#000>prop</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>HugeEdge</span> <span style=color:#000>readEdge</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>HugeGraph</span> <span style=color:#000>graph</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#000>BackendEntry</span> <span style=color:#000>entry</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>BackendEntry</span> <span style=color:#000>writeIndex</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>HugeIndex</span> <span style=color:#000>index</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>HugeIndex</span> <span style=color:#000>readIndex</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>HugeGraph</span> <span style=color:#000>graph</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#000>ConditionQuery</span> <span style=color:#000>query</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#000>BackendEntry</span> <span style=color:#000>entry</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>BackendEntry</span> <span style=color:#000>writeId</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>HugeType</span> <span style=color:#000>type</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#000>Id</span> <span style=color:#000>id</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>Query</span> <span style=color:#000>writeQuery</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>Query</span> <span style=color:#000>query</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span><span style=color:#ce5c00;font-weight:700>}</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>public</span> <span style=color:#204a87;font-weight:700>interface</span> <span style=color:#000>SchemaSerializer</span> <span style=color:#ce5c00;font-weight:700>{</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>BackendEntry</span> <span style=color:#000>writeVertexLabel</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>VertexLabel</span> <span style=color:#000>vertexLabel</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>VertexLabel</span> <span style=color:#000>readVertexLabel</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>HugeGraph</span> <span style=color:#000>graph</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#000>BackendEntry</span> <span style=color:#000>entry</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>BackendEntry</span> <span style=color:#000>writeEdgeLabel</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>EdgeLabel</span> <span style=color:#000>edgeLabel</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>EdgeLabel</span> <span style=color:#000>readEdgeLabel</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>HugeGraph</span> <span style=color:#000>graph</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#000>BackendEntry</span> <span style=color:#000>entry</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>BackendEntry</span> <span style=color:#000>writePropertyKey</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>PropertyKey</span> <span style=color:#000>propertyKey</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>PropertyKey</span> <span style=color:#000>readPropertyKey</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>HugeGraph</span> <span style=color:#000>graph</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#000>BackendEntry</span> <span style=color:#000>entry</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>BackendEntry</span> <span style=color:#000>writeIndexLabel</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>IndexLabel</span> <span style=color:#000>indexLabel</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>IndexLabel</span> <span style=color:#000>readIndexLabel</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>HugeGraph</span> <span style=color:#000>graph</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#000>BackendEntry</span> <span style=color:#000>entry</span><span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span><span style=color:#ce5c00;font-weight:700>}</span>
</span></span></code></pre></div><h6 id=214-extend-custom-configuration-items>2.1.4 Extend custom configuration items</h6><p>When adding a custom backend, it may be necessary to add new configuration items. The implementation process mainly includes:</p><ul><li>Add a configuration item container class and implement the interface <code>org.apache.hugegraph.config.OptionHolder</code></li><li>Provide a singleton method <code>public static OptionHolder instance()</code>, and call the method when the object is initialized <code>OptionHolder.registerOptions()</code></li><li>Add configuration item declaration, single-value configuration item type is <code>ConfigOption</code>, multi-value configuration item type is <code>ConfigListOption</code></li></ul><p>Take the RocksDB configuration item definition as an example:</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java><span style=display:flex><span><span style=color:#204a87;font-weight:700>public</span> <span style=color:#204a87;font-weight:700>class</span> <span style=color:#000>RocksDBOptions</span> <span style=color:#204a87;font-weight:700>extends</span> <span style=color:#000>OptionHolder</span> <span style=color:#ce5c00;font-weight:700>{</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>private</span> <span style=color:#000>RocksDBOptions</span><span style=color:#ce5c00;font-weight:700>()</span> <span style=color:#ce5c00;font-weight:700>{</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>super</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>}</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>private</span> <span style=color:#204a87;font-weight:700>static</span> <span style=color:#204a87;font-weight:700>volatile</span> <span style=color:#000>RocksDBOptions</span> <span style=color:#000>instance</span><span style=color:#ce5c00;font-weight:700>;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#204a87;font-weight:700>static</span> <span style=color:#204a87;font-weight:700>synchronized</span> <span style=color:#000>RocksDBOptions</span> <span style=color:#000>instance</span><span style=color:#ce5c00;font-weight:700>()</span> <span style=color:#ce5c00;font-weight:700>{</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>if</span> <span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>instance</span> <span style=color:#ce5c00;font-weight:700>==</span> <span style=color:#204a87;font-weight:700>null</span><span style=color:#ce5c00;font-weight:700>)</span> <span style=color:#ce5c00;font-weight:700>{</span>
</span></span><span style=display:flex><span> <span style=color:#000>instance</span> <span style=color:#ce5c00;font-weight:700>=</span> <span style=color:#204a87;font-weight:700>new</span> <span style=color:#000>RocksDBOptions</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span> <span style=color:#000>instance</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>registerOptions</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>}</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>return</span> <span style=color:#000>instance</span><span style=color:#ce5c00;font-weight:700>;</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>}</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#204a87;font-weight:700>static</span> <span style=color:#204a87;font-weight:700>final</span> <span style=color:#000>ConfigOption</span><span style=color:#ce5c00;font-weight:700>&lt;</span><span style=color:#000>String</span><span style=color:#ce5c00;font-weight:700>&gt;</span> <span style=color:#000>DATA_PATH</span> <span style=color:#ce5c00;font-weight:700>=</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>new</span> <span style=color:#000>ConfigOption</span><span style=color:#ce5c00;font-weight:700>&lt;&gt;(</span>
</span></span><span style=display:flex><span> <span style=color:#4e9a06>&#34;rocksdb.data_path&#34;</span><span style=color:#ce5c00;font-weight:700>,</span>
</span></span><span style=display:flex><span> <span style=color:#4e9a06>&#34;The path for storing data of RocksDB.&#34;</span><span style=color:#ce5c00;font-weight:700>,</span>
</span></span><span style=display:flex><span> <span style=color:#000>disallowEmpty</span><span style=color:#ce5c00;font-weight:700>(),</span>
</span></span><span style=display:flex><span> <span style=color:#4e9a06>&#34;rocksdb-data&#34;</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#204a87;font-weight:700>static</span> <span style=color:#204a87;font-weight:700>final</span> <span style=color:#000>ConfigOption</span><span style=color:#ce5c00;font-weight:700>&lt;</span><span style=color:#000>String</span><span style=color:#ce5c00;font-weight:700>&gt;</span> <span style=color:#000>WAL_PATH</span> <span style=color:#ce5c00;font-weight:700>=</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>new</span> <span style=color:#000>ConfigOption</span><span style=color:#ce5c00;font-weight:700>&lt;&gt;(</span>
</span></span><span style=display:flex><span> <span style=color:#4e9a06>&#34;rocksdb.wal_path&#34;</span><span style=color:#ce5c00;font-weight:700>,</span>
</span></span><span style=display:flex><span> <span style=color:#4e9a06>&#34;The path for storing WAL of RocksDB.&#34;</span><span style=color:#ce5c00;font-weight:700>,</span>
</span></span><span style=display:flex><span> <span style=color:#000>disallowEmpty</span><span style=color:#ce5c00;font-weight:700>(),</span>
</span></span><span style=display:flex><span> <span style=color:#4e9a06>&#34;rocksdb-data&#34;</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#204a87;font-weight:700>static</span> <span style=color:#204a87;font-weight:700>final</span> <span style=color:#000>ConfigListOption</span><span style=color:#ce5c00;font-weight:700>&lt;</span><span style=color:#000>String</span><span style=color:#ce5c00;font-weight:700>&gt;</span> <span style=color:#000>DATA_DISKS</span> <span style=color:#ce5c00;font-weight:700>=</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>new</span> <span style=color:#000>ConfigListOption</span><span style=color:#ce5c00;font-weight:700>&lt;&gt;(</span>
</span></span><span style=display:flex><span> <span style=color:#4e9a06>&#34;rocksdb.data_disks&#34;</span><span style=color:#ce5c00;font-weight:700>,</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>false</span><span style=color:#ce5c00;font-weight:700>,</span>
</span></span><span style=display:flex><span> <span style=color:#4e9a06>&#34;The optimized disks for storing data of RocksDB. &#34;</span> <span style=color:#ce5c00;font-weight:700>+</span>
</span></span><span style=display:flex><span> <span style=color:#4e9a06>&#34;The format of each element: `STORE/TABLE: /path/to/disk`.&#34;</span> <span style=color:#ce5c00;font-weight:700>+</span>
</span></span><span style=display:flex><span> <span style=color:#4e9a06>&#34;Allowed keys are [graph/vertex, graph/edge_out, graph/edge_in, &#34;</span> <span style=color:#ce5c00;font-weight:700>+</span>
</span></span><span style=display:flex><span> <span style=color:#4e9a06>&#34;graph/secondary_index, graph/range_index]&#34;</span><span style=color:#ce5c00;font-weight:700>,</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>null</span><span style=color:#ce5c00;font-weight:700>,</span>
</span></span><span style=display:flex><span> <span style=color:#000>String</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>class</span><span style=color:#ce5c00;font-weight:700>,</span>
</span></span><span style=display:flex><span> <span style=color:#000>ImmutableList</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>of</span><span style=color:#ce5c00;font-weight:700>()</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>);</span>
</span></span><span style=display:flex><span><span style=color:#ce5c00;font-weight:700>}</span>
</span></span></code></pre></div><h5 id=22-extend-custom-tokenizer>2.2 Extend custom tokenizer</h5><p>The tokenizer needs to implement the interface <code>org.apache.hugegraph.analyzer.Analyzer</code>, take implementing a SpaceAnalyzer space tokenizer as an example.</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java><span style=display:flex><span><span style=color:#204a87;font-weight:700>package</span> <span style=color:#000>org.apache.hugegraph.plugin</span><span style=color:#ce5c00;font-weight:700>;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>import</span> <span style=color:#000>java.util.Arrays</span><span style=color:#ce5c00;font-weight:700>;</span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>import</span> <span style=color:#000>java.util.HashSet</span><span style=color:#ce5c00;font-weight:700>;</span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>import</span> <span style=color:#000>java.util.Set</span><span style=color:#ce5c00;font-weight:700>;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>import</span> <span style=color:#000>org.apache.hugegraph.analyzer.Analyzer</span><span style=color:#ce5c00;font-weight:700>;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>public</span> <span style=color:#204a87;font-weight:700>class</span> <span style=color:#000>SpaceAnalyzer</span> <span style=color:#204a87;font-weight:700>implements</span> <span style=color:#000>Analyzer</span> <span style=color:#ce5c00;font-weight:700>{</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#5c35cc;font-weight:700>@Override</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>Set</span><span style=color:#ce5c00;font-weight:700>&lt;</span><span style=color:#000>String</span><span style=color:#ce5c00;font-weight:700>&gt;</span> <span style=color:#000>segment</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>String</span> <span style=color:#000>text</span><span style=color:#ce5c00;font-weight:700>)</span> <span style=color:#ce5c00;font-weight:700>{</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>return</span> <span style=color:#204a87;font-weight:700>new</span> <span style=color:#000>HashSet</span><span style=color:#ce5c00;font-weight:700>&lt;&gt;(</span><span style=color:#000>Arrays</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>asList</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#000>text</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>split</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#4e9a06>&#34; &#34;</span><span style=color:#ce5c00;font-weight:700>)));</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>}</span>
</span></span><span style=display:flex><span><span style=color:#ce5c00;font-weight:700>}</span>
</span></span></code></pre></div><h4 id=3-implement-the-plug-in-interface-and-register-it>3. Implement the plug-in interface and register it</h4><p>The plug-in registration entry is <code>HugeGraphPlugin.register()</code>, the custom plug-in must implement this interface method, and register the extension
items defined above inside it. The interface <code>org.apache.hugegraph.plugin.HugeGraphPlugin</code> is defined as follows:</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java><span style=display:flex><span><span style=color:#204a87;font-weight:700>public</span> <span style=color:#204a87;font-weight:700>interface</span> <span style=color:#000>HugeGraphPlugin</span> <span style=color:#ce5c00;font-weight:700>{</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>String</span> <span style=color:#000>name</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#204a87;font-weight:700>void</span> <span style=color:#000>register</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>String</span> <span style=color:#000>supportsMinVersion</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>String</span> <span style=color:#000>supportsMaxVersion</span><span style=color:#ce5c00;font-weight:700>();</span>
</span></span><span style=display:flex><span><span style=color:#ce5c00;font-weight:700>}</span>
</span></span></code></pre></div><p>And HugeGraphPlugin provides 4 static methods for registering extensions:</p><ul><li>registerOptions(String name, String classPath): register configuration items</li><li>registerBackend(String name, String classPath): register backend (BackendStoreProvider)</li><li>registerSerializer(String name, String classPath): register serializer</li><li>registerAnalyzer(String name, String classPath): register tokenizer</li></ul><p>The following is an example of registering the SpaceAnalyzer tokenizer:</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java><span style=display:flex><span><span style=color:#204a87;font-weight:700>package</span> <span style=color:#000>org.apache.hugegraph.plugin</span><span style=color:#ce5c00;font-weight:700>;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#204a87;font-weight:700>public</span> <span style=color:#204a87;font-weight:700>class</span> <span style=color:#000>DemoPlugin</span> <span style=color:#204a87;font-weight:700>implements</span> <span style=color:#000>HugeGraphPlugin</span> <span style=color:#ce5c00;font-weight:700>{</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#5c35cc;font-weight:700>@Override</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#000>String</span> <span style=color:#000>name</span><span style=color:#ce5c00;font-weight:700>()</span> <span style=color:#ce5c00;font-weight:700>{</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>return</span> <span style=color:#4e9a06>&#34;demo&#34;</span><span style=color:#ce5c00;font-weight:700>;</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>}</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#5c35cc;font-weight:700>@Override</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>public</span> <span style=color:#204a87;font-weight:700>void</span> <span style=color:#000>register</span><span style=color:#ce5c00;font-weight:700>()</span> <span style=color:#ce5c00;font-weight:700>{</span>
</span></span><span style=display:flex><span> <span style=color:#000>HugeGraphPlugin</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>registerAnalyzer</span><span style=color:#ce5c00;font-weight:700>(</span><span style=color:#4e9a06>&#34;demo&#34;</span><span style=color:#ce5c00;font-weight:700>,</span> <span style=color:#000>SpaceAnalyzer</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>class</span><span style=color:#ce5c00;font-weight:700>.</span><span style=color:#c4a000>getName</span><span style=color:#ce5c00;font-weight:700>());</span>
</span></span><span style=display:flex><span> <span style=color:#ce5c00;font-weight:700>}</span>
</span></span><span style=display:flex><span><span style=color:#ce5c00;font-weight:700>}</span>
</span></span></code></pre></div><h4 id=4-configure-spi-entry>4. Configure SPI entry</h4><ol><li>Make sure the services directory exists: hugegraph-plugin-demo/resources/META-INF/services</li><li>Create a text file in the services directory: org.apache.hugegraph.plugin.HugeGraphPlugin</li><li>The content of the file is as follows: org.apache.hugegraph.plugin.DemoPlugin</li></ol><h4 id=5-make-jar-package>5. Make Jar package</h4><p>Through maven packaging, execute the command in the project directory mvn package, and a Jar package file will be generated in the
target directory. Copy the Jar package to the <code>plugins</code> directory when using it, and restart the service to take effect.</p></div><div class=td-content style=page-break-before:always><h1 id=pg-2c9db416c8d78f898d52c91ec12535d4>4 - Backup and Restore</h1><h2 id=description>Description</h2><p>Backup and Restore are functions of backup map and restore map. The data backed up and restored includes metadata (schema) and graph data (vertex and edge).</p><h4 id=backup>Backup</h4><p>Export the metadata and graph data of a graph in the HugeGraph system in JSON format.</p><h4 id=restore>Restore</h4><p>Re-import the data in JSON format exported by Backup to a graph in the HugeGraph system.</p><p>Restore has two modes:</p><ul><li>In Restoring mode, the metadata and graph data exported by Backup are restored to the HugeGraph system intact. It can be used for graph backup and recovery, and the general target graph is a new graph (without metadata and graph data). for example:<ul><li>System upgrade, first back up the map, then upgrade the system, and finally restore the map to the new system</li><li>Graph migration, from a HugeGraph system, use the Backup function to export the graph, and then use the Restore function to import the graph into another HugeGraph system</li></ul></li><li>In the Merging mode, the metadata and graph data exported by Backup are imported into another graph that already has metadata or graph data. During the process, the ID of the metadata may change, and the IDs of vertices and edges will also change accordingly.<ul><li>Can be used to merge graphs</li></ul></li></ul><h2 id=instructions>Instructions</h2><p>You can use <a href=/docs/quickstart/hugegraph-tools>hugegraph-tools</a> to backup and restore graphs.</p><h4 id=backup-1>Backup</h4><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-bash data-lang=bash><span style=display:flex><span>bin/hugegraph backup -t all -d data
</span></span></code></pre></div><p>This command backs up all the metadata and graph data of the hugegraph graph of http://127.0.0.1 to the data directory.</p><blockquote><p>Backup works fine in all three graph modes</p></blockquote><h4 id=restore-1>Restore</h4><p>Restore has two modes: RESTORING and MERGING. Before backup, you must first set the graph mode according to your needs.</p><h5 id=step-1-view-and-set-graph-mode>Step 1: View and set graph mode</h5><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-bash data-lang=bash><span style=display:flex><span>bin/hugegraph graph-mode-get
</span></span></code></pre></div><p>This command is used to view the current graph mode, including: NONE, RESTORING, MERGING.</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-bash data-lang=bash><span style=display:flex><span>bin/hugegraph graph-mode-set -m RESTORING
</span></span></code></pre></div><p>This command is used to set the graph mode. Before Restore, it can be set to RESTORING or MERGING mode. In the example, it is set to RESTORING.</p><h5 id=step-2-restore-data>Step 2: Restore data</h5><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-bash data-lang=bash><span style=display:flex><span>bin/hugegraph restore -t all -d data
</span></span></code></pre></div><p>This command re-imports all metadata and graph data in the data directory to the hugegraph graph at http://127.0.0.1.</p><h5 id=step-3-restoring-graph-mode>Step 3: Restoring Graph Mode</h5><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-bash data-lang=bash><span style=display:flex><span>bin/hugegraph graph-mode-set -m NONE
</span></span></code></pre></div><p>This command is used to restore the graph mode to NONE.</p><p>So far, a complete graph backup and graph recovery process is over.</p><h4 id=help>help</h4><p>For detailed usage of backup and restore commands, please refer to the <a href=/docs/quickstart/hugegraph-tools>hugegraph-tools documentation</a>.</p><h2 id=api-description-for-backuprestore-usage-and-implementation>API description for Backup/Restore usage and implementation</h2><h4 id=backup-2>Backup</h4><p>Backup uses the corresponding list(GET) API export of metadata and graph data, and no new API is added.</p><h4 id=restore-2>Restore</h4><p>Restore uses the corresponding create(POST) API imports for metadata and graph data, and does not add new APIs.</p><p>There are two different modes for Restore: Restoring and Merging. In addition, there is a regular mode of NONE (default), the differences are as follows:</p><ul><li>In None mode, the writing of metadata and graph data is normal, please refer to the function description. special:<ul><li>ID is not allowed when metadata (schema) is created</li><li>Graph data (vertex) is not allowed to specify an ID when the id strategy is Automatic</li></ul></li><li>Restoring mode, restoring to a new graph, in particular:<ul><li>ID is allowed to be specified when metadata (schema) is created</li><li>Graph data (vertex) allows specifying an ID when the id strategy is Automatic</li></ul></li><li>Merging mode, merging into a graph with existing metadata and graph data, in particular:<ul><li>ID is not allowed when metadata (schema) is created</li><li>Graph data (vertex) allows specifying an ID when the id strategy is Automatic</li></ul></li></ul><p>Normally, the graph mode is None. When you need to restore the graph, you need to temporarily change the graph mode to Restoring mode or
Merging mode as needed, and when the Restore is completed, restore the graph mode to None.</p><p>The implemented RESTful API for setting graph mode is as follows:</p><h5 id=view-the-schema-of-a-graph-this-operation-requires-administrator-privileges>View the schema of a graph. <strong>This operation requires administrator privileges</strong></h5><h6 id=method--url>Method & Url</h6><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-fallback data-lang=fallback><span style=display:flex><span>GET http://localhost:8080/graphs/{graph}/mode
</span></span></code></pre></div><h6 id=response-status>Response Status</h6><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-json data-lang=json><span style=display:flex><span><span style=color:#0000cf;font-weight:700>200</span>
</span></span></code></pre></div><h6 id=response-body>Response Body</h6><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-json data-lang=json><span style=display:flex><span><span style=color:#000;font-weight:700>{</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>&#34;mode&#34;</span><span style=color:#000;font-weight:700>:</span> <span style=color:#4e9a06>&#34;NONE&#34;</span>
</span></span><span style=display:flex><span><span style=color:#000;font-weight:700>}</span>
</span></span></code></pre></div><blockquote><p>Legal graph modes include: NONE, RESTORING, MERGING</p></blockquote><h5 id=set-the-mode-of-a-graph-this-operation-requires-administrator-privileges>Set the mode of a graph. &ldquo;&ldquo;This operation requires administrator privileges**</h5><h6 id=method--url-1>Method & Url</h6><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-fallback data-lang=fallback><span style=display:flex><span>PUT http://localhost:8080/graphs/{graph}/mode
</span></span></code></pre></div><h6 id=request-body>Request Body</h6><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-fallback data-lang=fallback><span style=display:flex><span>&#34;RESTORING&#34;
</span></span></code></pre></div><blockquote><p>Legal graph modes include: NONE, RESTORING, MERGING</p></blockquote><h6 id=response-status-1>Response Status</h6><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-json data-lang=json><span style=display:flex><span><span style=color:#0000cf;font-weight:700>200</span>
</span></span></code></pre></div><h6 id=response-body-1>Response Body</h6><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-json data-lang=json><span style=display:flex><span><span style=color:#000;font-weight:700>{</span>
</span></span><span style=display:flex><span> <span style=color:#204a87;font-weight:700>&#34;mode&#34;</span><span style=color:#000;font-weight:700>:</span> <span style=color:#4e9a06>&#34;RESTORING&#34;</span>
</span></span><span style=display:flex><span><span style=color:#000;font-weight:700>}</span>
</span></span></code></pre></div></div><div class=td-content style=page-break-before:always><h1 id=pg-3465b699399f48689cdc6b5e59a10d69>5 - FAQ</h1><ul><li><p>How to choose the back-end storage? Choose RocksDB or Cassandra or Hbase or Mysql?</p><p>Judge according to your specific needs. Generally, if the stand-alone machine or the data volume is &lt; 10 billion, RocksDB is recommended, and other back-end clusters that use distributed storage are recommended.</p></li><li><p>Prompt when starting the service: <code>xxx (core dumped) xxx</code></p><p>Please check if the JDK version is Java 11, at least Java 8 is required</p></li><li><p>The service is started successfully, but there is a prompt similar to &ldquo;Unable to connect to the backend or the connection is not open&rdquo; when operating the graph</p><p>init-storeBefore starting the service for the first time, you need to use the initialization backend first , and subsequent versions will prompt more clearly and directly.</p></li><li><p>Do all backends need to be executed before use init-store, and can the serialization options be filled in at will?</p><p>Except memorynot required, other backends are required, such as: <code>cassandra</code>, <code>hbaseand</code>, <code>rocksdb</code>, etc. Serialization needs to be one-to-one correspondence and cannot be filled in at will.</p></li><li><p>Execution <code>init-store</code> error: <code>Exception in thread "main" java.lang.UnsatisfiedLinkError: /tmp/librocksdbjni3226083071221514754.so: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.10' not found (required by /tmp/librocksdbjni3226083071221514754.so)</code></p><p>RocksDB requires gcc 4.3.0 (GLIBCXX_3.4.10) and above</p></li><li><p>The error <code>NoHostAvailableException</code> occurred while executing <code>init-store.sh</code>.</p><p><code>NoHostAvailableException</code> means that the <code>Cassandra</code> service cannot be connected to. If you are sure that you want to use the Cassandra backend, please install and start this service first. As for the message itself, it may not be clear enough, and we will update the documentation to provide further explanation.</p></li><li><p>The <code>bin</code> directory contains <code>start-hugegraph.sh</code>, <code>start-restserver.sh</code> and <code>start-gremlinserver.sh</code>. These scripts seem to be related to startup. Which one should be used?</p><p>Since version 0.3.3, GremlinServer and RestServer have been merged into HugeGraphServer. To start, use start-hugegraph.sh. The latter two will be removed in future versions.</p></li><li><p>Two graphs are configured, the names are <code>hugegraph</code> and <code>hugegraph1</code>, and the command to start the service is <code>start-hugegraph.sh</code>. Is only the hugegraph graph opened?</p><p><code>start-hugegraph.sh</code> will open all graphs under the graphs of <code>gremlin-server.yaml</code>. The two have no direct relationship in name</p></li><li><p>After the service starts successfully, garbled characters are returned when using <code>curl</code> to query all vertices</p><p>The batch vertices/edges returned by the server are compressed (gzip), and can be redirected to <code>gunzip</code> for decompression (<code>curl http://example | gunzip</code>), or can be sent with the <code>postman</code> of <code>Firefox</code> or the <code>restlet</code> plug-in of Chrome browser. request, the response data will be decompressed automatically.</p></li><li><p>When using the vertex Id to query the vertex through the <code>RESTful API</code>, it returns empty, but the vertex does exist</p><p>Check the type of the vertex ID. If it is a string type, the &ldquo;id&rdquo; part of the API URL needs to be enclosed in double quotes, while for numeric types, it is not necessary to enclose the ID in quotes.</p></li><li><p>Vertex Id has been double quoted as required, but querying the vertex via the RESTful API still returns empty</p><p>Check whether the vertex id contains <code>+</code>, <code>space</code>, <code>/</code>, <code>?</code>, <code>%</code>, <code>&</code>, and <code>=</code> reserved characters of these <code>URLs</code>. If they exist, they need to be encoded. The following table gives the coded values:</p><div class=highlight><pre tabindex=0 style=background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-fallback data-lang=fallback><span style=display:flex><span>special character | encoded value
</span></span><span style=display:flex><span>------------------| -------------
</span></span><span style=display:flex><span>+ | %2B
</span></span><span style=display:flex><span>space | %20
</span></span><span style=display:flex><span>/ | %2F
</span></span><span style=display:flex><span>? | %3F
</span></span><span style=display:flex><span>% | %25
</span></span><span style=display:flex><span># | %23
</span></span><span style=display:flex><span>&amp; | %26
</span></span><span style=display:flex><span>= | %3D
</span></span></code></pre></div></li><li><p>Timeout when querying vertices or edges of a certain category (<code>query by label</code>)</p><p>Since the amount of data belonging to a certain label may be relatively large, please add a limit limit.</p></li><li><p>It is possible to operate the graph through the <code>RESTful API</code>, but when sending <code>Gremlin</code> statements, an error is reported: <code>Request Failed(500)</code></p><p>It may be that the configuration of <code>GremlinServer</code> is wrong, check whether the <code>host</code> and <code>port</code> of <code>gremlin-server.yaml</code> match the <code>gremlinserver.url</code> of <code>rest-server.properties</code>, if they do not match, modify them, and then Restart the service.</p></li><li><p>When using <code>Loader</code> to import data, a <code>Socket Timeout</code> exception occurs, and then <code>Loader</code> is interrupted</p><p>Continuously importing data will put too much pressure on the <code>Server</code>, which will cause some requests to time out. The pressure on <code>Server</code> can be appropriately relieved by adjusting the parameters of <code>Loader</code> (such as: number of retries, retry interval, error tolerance, etc.), and reduce the frequency of this problem.</p></li><li><p>How to delete all vertices and edges. There is no such interface in the RESTful API. Calling <code>g.V().drop()</code> of <code>gremlin</code> will report an error <code>Vertices in transaction have reached capacity xxx</code></p><p>At present, there is really no good way to delete all the data. If the user deploys the <code>Server</code> and the backend by himself, he can directly clear the database and restart the <code>Server</code>. You can use the paging API or scan API to get all the data first, and then delete them one by one.</p></li><li><p>The database has been cleared and <code>init-store</code> has been executed, but when trying to add a schema, the prompt &ldquo;xxx has existed&rdquo; appeared.</p><p>There is a cache in the <code>HugeGraphServer</code>, and it is necessary to restart the <code>Server</code> when the database is cleared, otherwise the residual cache will be inconsistent.</p></li><li><p>An error is reported during the process of inserting vertices or edges: <code>Id max length is 128, but got xxx {yyy}</code> or <code>Big id max length is 32768, but got xxx</code></p><p>In order to ensure query performance, the current backend storage limits the length of the id column. The vertex id cannot exceed 128 bytes, the edge id cannot exceed 32768 bytes, and the index id cannot exceed 128 bytes.</p></li><li><p>Is there support for nested attributes, and if not, are there any alternatives?</p><p>Nested attributes are currently not supported. Alternative: Nested attributes can be taken out as individual vertices and connected with edges.</p></li><li><p>Can an <code>EdgeLabel</code> connect multiple pairs of <code>VertexLabel</code>, such as &ldquo;investment&rdquo; relationship, which can be &ldquo;individual&rdquo; investing in &ldquo;enterprise&rdquo;, or &ldquo;enterprise&rdquo; investing in &ldquo;enterprise&rdquo;?</p><p>An <code>EdgeLabel</code> does not support connecting multiple pairs of <code>VertexLabels</code>, users need to split the <code>EdgeLabel</code> into finer details, such as: &ldquo;personal investment&rdquo;, &ldquo;enterprise investment&rdquo;.</p></li><li><p>Prompt <code>HTTP 415 Unsupported Media Type</code> when sending a request through <code>RestAPI</code></p><p><code>Content-Type: application/json</code> needs to be specified in the request header</p></li></ul><p>Other issues can be searched in the issue area of the corresponding project, such as <a href=https://github.com/apache/hugegraph/issues>Server-Issues</a> / <a href=https://github.com/apache/hugegraph-loader/issues>Loader Issues</a></p></div><div class=td-content style=page-break-before:always><h1 id=pg-d54c862d45861ca39a945d90325e3909>6 - Security Report</h1><h2 id=reporting-new-security-problems-with-apache-hugegraph>Reporting New Security Problems with Apache HugeGraph</h2><p>Adhering to the specifications of ASF, the HugeGraph community maintains a highly proactive and open attitude towards addressing security issues in the <strong>remediation</strong> projects.</p><p>We strongly recommend that users first report such issues to our dedicated security email list, with detailed procedures specified in the <a href=https://www.apache.org/security/committers.html>ASF SEC</a> code of conduct.</p><p>Please note that the security email group is reserved for reporting <strong>undisclosed</strong> security vulnerabilities and following up on the vulnerability resolution process.
Regular software <code>Bug/Error</code> reports should be directed to <code>Github Issue/Discussion</code> or the <code>HugeGraph-Dev</code> email group. Emails sent to the security list that are unrelated to security issues will be ignored.</p><p>The independent security email (group) address is: <code>security@hugegraph.apache.org</code></p><p>The general process for handling security vulnerabilities is as follows:</p><ul><li>The reporter privately reports the vulnerability to the Apache HugeGraph SEC email group (including as much information as possible, such as reproducible versions, relevant descriptions, reproduction methods, and the scope of impact)</li><li>The HugeGraph project security team collaborates privately with the reporter to discuss the vulnerability resolution (after preliminary confirmation, a <code>CVE</code> number can be requested for registration)</li><li>The project creates a new version of the software package affected by the vulnerability to provide a fix</li><li>At an appropriate time, a general description of the vulnerability and how to apply the fix will be publicly disclosed (in compliance with ASF standards, the announcement should not disclose sensitive information such as reproduction details)</li><li>Official CVE release and related procedures follow the ASF-SEC page</li></ul><h2 id=known-security-vulnerabilities-cves>Known Security Vulnerabilities (CVEs)</h2><h3 id=hugegraph-main-project-serverpdstore>HugeGraph main project (Server/PD/Store)</h3><ul><li><a href="https://www.cve.org/CVERecord?id=CVE-2024-27348">CVE-2024-27348</a>: HugeGraph-Server - Command execution in gremlin</li><li><a href="https://www.cve.org/CVERecord?id=CVE-2024-27349">CVE-2024-27349</a>: HugeGraph-Server - Bypass whitelist in Auth mode</li></ul><h3 id=hugegraph-toolchain-project-hubbleloaderclienttools>HugeGraph-Toolchain project (Hubble/Loader/Client/Tools/..)</h3><ul><li><a href="https://www.cve.org/CVERecord?id=CVE-2024-27347">CVE-2024-27347</a>: HugeGraph-Hubble - SSRF in Hubble connection page</li></ul></div></main></div></div><footer class="bg-dark py-3 row d-print-none"><div class=footer-container><div class="row bg-dark"><div class=col-1></div><div class="col-4 text-center container-center"><div class=footer-row><a href=https://www.apache.org><div class=footer-apache-logo><svg id="Layer_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 7127.6 2890" enable-background="new 0 0 7127.6 2890"><path fill="#6d6e71" d="M7104.7 847.8c15.3 15.3 22.9 33.7 22.9 55.2s-7.6 39.9-22.9 55.4c-15.3 15.4-33.8 23.1-55.6 23.1s-40.2-7.6-55.4-22.9c-15.1-15.3-22.7-33.7-22.7-55.2s7.6-39.9 22.9-55.4c15.3-15.4 33.7-23.1 55.4-23.1C7070.9 824.9 7089.4 832.5 7104.7 847.8zM7098.1 951.9c13.3-13.6 20-29.8 20-48.7s-6.6-35-19.8-48.5c-13.2-13.4-29.4-20.1-48.6-20.1-19.2.0-35.4 6.7-48.7 20.2s-19.9 29.7-19.9 48.7 6.6 35.2 19.7 48.6c13.1 13.4 29.3 20.1 48.5 20.1S7084.7 965.4 7098.1 951.9zm-11-63.8c0 14-6.1 22.8-18.4 26.4l22.5 30.5H7073l-20.3-28.3h-18.6V945h-14.7v-84.6h31.8c12.8.0 22 2.2 27.6 6.6C7084.4 871.4 7087.1 878.4 7087.1 888.1zM7068.2 9e2c3-2.4 4.4-6.5 4.4-12s-1.5-9.4-4.5-11.6-8.4-3.2-16-3.2h-18v30.5h17.5C7059.7 903.6 7065.3 902.4 7068.2 9e2z"/><path fill="#6d6e71" d="M1803.6 499.8v155.4h-20V499.8h-56.8v-19.2h133.9v19.2H1803.6z"/><path fill="#6d6e71" d="M2082.2 655.2v-76.9H1977v76.9h-20V480.5h20v78.9h105.2v-78.9h20v174.7h-20z"/><path fill="#6d6e71" d="M2241.4 499.8v57.4h88.1v19.2h-88.1v59.8h101.8v19h-121.8V480.5H2340v19.2H2241.4z"/><path fill="#d22128" d="M1574.5 1852.4l417.3-997.6h80.1l417.3 997.6h-105.4l-129.3-311.9h-448.2l-127.9 311.9H1574.5zM2032.6 970l-205.1 493.2h404.7L2032.6 970z"/><path fill="#d22128" d="M2596.9 1852.4V854.8H3010c171.4.0 295.1 158.8 295.1 313.3.0 163-115.2 316.1-286.6 316.1h-324.6v368.1h-97zm97-455.3h318.9c118 0 193.9-108.2 193.9-229 0-125.1-92.7-226.2-202.3-226.2h-310.5v455.2z"/><path fill="#d22128" d="M3250.5 1852.4l417.3-997.6h80.1l417.3 997.6h-105.4l-129.3-311.9h-448.2l-127.9 311.9H3250.5zM3708.6 970l-205.1 493.2h404.7L3708.6 970z"/><path fill="#d22128" d="M4637.3 849.1c177 0 306.3 89.9 368.1 217.8l-78.7 47.8c-63.2-132.1-186.9-177-295.1-177-238.9.0-369.5 213.6-369.5 414.5.0 220.6 161.6 420.1 373.7 420.1 112.4.0 244.5-56.2 307.7-185.5l81.5 42.1c-64.6 148.9-241.7 231.8-394.8 231.8-274 0-466.5-261.3-466.5-514.2C4163.8 1106.3 4336.6 849.1 4637.3 849.1z"/><path fill="#d22128" d="M5949.1 854.8v997.6h-98.4v-466.5h-591.5v466.5h-96.9V854.8h96.9v444h591.5v-444H5949.1z"/><path fill="#d22128" d="M6844.6 1765.2v87.1h-670.2V854.8H6832v87.1h-560.6v359.7h489v82.9h-489v380.8H6844.6z"/><path fill="#6d6e71" d="M1667.6 2063.6c11.8 3.5 22.2 8.3 31 14.2l-10.3 22.6c-9-6-18.6-10.4-28.9-13.4-10.2-2.9-20-4.4-29.2-4.4-13.6.0-24.5 2.4-32.6 7.3s-12.2 11.8-12.2 20.7c0 7.6 2.3 14 6.8 19s10.2 8.9 17 11.7c6.8 2.8 16.1 6 28 9.6 14.4 4.6 26 8.9 34.7 12.9 8.8 4 16.3 9.9 22.5 17.8 6.2 7.8 9.3 18.2 9.3 31 0 11.7-3.2 21.8-9.5 30.6-6.3 8.7-15.3 15.5-26.8 20.3-11.6 4.8-24.9 7.2-40 7.2s-29.7-2.9-43.9-8.7c-14.2-5.8-26.4-13.6-36.6-23.4l10.7-21.6c9.6 9.4 20.7 16.7 33.3 21.9 12.6 5.2 24.8 7.8 36.8 7.8 15.3.0 27.3-3 36.1-8.9s13.2-13.9 13.2-23.9c0-7.8-2.3-14.3-6.9-19.4-4.6-5.1-10.3-9-17.1-11.9-6.8-2.8-16.1-6-28-9.6-14.2-4.2-25.7-8.3-34.6-12.2-8.9-3.9-16.4-9.7-22.5-17.5-6.1-7.7-9.2-17.9-9.2-30.6.0-10.9 3-20.4 9-28.6s14.6-14.6 25.6-19.1c11.1-4.5 23.8-6.8 38.2-6.8C1643.8 2058.3 1655.7 2060.1 1667.6 2063.6z"/><path fill="#6d6e71" d="M1980.1 2072.8c16.8 9.4 30.2 22.3 40 38.4 9.8 16.2 14.8 33.9 14.8 53.3.0 19.5-4.9 37.4-14.8 53.6-9.8 16.3-23.2 29.1-40 38.6s-35.3 14.3-55.2 14.3c-20.3.0-38.8-4.7-55.7-14.3-16.8-9.5-30.2-22.4-40-38.6-9.8-16.3-14.8-34.1-14.8-53.6s4.9-37.3 14.8-53.5c9.8-16.2 23.2-29 40-38.3 16.8-9.4 35.4-14 55.7-14C1944.8 2058.6 1963.2 2063.3 1980.1 2072.8zM1881.9 2092.7c-13.1 7.4-23.6 17.5-31.4 30.1-7.8 12.6-11.8 26.5-11.8 41.7.0 15.3 3.9 29.3 11.8 42 7.8 12.7 18.3 22.8 31.4 30.2 13.1 7.4 27.4 11.1 42.9 11.1s29.7-3.7 42.7-11.1 23.3-17.4 31.1-30.2c7.7-12.7 11.6-26.7 11.6-42s-3.9-29.2-11.6-41.8c-7.7-12.6-18.1-22.6-31.1-30s-27.2-11.2-42.6-11.2C1909.4 2081.5 1895.1 2085.2 1881.9 2092.7z"/><path fill="#6d6e71" d="M2186.5 2082.4v74h98.4v23.2h-98.4v90.2h-24.1v-210.6h133.8v23.2H2186.5z"/><path fill="#6d6e71" d="M2491.6 2082.4v187.4h-24.1v-187.4h-68.4v-23.2h161.4v23.2H2491.6z"/><path fill="#6d6e71" d="M2871.8 2269.8l-56.8-177.4-57.6 177.4h-24.5l-70.5-210.6h25.9l57.9 182.7 57.1-182.4 24.1-.3 57.7 182.7 57.1-182.7h25l-70.6 210.6H2871.8z"/><path fill="#6d6e71" d="M3087.3 2216.6l-23.5 53.2h-25.6l94.4-210.6h25l94.1 210.6h-26.1l-23.5-53.2H3087.3zM3144.5 2086.6l-46.9 106.8h94.4l-47.5-106.8z"/><path fill="#6d6e71" d="M3461.1 2202.7c-6 .4-10.7.6-14.1.6h-56v66.5h-24v-210.6h80c26.2.0 46.6 6.2 61.2 18.5 14.5 12.3 21.8 29.8 21.8 52.3.0 17.2-4.1 31.7-12.2 43.3-8.1 11.6-19.8 20-35 25l49.2 71.5h-27.3L3461.1 2202.7zM3491.3 2167.6c10.3-8.4 15.5-20.8 15.5-37 0-15.9-5.2-27.9-15.5-36s-25.1-12.2-44.3-12.2h-56v97.8h56C3466.2 2180.2 3481 2176 3491.3 2167.6z"/><path fill="#6d6e71" d="M3688.3 2082.4v69.2h106.2v23.2h-106.2v72.1h122.8v22.9h-146.9v-210.6h142.9v23.2H3688.3z"/><path fill="#6d6e71" d="M4147 2082.4v74h98.4v23.2H4147v90.2h-24.1v-210.6h133.8v23.2H4147z"/><path fill="#6d6e71" d="M4523.3 2072.8c16.8 9.4 30.2 22.3 40 38.4 9.8 16.2 14.8 33.9 14.8 53.3.0 19.5-4.9 37.4-14.8 53.6-9.8 16.3-23.2 29.1-40 38.6s-35.3 14.3-55.2 14.3c-20.3.0-38.8-4.7-55.7-14.3-16.8-9.5-30.2-22.4-40-38.6-9.8-16.3-14.8-34.1-14.8-53.6s4.9-37.3 14.8-53.5c9.8-16.2 23.2-29 40-38.3 16.8-9.4 35.4-14 55.7-14C4488.1 2058.6 4506.5 2063.3 4523.3 2072.8zM4425.2 2092.7c-13.1 7.4-23.6 17.5-31.4 30.1-7.8 12.6-11.8 26.5-11.8 41.7.0 15.3 3.9 29.3 11.8 42 7.8 12.7 18.3 22.8 31.4 30.2 13.1 7.4 27.4 11.1 42.9 11.1s29.7-3.7 42.7-11.1 23.3-17.4 31.1-30.2c7.7-12.7 11.6-26.7 11.6-42s-3.9-29.2-11.6-41.8c-7.7-12.6-18.1-22.6-31.1-30s-27.2-11.2-42.6-11.2C4452.6 2081.5 4438.3 2085.2 4425.2 2092.7z"/><path fill="#6d6e71" d="M4854.7 2247.7c-15.7 15.5-37.3 23.3-64.8 23.3-27.7.0-49.4-7.8-65.1-23.3-15.7-15.5-23.6-37-23.6-64.6v-124h24.1v124c0 20.3 5.8 36.1 17.3 47.5 11.6 11.4 27.3 17.1 47.3 17.1 20.1.0 35.8-5.7 47.1-17 11.4-11.3 17-27.2 17-47.7v-124h24.1v124C4878.2 2210.7 4870.4 2232.2 4854.7 2247.7z"/><path fill="#6d6e71" d="M5169.5 2269.8l-126.3-169.1v169.1h-24.1v-210.6h25l126.3 169.3v-169.3h23.8v210.6H5169.5z"/><path fill="#6d6e71" d="M5478.4 2073.1c16.4 9.3 29.4 21.9 38.9 37.9 9.6 16 14.3 33.9 14.3 53.5s-4.8 37.6-14.3 53.6c-9.5 16.1-22.6 28.7-39.3 37.9-16.6 9.2-35.2 13.8-55.5 13.8h-84.3v-210.6h85.2C5443.7 2059.2 5462 2063.8 5478.4 2073.1zM5362.3 2246.9h61.4c15.5.0 29.6-3.5 42.3-10.6s22.8-16.9 30.2-29.5c7.4-12.5 11.1-26.5 11.1-42s-3.8-29.4-11.3-41.9-17.7-22.3-30.6-29.6c-12.8-7.2-27-10.9-42.6-10.9h-60.5v164.5z"/><path fill="#6d6e71" d="M5668.6 2216.6l-23.5 53.2h-25.6l94.4-210.6h25l94.1 210.6h-26l-23.5-53.2H5668.6zM5725.8 2086.6l-46.9 106.8h94.4l-47.5-106.8z"/><path fill="#6d6e71" d="M5991 2082.4v187.4h-24v-187.4h-68.4v-23.2H6060v23.2h-69z"/><path fill="#6d6e71" d="M6175.9 2269.8v-210.6h24.1v210.6H6175.9z"/><path fill="#6d6e71" d="M6493.7 2072.8c16.8 9.4 30.2 22.3 40 38.4 9.8 16.2 14.8 33.9 14.8 53.3.0 19.5-4.9 37.4-14.8 53.6-9.8 16.3-23.2 29.1-40 38.6s-35.3 14.3-55.2 14.3c-20.3.0-38.8-4.7-55.7-14.3-16.8-9.5-30.2-22.4-40-38.6-9.8-16.3-14.8-34.1-14.8-53.6s4.9-37.3 14.8-53.5c9.8-16.2 23.2-29 40-38.3 16.8-9.4 35.4-14 55.7-14C6458.5 2058.6 6476.9 2063.3 6493.7 2072.8zM6395.6 2092.7c-13.1 7.4-23.6 17.5-31.4 30.1-7.8 12.6-11.8 26.5-11.8 41.7.0 15.3 3.9 29.3 11.8 42 7.8 12.7 18.3 22.8 31.4 30.2 13.1 7.4 27.4 11.1 42.9 11.1s29.7-3.7 42.7-11.1 23.3-17.4 31.1-30.2c7.7-12.7 11.6-26.7 11.6-42s-3.9-29.2-11.6-41.8c-7.7-12.6-18.1-22.6-31.1-30s-27.2-11.2-42.6-11.2C6423 2081.5 6408.8 2085.2 6395.6 2092.7z"/><path fill="#6d6e71" d="M6826.5 2269.8l-126.3-169.1v169.1h-24.1v-210.6h25l126.3 169.3v-169.3h23.8v210.6H6826.5z"/><linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="-4516.6152" y1="-2338.7222" x2="-4108.4111" y2="-1861.3982" gradientTransform="matrix(0.4226 -0.9063 0.9063 0.4226 5117.8774 -2859.9343)"><stop offset="0" style="stop-color:#F69923"/><stop offset=".3123" style="stop-color:#F79A23"/><stop offset=".8383" style="stop-color:#E97826"/></linearGradient><path fill="url(#SVGID_1_)" d="M1230.1 13.7c-45.3 26.8-120.6 102.5-210.5 212.3l82.6 155.9c58-82.9 116.9-157.5 176.3-221.2 4.6-5.1 7-7.5 7-7.5-2.3 2.5-4.6 5-7 7.5-19.2 21.2-77.5 89.2-165.5 224.4 84.7-4.2 214.9-21.6 321.1-39.7 31.6-177-31-258-31-258S1323.4-41.4 1230.1 13.7z"/><path fill="none" d="M1090.2 903.1c.6-.1 1.2-.2 1.8-.3l-11.9 1.3c-.7.3-1.4.7-2.1 1C1082.1 904.4 1086.2 903.7 1090.2 903.1z"/><path fill="none" d="M1005.9 1182.3c-6.7 1.5-13.7 2.7-20.7 3.7C992.3 1185 999.2 1183.8 1005.9 1182.3z"/><path fill="none" d="M432.9 1808.8c.9-2.3 1.8-4.7 2.6-7 18.2-48 36.2-94.7 54-140.1 20-51 39.8-100.4 59.3-148.3 20.6-50.4 40.9-99.2 60.9-146.3 21-49.4 41.7-97 62-142.8 16.5-37.3 32.8-73.4 48.9-108.3 5.4-11.7 10.7-23.2 16-34.6 10.5-22.7 21-44.8 31.3-66.5 9.5-20 19-39.6 28.3-58.8 3.1-6.4 6.2-12.8 9.3-19.1.5-1 1-2 1.5-3.1l-10.2 1.1-8-15.9c-.8 1.6-1.6 3.1-2.4 4.6-14.5 28.8-28.9 57.9-43.1 87.2-8.2 16.9-16.4 34-24.6 51-22.6 47.4-44.8 95.2-66.6 143.3-22.1 48.6-43.7 97.5-64.9 146.5-20.8 48.1-41.3 96.2-61.2 144.2-20 48-39.5 95.7-58.5 143.2-19.9 49.5-39.2 98.7-58 147.2-4.2 10.9-8.5 21.9-12.7 32.8-15 39.2-29.7 77.8-44 116l12.7 25.1 11.4-1.2c.4-1.1.8-2.3 1.3-3.4C396.7 1905.4 414.9 1856.4 432.9 1808.8z"/><path fill="none" d="M980 1186.8c.1.0.1.0.1-.1C980.1 1186.8 980.1 1186.8 980 1186.8z"/><path fill="#be202e" d="M952.6 1323c-10.6 1.9-21.4 3.8-32.5 5.7-.1.0-.1.1-.2.1 5.6-.8 11.2-1.7 16.6-2.6C942 1325.2 947.3 1324.1 952.6 1323z"/><path opacity=".35" fill="#be202e" d="M952.6 1323c-10.6 1.9-21.4 3.8-32.5 5.7-.1.0-.1.1-.2.1 5.6-.8 11.2-1.7 16.6-2.6C942 1325.2 947.3 1324.1 952.6 1323z"/><path fill="#be202e" d="M980.3 1186.7C980.2 1186.7 980.2 1186.7 980.3 1186.7c-.1.1-.2.1-.2.1 1.8-.2 3.5-.5 5.2-.8 7-1 13.9-2.2 20.7-3.7C997.5 1183.8 989 1185.2 980.3 1186.7z"/><path opacity=".35" fill="#be202e" d="M980.3 1186.7C980.2 1186.7 980.2 1186.7 980.3 1186.7c-.1.1-.2.1-.2.1 1.8-.2 3.5-.5 5.2-.8 7-1 13.9-2.2 20.7-3.7C997.5 1183.8 989 1185.2 980.3 1186.7z"/><linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="-7537.7339" y1="-2391.4075" x2="-4625.4141" y2="-2391.4075" gradientTransform="matrix(0.4226 -0.9063 0.9063 0.4226 5117.8774 -2859.9343)"><stop offset=".3233" style="stop-color:#9E2064"/><stop offset=".6302" style="stop-color:#C92037"/><stop offset=".7514" style="stop-color:#CD2335"/><stop offset="1" style="stop-color:#E97826"/></linearGradient><path fill="url(#SVGID_2_)" d="M858.6 784.7c25.1-46.9 50.5-92.8 76.2-137.4 26.7-46.4 53.7-91.3 80.9-134.7 1.6-2.6 3.2-5.2 4.8-7.7 27-42.7 54.2-83.7 81.6-122.9L1019.5 226c-6.2 7.6-12.5 15.3-18.8 23.2-23.8 29.7-48.6 61.6-73.9 95.5-28.6 38.2-58 78.9-87.8 121.7-27.6 39.5-55.5 80.9-83.5 123.7-23.8 36.5-47.7 74-71.4 112.5-.9 1.4-1.8 2.9-2.6 4.3L789 919.2c22.8-45.6 46.1-90.5 69.6-134.5z"/><linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="-7186.1777" y1="-2099.3059" x2="-5450.7183" y2="-2099.3059" gradientTransform="matrix(0.4226 -0.9063 0.9063 0.4226 5117.8774 -2859.9343)"><stop offset="0" style="stop-color:#282662"/><stop offset=".0954839" style="stop-color:#662E8D"/><stop offset=".7882" style="stop-color:#9F2064"/><stop offset=".9487" style="stop-color:#CD2032"/></linearGradient><path fill="url(#SVGID_3_)" d="M369 1981c-14.2 39.1-28.5 78.9-42.9 119.6-.2.6-.4 1.2-.6 1.8-2 5.7-4.1 11.5-6.1 17.2-9.7 27.4-18 52.1-37.3 108.2 31.7 14.5 57.1 52.5 81.1 95.6-2.6-44.7-21-86.6-56.2-119.1 156.1 7 290.6-32.4 360.1-146.6 6.2-10.2 11.9-20.9 17-32.2-31.6 40.1-70.8 57.1-144.5 53-.2.1-.3.1-.5.2.2-.1.3-.1.5-.2 108.6-48.6 163.1-95.3 211.2-172.6 11.4-18.3 22.5-38.4 33.8-60.6-94.9 97.5-205 125.3-320.9 104.2l-86.9 9.5C374.4 1966.3 371.7 1973.6 369 1981z"/><linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="-7374.1626" y1="-2418.5454" x2="-4461.8428" y2="-2418.5454" gradientTransform="matrix(0.4226 -0.9063 0.9063 0.4226 5117.8774 -2859.9343)"><stop offset=".3233" style="stop-color:#9E2064"/><stop offset=".6302" style="stop-color:#C92037"/><stop offset=".7514" style="stop-color:#CD2335"/><stop offset="1" style="stop-color:#E97826"/></linearGradient><path fill="url(#SVGID_4_)" d="M409.6 1786.3c18.8-48.5 38.1-97.7 58-147.2 19-47.4 38.5-95.2 58.5-143.2s40.4-96.1 61.2-144.2c21.2-49 42.9-97.8 64.9-146.5 21.8-48.1 44-95.9 66.6-143.3 8.1-17.1 16.3-34.1 24.6-51 14.2-29.3 28.6-58.4 43.1-87.2.8-1.6 1.6-3.1 2.4-4.6L681.4 706.8c-1.8 2.9-3.5 5.8-5.3 8.6-25.1 40.9-50 82.7-74.4 125.4-24.7 43.1-49 87.1-72.7 131.7-20 37.6-39.6 75.6-58.6 113.9-3.8 7.8-7.6 15.5-11.3 23.2-23.4 48.2-44.6 94.8-63.7 139.5-21.7 50.7-40.7 99.2-57.5 145.1-11 30.2-21 59.4-30.1 87.4-7.5 24-14.7 47.9-21.5 71.8-16 56.3-29.9 112.4-41.2 168.3L353 1935.1c14.3-38.1 28.9-76.8 44-116C401.1 1808.2 405.4 1797.3 409.6 1786.3z"/><linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="-7161.7642" y1="-2379.1431" x2="-5631.2524" y2="-2379.1431" gradientTransform="matrix(0.4226 -0.9063 0.9063 0.4226 5117.8774 -2859.9343)"><stop offset="0" style="stop-color:#282662"/><stop offset=".0954839" style="stop-color:#662E8D"/><stop offset=".7882" style="stop-color:#9F2064"/><stop offset=".9487" style="stop-color:#CD2032"/></linearGradient><path fill="url(#SVGID_5_)" d="M243.5 1729.4c-13.6 68.2-23.2 136.2-28 203.8-.2 2.4-.4 4.7-.5 7.1-33.7-54-124-106.8-123.8-106.2 64.6 93.7 113.7 186.7 120.9 278-34.6 7.1-82-3.2-136.8-23.3 57.1 52.5 1e2 67 116.7 70.9-52.5 3.3-107.1 39.3-162.1 80.8 80.5-32.8 145.5-45.8 192.1-35.3C148.1 2414.2 74.1 2645 0 2890c22.7-6.7 36.2-21.9 43.9-42.6 13.2-44.4 100.8-335.6 238-718.2 3.9-10.9 7.8-21.8 11.8-32.9 1.1-3 2.2-6.1 3.3-9.2 14.5-40.1 29.5-81.1 45.1-122.9 3.5-9.5 7.1-19 10.7-28.6.1-.2.1-.4.2-.6l-107.9-213.2C244.6 1724.4 244 1726.9 243.5 1729.4z"/><linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="-7374.1626" y1="-2117.1309" x2="-4461.8428" y2="-2117.1309" gradientTransform="matrix(0.4226 -0.9063 0.9063 0.4226 5117.8774 -2859.9343)"><stop offset=".3233" style="stop-color:#9E2064"/><stop offset=".6302" style="stop-color:#C92037"/><stop offset=".7514" style="stop-color:#CD2335"/><stop offset="1" style="stop-color:#E97826"/></linearGradient><path fill="url(#SVGID_6_)" d="M805.6 937c-3.1 6.3-6.2 12.7-9.3 19.1-9.3 19.2-18.8 38.8-28.3 58.8-10.3 21.7-20.7 43.9-31.3 66.5-5.3 11.4-10.6 22.9-16 34.6-16.1 35-32.4 71.1-48.9 108.3-20.3 45.8-41 93.4-62 142.8-20 47.1-40.3 95.9-60.9 146.3-19.5 47.9-39.3 97.3-59.3 148.3-17.8 45.4-35.9 92.1-54 140.1-.9 2.3-1.8 4.7-2.6 7-18 47.6-36.2 96.6-54.6 146.8-.4 1.1-.8 2.3-1.3 3.4l86.9-9.5c-1.7-.3-3.5-.5-5.2-.9 103.9-13 242.1-90.6 331.4-186.5 41.1-44.2 78.5-96.3 113-157.3 25.7-45.4 49.8-95.8 72.8-151.5 20.1-48.7 39.4-101.4 58-158.6-23.9 12.6-51.2 21.8-81.4 28.2-5.3 1.1-10.7 2.2-16.1 3.1-5.5 1-11 1.8-16.6 2.6.1.0.1-.1.2-.1 96.9-37.3 158-109.2 202.4-197.4-25.5 17.4-66.9 40.1-116.6 51.1-6.7 1.5-13.7 2.7-20.7 3.7-1.7.3-3.5.6-5.2.8.1.0.1.0.1-.1h.1c33.6-14.1 62-29.8 86.6-48.4 5.3-4 10.4-8.1 15.3-12.3 7.5-6.5 14.7-13.3 21.5-20.5 4.4-4.6 8.6-9.3 12.7-14.2 9.6-11.5 18.7-23.9 27.1-37.3 2.6-4.1 5.1-8.3 7.6-12.6 3.2-6.2 6.3-12.3 9.3-18.3 13.5-27.2 24.4-51.5 33-72.8 4.3-10.6 8.1-20.5 11.3-29.7 1.3-3.7 2.5-7.2 3.7-10.6 3.4-10.2 6.2-19.3 8.4-27.3 3.3-12 5.3-21.5 6.4-28.4-3.3 2.6-7.1 5.2-11.3 7.7-29.3 17.5-79.5 33.4-119.9 40.8l79.8-8.8-79.8 8.8c-.6.1-1.2.2-1.8.3-4 .7-8.1 1.3-12.2 2 .7-.3 1.4-.7 2.1-1l-273 29.9C806.6 935 806.1 936 805.6 937z"/><linearGradient id="SVGID_7_" gradientUnits="userSpaceOnUse" x1="-7554.8232" y1="-2132.0981" x2="-4642.5034" y2="-2132.0981" gradientTransform="matrix(0.4226 -0.9063 0.9063 0.4226 5117.8774 -2859.9343)"><stop offset=".3233" style="stop-color:#9E2064"/><stop offset=".6302" style="stop-color:#C92037"/><stop offset=".7514" style="stop-color:#CD2335"/><stop offset="1" style="stop-color:#E97826"/></linearGradient><path fill="url(#SVGID_7_)" d="M1112.9 385.1c-24.3 37.3-50.8 79.6-79.4 127.5-1.5 2.5-3 5.1-4.5 7.6-24.6 41.5-50.8 87.1-78.3 137-23.8 43.1-48.5 89.3-74.3 139C854 839.5 830.8 885.4 807 934l273-29.9c79.5-36.6 115.1-69.7 149.6-117.6 9.2-13.2 18.4-27 27.5-41.3 28-43.8 55.6-92 80.1-139.9 23.7-46.3 44.7-92.2 60.7-133.5 10.2-26.3 18.4-50.8 24.1-72.3 5-19 8.9-36.9 11.9-54.1C1327.9 363.5 1197.6 380.9 1112.9 385.1z"/><path fill="#be202e" d="M936.5 1326.1c-5.5 1-11 1.8-16.6 2.6C925.5 1328 931 1327.1 936.5 1326.1z"/><path opacity=".35" fill="#be202e" d="M936.5 1326.1c-5.5 1-11 1.8-16.6 2.6C925.5 1328 931 1327.1 936.5 1326.1z"/><linearGradient id="SVGID_8_" gradientUnits="userSpaceOnUse" x1="-7374.1626" y1="-2027.484" x2="-4461.8433" y2="-2027.484" gradientTransform="matrix(0.4226 -0.9063 0.9063 0.4226 5117.8774 -2859.9343)"><stop offset=".3233" style="stop-color:#9E2064"/><stop offset=".6302" style="stop-color:#C92037"/><stop offset=".7514" style="stop-color:#CD2335"/><stop offset="1" style="stop-color:#E97826"/></linearGradient><path fill="url(#SVGID_8_)" d="M936.5 1326.1c-5.5 1-11 1.8-16.6 2.6C925.5 1328 931 1327.1 936.5 1326.1z"/><path fill="#be202e" d="M980 1186.8c1.8-.2 3.5-.5 5.2-.8C983.5 1186.3 981.8 1186.6 980 1186.8z"/><path opacity=".35" fill="#be202e" d="M980 1186.8c1.8-.2 3.5-.5 5.2-.8C983.5 1186.3 981.8 1186.6 980 1186.8z"/><linearGradient id="SVGID_9_" gradientUnits="userSpaceOnUse" x1="-7374.1626" y1="-2037.7417" x2="-4461.8433" y2="-2037.7417" gradientTransform="matrix(0.4226 -0.9063 0.9063 0.4226 5117.8774 -2859.9343)"><stop offset=".3233" style="stop-color:#9E2064"/><stop offset=".6302" style="stop-color:#C92037"/><stop offset=".7514" style="stop-color:#CD2335"/><stop offset="1" style="stop-color:#E97826"/></linearGradient><path fill="url(#SVGID_9_)" d="M980 1186.8c1.8-.2 3.5-.5 5.2-.8C983.5 1186.3 981.8 1186.6 980 1186.8z"/><path fill="#be202e" d="M980.2 1186.7z"/><path opacity=".35" fill="#be202e" d="M980.2 1186.7z"/><linearGradient id="SVGID_10_" gradientUnits="userSpaceOnUse" x1="-5738.0635" y1="-2039.799" x2="-5094.3457" y2="-2039.799" gradientTransform="matrix(0.4226 -0.9063 0.9063 0.4226 5117.8774 -2859.9343)"><stop offset=".3233" style="stop-color:#9E2064"/><stop offset=".6302" style="stop-color:#C92037"/><stop offset=".7514" style="stop-color:#CD2335"/><stop offset="1" style="stop-color:#E97826"/></linearGradient><path fill="url(#SVGID_10_)" d="M980.2 1186.7z"/></svg></div></a><ul class=footer-link><li><a class=white href=http://www.apache.org>Foundation</a></li><li><a class=white href=http://www.apache.org/licenses/>License</a></li><li><a class=white href=https://www.apache.org/security/>Security</a></li><li><a class=white href=http://www.apache.org/events/current-event>Events</a></li><li><a class=white href=http://www.apache.org/foundation/sponsorship.html>Sponsorship</a></li><li><a class=white href=http://www.apache.org/foundation/thanks.html>Thanks</a></li><li><a class=white href=https://privacy.apache.org/policies/privacy-policy-public.html target=_blank>Privacy</a></li></ul></div></div><div class="col-6 text-white text-center container-center"><p>Copyright &copy; 2024 The Apache Software Foundation, Licensed under the <a class=white href=https://www.apache.org/licenses/LICENSE-2.0>Apache License Version 2.0</a></p><p>Apache and the Apache feather logo are trademarks of The Apache Software Foundation.</p></div><div class=col-1></div></div></div></footer></div><script src=https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js integrity=sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN crossorigin=anonymous></script>
<script src=https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.min.js integrity="sha512-UR25UO94eTnCVwjbXozyeVd6ZqpaAE9naiEUBK/A+QDbfSTQFhPGj5lOR6d8tsgbBk84Ggb5A3EkjsOgPRPcKA==" crossorigin=anonymous></script>
<script src=/js/tabpane-persist.js></script>
<script src=/js/main.min.aa9f4c5dae6a98b2c46277f4c56f1673a2b000d1756ce4ffae93784cab25e6d5.js integrity="sha256-qp9MXa5qmLLEYnf0xW8Wc6KwANF1bOT/rpN4TKsl5tU=" crossorigin=anonymous></script>
<script src=/js/prism.js></script></body></html>