You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@helix.apache.org by xy...@apache.org on 2023/04/27 20:36:10 UTC

[helix] 01/37: Add new submodule meta client - a generic metadata client (#2234)

This is an automated email from the ASF dual-hosted git repository.

xyuanlu pushed a commit to branch metaclient
in repository https://gitbox.apache.org/repos/asf/helix.git

commit e3dcfbcf1bfba12774836f95b83d5741ddbd25f9
Author: xyuanlu <xy...@gmail.com>
AuthorDate: Thu Oct 20 09:49:07 2022 -0700

    Add new submodule meta client - a generic metadata client (#2234)
    
    Add new submodule meta client - a generic metadata client
---
 meta-client/pom.xml                                |  73 ++++++++++
 meta-client/src/assemble/assembly.xml              |  60 ++++++++
 .../apache/helix/metaclient/api/AsyncCallback.java |  49 +++++++
 .../apache/helix/metaclient/api/DataUpdater.java   |  28 ++++
 .../helix/metaclient/api/MetaClientInterface.java  | 158 +++++++++++++++++++++
 .../java/org/apache/helix/metaclient/api/Op.java   |  38 +++++
 .../org/apache/helix/metaclient/api/OpResult.java  |  26 ++++
 pom.xml                                            |   1 +
 8 files changed, 433 insertions(+)

diff --git a/meta-client/pom.xml b/meta-client/pom.xml
new file mode 100644
index 000000000..24e07ebb8
--- /dev/null
+++ b/meta-client/pom.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <parent>
+    <groupId>org.apache.helix</groupId>
+    <artifactId>helix</artifactId>
+    <version>1.0.5-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>meta-client</artifactId>
+  <packaging>bundle</packaging>
+  <name>Apache Helix :: Meta Client</name>
+
+  <properties>
+    <osgi.import>
+      org.apache.commons.cli*,
+      *
+    </osgi.import>
+    <osgi.export>org.apache.helix.metaclient*;version="${project.version};-noimport:=true</osgi.export>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.helix</groupId>
+      <artifactId>zookeeper-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <resources>
+      <resource>
+        <directory>${basedir}</directory>
+        <includes>
+          <include>DISCLAIMER</include>
+        </includes>
+      </resource>
+    </resources>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <configuration>
+          <descriptors>
+            <descriptor>src/assemble/assembly.xml</descriptor>
+          </descriptors>
+        </configuration>
+        <executions>
+          <execution>
+            <phase>package</phase>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
\ No newline at end of file
diff --git a/meta-client/src/assemble/assembly.xml b/meta-client/src/assemble/assembly.xml
new file mode 100644
index 000000000..cd4eb210c
--- /dev/null
+++ b/meta-client/src/assemble/assembly.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+<assembly>
+  <id>pkg</id>
+  <formats>
+    <format>tar</format>
+  </formats>
+  <fileSets>
+    <fileSet>
+      <directory>${project.build.directory}/${project.artifactId}-pkg/bin</directory>
+      <outputDirectory>bin</outputDirectory>
+      <lineEnding>unix</lineEnding>
+      <fileMode>0755</fileMode>
+      <directoryMode>0755</directoryMode>
+    </fileSet>
+    <fileSet>
+      <directory>${project.build.directory}/${project.artifactId}-pkg/repo/</directory>
+      <outputDirectory>repo</outputDirectory>
+      <fileMode>0755</fileMode>
+      <directoryMode>0755</directoryMode>
+      <excludes>
+        <exclude>**/*.xml</exclude>
+      </excludes>
+    </fileSet>
+    <fileSet>
+      <directory>${project.build.directory}/${project.artifactId}-pkg/conf</directory>
+      <outputDirectory>conf</outputDirectory>
+      <lineEnding>unix</lineEnding>
+      <fileMode>0755</fileMode>
+      <directoryMode>0755</directoryMode>
+    </fileSet>
+    <fileSet>
+      <directory>${project.basedir}</directory>
+      <outputDirectory>/</outputDirectory>
+      <includes>
+        <include>LICENSE</include>
+        <include>NOTICE</include>
+        <include>DISCLAIMER</include>
+      </includes>
+      <fileMode>0755</fileMode>
+    </fileSet>
+  </fileSets>
+</assembly>
\ No newline at end of file
diff --git a/meta-client/src/main/java/org/apache/helix/metaclient/api/AsyncCallback.java b/meta-client/src/main/java/org/apache/helix/metaclient/api/AsyncCallback.java
new file mode 100644
index 000000000..1bfa5c6ab
--- /dev/null
+++ b/meta-client/src/main/java/org/apache/helix/metaclient/api/AsyncCallback.java
@@ -0,0 +1,49 @@
+package org.apache.helix.metaclient.api;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+/**
+ * An asynchronous callback is deferred to invoke after an async CRUD operation returns.
+ * The corresponding callback is registered when async CRUD API is invoked.
+ */
+public interface AsyncCallback {
+  //This callback is used when stat object is returned from the operation.
+  interface StatCallback extends AsyncCallback {
+    void processResult(int returnCode, String key, Object context, MetaClientInterface.Stat stat);
+  }
+
+  //This callback is used when data is returned from the operation.
+  interface DataCallback extends AsyncCallback {
+    void processResult(int returnCode, String key, Object context, byte[] data, MetaClientInterface.Stat stat);
+  }
+
+  //This callback is used when nothing is returned from the operation.
+  interface VoidCallback extends AsyncCallback {
+    void processResult(int returnCode, String key, Object context);
+  }
+
+  //This callback is used to process the list if OpResults from a single transactional call.
+  interface TransactionCallback extends AsyncCallback {
+    void processResult(int returnCode, String key, Object context, List<OpResult> opResults);
+  }
+
+}
\ No newline at end of file
diff --git a/meta-client/src/main/java/org/apache/helix/metaclient/api/DataUpdater.java b/meta-client/src/main/java/org/apache/helix/metaclient/api/DataUpdater.java
new file mode 100644
index 000000000..6ad45d642
--- /dev/null
+++ b/meta-client/src/main/java/org/apache/helix/metaclient/api/DataUpdater.java
@@ -0,0 +1,28 @@
+package org.apache.helix.metaclient.api;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Updates the value of a key. This is used together with {@link MetaClientInterface.update(String key, DataUpdater<T> updater)}.
+ * @param <T>
+ */
+public interface DataUpdater<T extends Object> {
+  public T update(T currentData);
+}
\ No newline at end of file
diff --git a/meta-client/src/main/java/org/apache/helix/metaclient/api/MetaClientInterface.java b/meta-client/src/main/java/org/apache/helix/metaclient/api/MetaClientInterface.java
new file mode 100644
index 000000000..4ad649c26
--- /dev/null
+++ b/meta-client/src/main/java/org/apache/helix/metaclient/api/MetaClientInterface.java
@@ -0,0 +1,158 @@
+package org.apache.helix.metaclient.api;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+
+public interface MetaClientInterface<T> {
+
+  enum EntryMode {
+    //The node will be removed automatically when the session associated with the creation
+    // of the node expires.
+    EPHEMERAL,
+    //The node will not be automatically deleted upon client's disconnect.
+    PERSISTENT
+  }
+
+  /**
+   * Interface representing the metadata of an entry. It contains entry type and version number.
+   */
+  class Stat {
+    private int _version;
+    private EntryMode _entryMode;
+
+    public EntryMode getEntryType() {return _entryMode;}
+    public int getVersion() {return  _version;}
+  }
+
+  //synced CRUD API
+  void create(final String key, T data, final EntryMode mode);
+
+  void create(final String key, T data, final EntryMode mode, long ttl);
+
+  /**
+   * Set the data for the entry of the given key if it exists and the given version matches the
+   * version of the node (if the given version is -1, it matches any node's versions).
+   */
+  void set(final String key, T data, int version);
+
+  /**
+   * Update existing data of a given key using an updater. This method will issue a read to get
+   * current data and apply updater upon the current data.
+   * @param updater : An updater that modifies the entry value.
+   * @return: the updated value.
+   */
+  T update(String key, DataUpdater<T> updater);
+
+  /**
+   * Check if there is an entry for the given key.
+   * @param key
+   * @return return a Stat object if the entry exists. Return null otherwise.
+   */
+  Stat exists(final String key);
+
+  /**
+   * Fetch the data for a given key.
+   * TODO: define exception type when key does not exist
+   */
+  T get(String key);
+
+  /**
+   * API for transaction. The list of operation will be executed as an atomic operation.
+   * @param ops a list of operations. These operations will all be executed or non of them.
+   * @return
+   */
+  List<OpResult> transactionOP(final Iterable<Op> ops);
+
+  /**
+   * Return a list of sub entries for the given keys
+   * @param path: For metadata storage that has hierarchical key space (e.g. ZK), the path would be
+   *            a parent path,
+   *            For metadata storage that has non-hierarchical key space (e.g. etcd), the path would
+   *            be a prefix path.
+   */
+  List<String> getSubEntryKeys(final String path);
+
+  /**
+   * Return the number of sub entries for the given keys
+   * @param path: For metadata storage that has hierarchical key space (e.g. ZK), the path would be
+   *            a parent path,
+   *            For metadata storage that has non-hierarchical key space (e.g. etcd), the path would
+   *            be a prefix path.
+   */
+  int countSubEntries(final String path);
+
+  /**
+   * Remove the entry associated with the given key.
+   * For metadata storage that has hierarchical key space, the entry can only be deleted if the key
+   * has no child entry.
+   * TODO: throws
+   * @param path
+   * @return
+   */
+  boolean delete(String path);
+
+  /**
+   * Remove the entry associated with the given key.
+   * For metadata storage that has hierarchical key space, remove all its child entries as well
+   * For metadata storage that has non-hierarchical key space, this API is the same as delete()
+   * @param path
+   * @return
+   */
+  boolean recursiveDelete(String path);
+
+  /* Asynchronous methods return immediately.
+   * They take a callback object that will be executed either on successful execution of the request
+   * or on error with an appropriate return code indicating the error.
+   */
+  void asyncCreate(final String key, T data, int version, long ttl,
+      AsyncCallback.VoidCallback cb);
+
+  void asyncSet(final String key, T data, int version, AsyncCallback.VoidCallback cb);
+
+  void asyncUpdate(final String key, DataUpdater<T> updater, AsyncCallback.VoidCallback cb);
+
+  void asyncGet(final String key, AsyncCallback.DataCallback cb);
+
+  void asyncCountSubEntries(final String path, AsyncCallback.DataCallback cb);
+
+  void asyncExist(final String key, AsyncCallback.StatCallback cb);
+
+  void asyncDelete(final String keys, AsyncCallback.VoidCallback cb);
+
+  void asyncTransaction(final String keys, AsyncCallback.TransactionCallback cb);
+
+  /* Batched APIs return result to user when all request finishes.
+   * These calls are not executed as a transaction.
+   */
+  boolean[] create(List<String> key, List<T> data, List<EntryMode> mode, List<Long> ttl);
+
+  boolean[] set(List<String> keys, List<T> values, List<Integer> version);
+
+  List<T> update(List<String> keys, List<DataUpdater<T>> updater);
+
+  List<T> get(List<String> keys);
+
+  List<Stat> exists(List<String> keys);
+
+  boolean[] delete(List<String> keys);
+
+}
\ No newline at end of file
diff --git a/meta-client/src/main/java/org/apache/helix/metaclient/api/Op.java b/meta-client/src/main/java/org/apache/helix/metaclient/api/Op.java
new file mode 100644
index 000000000..0c596d877
--- /dev/null
+++ b/meta-client/src/main/java/org/apache/helix/metaclient/api/Op.java
@@ -0,0 +1,38 @@
+package org.apache.helix.metaclient.api;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ *  Represents a single operation in a multi-operation transaction.  Each operation can be a create, set,
+ *  version check or delete operation.
+ */
+public class Op {
+  /**
+   * Check the version of an entry. True only when the version is the same as expected.
+   */
+  public static class Check extends Op {
+  }
+  public static class Create extends Op{
+  }
+  public static class Delete extends Op{
+  }
+  public static class Set extends Op{
+  }
+}
diff --git a/meta-client/src/main/java/org/apache/helix/metaclient/api/OpResult.java b/meta-client/src/main/java/org/apache/helix/metaclient/api/OpResult.java
new file mode 100644
index 000000000..aae379df7
--- /dev/null
+++ b/meta-client/src/main/java/org/apache/helix/metaclient/api/OpResult.java
@@ -0,0 +1,26 @@
+package org.apache.helix.metaclient.api;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Represent the result of a single operation of a multi operation transaction.
+ */
+public class OpResult {
+}
diff --git a/pom.xml b/pom.xml
index ae321b083..399b4e4d3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -310,6 +310,7 @@
     <module>helix-front</module>
     <module>recipes</module>
     <module>helix-view-aggregator</module>
+    <module>meta-client</module>
   </modules>
 
   <mailingLists>