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 <[email protected]> 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>
