This is an automated email from the ASF dual-hosted git repository.
stoty pushed a commit to branch branch-3
in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/branch-3 by this push:
new 49caa728ed3 HBASE-28411 Remove direct dependency on Curator (#5726)
49caa728ed3 is described below
commit 49caa728ed30e558c6a5354044a1da01d8f909d9
Author: Istvan Toth <[email protected]>
AuthorDate: Tue Sep 2 14:55:02 2025 +0200
HBASE-28411 Remove direct dependency on Curator (#5726)
Signed-off-by: Duo Zhang <[email protected]>
(cherry picked from commit c170311752ff578f3fc83ca81368d6b94416e95e)
---
hbase-examples/pom.xml | 12 --
.../example/ZooKeeperScanPolicyObserver.java | 121 +++++++++++++--------
pom.xml | 50 ++-------
3 files changed, 85 insertions(+), 98 deletions(-)
diff --git a/hbase-examples/pom.xml b/hbase-examples/pom.xml
index c90a46644a4..e1a29d665b9 100644
--- a/hbase-examples/pom.xml
+++ b/hbase-examples/pom.xml
@@ -127,18 +127,6 @@
<artifactId>protobuf-java</artifactId>
<version>${internal.protobuf.version}</version>
</dependency>
- <dependency>
- <groupId>org.apache.curator</groupId>
- <artifactId>curator-framework</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.curator</groupId>
- <artifactId>curator-client</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.curator</groupId>
- <artifactId>curator-recipes</artifactId>
- </dependency>
<dependency>
<groupId>com.github.stephenc.findbugs</groupId>
<artifactId>findbugs-annotations</artifactId>
diff --git
a/hbase-examples/src/main/java/org/apache/hadoop/hbase/coprocessor/example/ZooKeeperScanPolicyObserver.java
b/hbase-examples/src/main/java/org/apache/hadoop/hbase/coprocessor/example/ZooKeeperScanPolicyObserver.java
index 1fba63d054a..7a8978ea8d0 100644
---
a/hbase-examples/src/main/java/org/apache/hadoop/hbase/coprocessor/example/ZooKeeperScanPolicyObserver.java
+++
b/hbase-examples/src/main/java/org/apache/hadoop/hbase/coprocessor/example/ZooKeeperScanPolicyObserver.java
@@ -20,11 +20,6 @@ package org.apache.hadoop.hbase.coprocessor.example;
import java.io.IOException;
import java.util.Optional;
import java.util.OptionalLong;
-import org.apache.curator.framework.CuratorFramework;
-import org.apache.curator.framework.CuratorFrameworkFactory;
-import org.apache.curator.framework.recipes.cache.ChildData;
-import org.apache.curator.framework.recipes.cache.NodeCache;
-import org.apache.curator.retry.RetryForever;
import org.apache.hadoop.hbase.CoprocessorEnvironment;
import org.apache.hadoop.hbase.coprocessor.ObserverContext;
import org.apache.hadoop.hbase.coprocessor.RegionCoprocessor;
@@ -39,6 +34,14 @@ import
org.apache.hadoop.hbase.regionserver.compactions.CompactionRequest;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
import org.apache.yetus.audience.InterfaceAudience;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.KeeperException.NodeExistsException;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.data.Stat;
/**
* This is an example showing how a RegionObserver could be configured via
ZooKeeper in order to
@@ -66,72 +69,105 @@ public class ZooKeeperScanPolicyObserver implements
RegionCoprocessor, RegionObs
public static final String NODE = "/backup/example/lastbackup";
private static final String ZKKEY = "ZK";
- private NodeCache cache;
+ private ZKDataHolder cache;
/**
* Internal watcher that keep "data" up to date asynchronously.
*/
- private static final class ZKDataHolder {
+ private static final class ZKDataHolder implements Watcher {
private final String ensemble;
private final int sessionTimeout;
- private CuratorFramework client;
-
- private NodeCache cache;
+ private ZooKeeper zk;
private int ref;
+ private byte[] data;
+
public ZKDataHolder(String ensemble, int sessionTimeout) {
this.ensemble = ensemble;
this.sessionTimeout = sessionTimeout;
}
- private void create() throws Exception {
- client =
-
CuratorFrameworkFactory.builder().connectString(ensemble).sessionTimeoutMs(sessionTimeout)
- .retryPolicy(new RetryForever(1000)).canBeReadOnly(true).build();
- client.start();
- cache = new NodeCache(client, NODE);
- cache.start(true);
+ private void open() throws IOException {
+ if (zk == null) {
+ zk = new ZooKeeper(ensemble, sessionTimeout, this);
+ // In a real application, you'd probably want to create these Znodes
externally,
+ // and not from the coprocessor
+ StringBuffer createdPath = new StringBuffer();
+ byte[] empty = new byte[0];
+ for (String element : NODE.split("/")) {
+ if (element.isEmpty()) {
+ continue;
+ }
+ try {
+ createdPath = createdPath.append("/").append(element);
+ zk.create(createdPath.toString(), empty,
ZooDefs.Ids.OPEN_ACL_UNSAFE,
+ CreateMode.PERSISTENT);
+ } catch (NodeExistsException e) {
+ // That's OK
+ } catch (KeeperException e) {
+ throw new IOException(e);
+ } catch (InterruptedException e) {
+ // Restore interrupt status
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
}
private void close() {
- if (cache != null) {
+ if (zk != null) {
try {
- cache.close();
- } catch (IOException e) {
- // should not happen
- throw new AssertionError(e);
+ zk.close();
+ zk = null;
+ } catch (InterruptedException e) {
+ // Restore interrupt status
+ Thread.currentThread().interrupt();
}
- cache = null;
- }
- if (client != null) {
- client.close();
- client = null;
}
}
- public synchronized NodeCache acquire() throws Exception {
+ public synchronized byte[] getData() {
if (ref == 0) {
+ Stat stat = null;
try {
- create();
- } catch (Exception e) {
- close();
- throw e;
+ stat = zk.exists(NODE, this);
+ } catch (KeeperException e) {
+ // Value will always be null if the initial connection fails.
+ // In a real application you probably want to try to
+ // periodically re-connect in this case.
+ } catch (InterruptedException e) {
+ // Restore interrupt status
+ Thread.currentThread().interrupt();
+ }
+ if (stat != null) {
+ refresh();
}
}
ref++;
- return cache;
+ return data;
}
- public synchronized void release() {
- ref--;
- if (ref == 0) {
- close();
+ private synchronized void refresh() {
+ try {
+ data = zk.getData(NODE, this, null);
+ } catch (KeeperException e) {
+ // Value will always be null if this fails (as we cannot set the new
watcher)
+ // In a real application you probably want to try to
+ // periodically re-connect in this case.
+ } catch (InterruptedException e) {
+ // Restore interrupt status
+ Thread.currentThread().interrupt();
}
}
+
+ @Override
+ public void process(WatchedEvent event) {
+ refresh();
+ }
}
@Override
@@ -143,7 +179,8 @@ public class ZooKeeperScanPolicyObserver implements
RegionCoprocessor, RegionObs
int sessionTimeout =
renv.getConfiguration().getInt(ZK_SESSION_TIMEOUT_KEY,
ZK_SESSION_TIMEOUT_DEFAULT);
return new ZKDataHolder(ensemble, sessionTimeout);
- })).acquire();
+ }));
+ cache.open();
} catch (Exception e) {
throw new IOException(e);
}
@@ -153,15 +190,11 @@ public class ZooKeeperScanPolicyObserver implements
RegionCoprocessor, RegionObs
public void stop(CoprocessorEnvironment env) throws IOException {
RegionCoprocessorEnvironment renv = (RegionCoprocessorEnvironment) env;
this.cache = null;
- ((ZKDataHolder) renv.getSharedData().get(ZKKEY)).release();
+ ((ZKDataHolder) renv.getSharedData().get(ZKKEY)).close();
}
private OptionalLong getExpireBefore() {
- ChildData data = cache.getCurrentData();
- if (data == null) {
- return OptionalLong.empty();
- }
- byte[] bytes = data.getData();
+ byte[] bytes = cache.getData();
if (bytes == null || bytes.length != Long.BYTES) {
return OptionalLong.empty();
}
diff --git a/pom.xml b/pom.xml
index 368fba739f2..6ff7f5a056a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -872,7 +872,6 @@
<bouncycastle.version>1.81</bouncycastle.version>
<skyscreamer.version>1.5.1</skyscreamer.version>
<commons-crypto.version>1.1.0</commons-crypto.version>
- <curator.version>5.7.1</curator.version>
<!-- Plugin Dependencies -->
<build.helper.maven.version>3.0.0</build.helper.maven.version>
<buildnumber.maven.version>1.4</buildnumber.maven.version>
@@ -1695,47 +1694,6 @@
</exclusion>
</exclusions>
</dependency>
- <dependency>
- <groupId>org.apache.curator</groupId>
- <artifactId>curator-framework</artifactId>
- <version>${curator.version}</version>
- <exclusions>
- <exclusion>
- <groupId>org.apache.zookeeper</groupId>
- <artifactId>zookeeper</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.apache.curator</groupId>
- <artifactId>curator-client</artifactId>
- <version>${curator.version}</version>
- <exclusions>
- <exclusion>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.apache.zookeeper</groupId>
- <artifactId>zookeeper</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.apache.curator</groupId>
- <artifactId>curator-recipes</artifactId>
- <version>${curator.version}</version>
- <exclusions>
- <exclusion>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.apache.zookeeper</groupId>
- <artifactId>zookeeper</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
<dependency>
<groupId>org.apache.yetus</groupId>
<artifactId>audience-annotations</artifactId>
@@ -2586,6 +2544,14 @@
<bannedImport>org.apache.hadoop.thirdparty.**</bannedImport>
</bannedImports>
</restrictImports>
+ <restrictImports
implementation="de.skuzzle.enforcer.restrictimports.rule.RestrictImports">
+ <includeTestCode>true</includeTestCode>
+ <commentLineBufferSize>512</commentLineBufferSize>
+ <reason>Use ZooKeeper directly</reason>
+ <bannedImports>
+ <bannedImport>org.apache.curator.**</bannedImport>
+ </bannedImports>
+ </restrictImports>
<restrictImports
implementation="de.skuzzle.enforcer.restrictimports.rule.RestrictImports">
<includeTestCode>true</includeTestCode>
<commentLineBufferSize>512</commentLineBufferSize>