diff --git a/sharding-orchestration/pom.xml b/sharding-orchestration/pom.xml
index 72cb52051055054fe6a201e250dd882f04924bc6..7bed9e04474f3d61af7ab1ae319ab75cccc52b8f 100644
--- a/sharding-orchestration/pom.xml
+++ b/sharding-orchestration/pom.xml
@@ -32,5 +32,6 @@
Maybe use cache if existed.
+ * + * @param key key of data + * @return value of data + */ + String get(String key); + + /** + * Persist data. + * + * @param key key of data + * @param value value of data + */ + void persist(String key, String value); + + /** + * Close. + */ + void close(); + + /** + * Initialize the lock of the key. + * + * @param key key of data + */ + void initLock(String key); + + /** + * Try to get the lock of the key. + * + * @return get the lock or not + */ + boolean tryLock(); + + /** + * Try to release the lock of the key. + * + */ + void tryRelease(); +} diff --git a/sharding-orchestration/sharding-orchestration-distributed-lock/sharding-orchestration-distributed-lock-api/src/main/java/org/apache/shardingsphere/orchestration/distributed/lock/api/DistributedLockConfiguration.java b/sharding-orchestration/sharding-orchestration-distributed-lock/sharding-orchestration-distributed-lock-api/src/main/java/org/apache/shardingsphere/orchestration/distributed/lock/api/DistributedLockConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..67d0ad401e7f7a0ff00b89c8872325da5552a90a --- /dev/null +++ b/sharding-orchestration/sharding-orchestration-distributed-lock/sharding-orchestration-distributed-lock-api/src/main/java/org/apache/shardingsphere/orchestration/distributed/lock/api/DistributedLockConfiguration.java @@ -0,0 +1,77 @@ +/* + * 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. + */ + +package org.apache.shardingsphere.orchestration.distributed.lock.api; + +import lombok.Getter; +import lombok.Setter; +import org.apache.shardingsphere.api.config.TypeBasedSPIConfiguration; + +import java.util.Properties; + +/** + * Distributed Lock configuration. + * + * @author wangguangyuan + */ +@Getter +@Setter +public final class DistributedLockConfiguration extends TypeBasedSPIConfiguration { + + /** + * Server list of distributed lock center. + */ + private String serverLists; + + /** + * Namespace of distributed lock center. + */ + private String namespace; + + /** + * Digest of distributed lock center. + */ + private String digest; + + /** + * Operation timeout time in milliseconds. + */ + private int operationTimeoutMilliseconds = 500; + + /** + * Max number of times to retry. + */ + private int maxRetries = 3; + + /** + * Time interval in milliseconds on each retry. + */ + private int retryIntervalMilliseconds = 500; + + /** + * Time to live in seconds of ephemeral keys. + */ + private int timeToLiveSeconds = 60; + + public DistributedLockConfiguration(final String type) { + super(type); + } + + public DistributedLockConfiguration(final String type, final Properties properties) { + super(type, properties); + } +} diff --git a/sharding-orchestration/sharding-orchestration-distributed-lock/sharding-orchestration-distributed-lock-api/src/main/java/org/apache/shardingsphere/orchestration/distributed/lock/exception/DistributedLockException.java b/sharding-orchestration/sharding-orchestration-distributed-lock/sharding-orchestration-distributed-lock-api/src/main/java/org/apache/shardingsphere/orchestration/distributed/lock/exception/DistributedLockException.java new file mode 100644 index 0000000000000000000000000000000000000000..43abf94ee9dac8e200defec01d52b7e1997e2796 --- /dev/null +++ b/sharding-orchestration/sharding-orchestration-distributed-lock/sharding-orchestration-distributed-lock-api/src/main/java/org/apache/shardingsphere/orchestration/distributed/lock/exception/DistributedLockException.java @@ -0,0 +1,36 @@ +/* + * 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. + */ + +package org.apache.shardingsphere.orchestration.distributed.lock.exception; + +/** + * Distributed Lock exception. + * + * @author wangguangyuan + */ +public final class DistributedLockException extends RuntimeException { + + private static final long serialVersionUID = -6417179023552012152L; + + public DistributedLockException(final String errorMessage, final Object... args) { + super(String.format(errorMessage, args)); + } + + public DistributedLockException(final Exception cause) { + super(cause); + } +} diff --git a/sharding-orchestration/sharding-orchestration-distributed-lock/sharding-orchestration-distributed-lock-zookeeper-curator/pom.xml b/sharding-orchestration/sharding-orchestration-distributed-lock/sharding-orchestration-distributed-lock-zookeeper-curator/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..17402f8b5ef3d9666e3073e724cb9bc19c7bfec6 --- /dev/null +++ b/sharding-orchestration/sharding-orchestration-distributed-lock/sharding-orchestration-distributed-lock-zookeeper-curator/pom.xml @@ -0,0 +1,53 @@ + + +Ignore interrupt and connection invalid exception.
+ * + * @param cause to be handled exception + */ + public static void handleException(final Exception cause) { + if (null == cause) { + return; + } + if (isIgnoredException(cause) || null != cause.getCause() && isIgnoredException(cause.getCause())) { + log.debug("Ignored exception for: {}", cause.getMessage()); + } else if (cause instanceof InterruptedException) { + Thread.currentThread().interrupt(); + } else { + throw new DistributedLockException(cause); + } + } + + private static boolean isIgnoredException(final Throwable cause) { + return cause instanceof ConnectionLossException || cause instanceof NoNodeException || cause instanceof NodeExistsException; + } +} diff --git a/sharding-orchestration/sharding-orchestration-distributed-lock/sharding-orchestration-distributed-lock-zookeeper-curator/src/main/resources/META-INF.services/org.apache.shardingsphere.orchestration.distributed.lock.api.DistributedLockCenter b/sharding-orchestration/sharding-orchestration-distributed-lock/sharding-orchestration-distributed-lock-zookeeper-curator/src/main/resources/META-INF.services/org.apache.shardingsphere.orchestration.distributed.lock.api.DistributedLockCenter new file mode 100644 index 0000000000000000000000000000000000000000..2ac4e65473e88fc2d650c8b45f78558166172a08 --- /dev/null +++ b/sharding-orchestration/sharding-orchestration-distributed-lock/sharding-orchestration-distributed-lock-zookeeper-curator/src/main/resources/META-INF.services/org.apache.shardingsphere.orchestration.distributed.lock.api.DistributedLockCenter @@ -0,0 +1,18 @@ +# +# 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. +# + +org.apache.shardingsphere.orchestration.distributed.lock.zookeeper.curator.CuratorZookeeperDistributedLockCenter diff --git a/sharding-orchestration/sharding-orchestration-distributed-lock/sharding-orchestration-distributed-lock-zookeeper-curator/src/test/java/org/apache/shardingsphere/orchestration/distributed/lock/zookeeper/curator/test/CuratorZookeeperDistributedLockCenterTest.java b/sharding-orchestration/sharding-orchestration-distributed-lock/sharding-orchestration-distributed-lock-zookeeper-curator/src/test/java/org/apache/shardingsphere/orchestration/distributed/lock/zookeeper/curator/test/CuratorZookeeperDistributedLockCenterTest.java new file mode 100644 index 0000000000000000000000000000000000000000..749ed4caacfbdc213566aa48cacdbf03d12c1692 --- /dev/null +++ b/sharding-orchestration/sharding-orchestration-distributed-lock/sharding-orchestration-distributed-lock-zookeeper-curator/src/test/java/org/apache/shardingsphere/orchestration/distributed/lock/zookeeper/curator/test/CuratorZookeeperDistributedLockCenterTest.java @@ -0,0 +1,80 @@ +/* + * 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. + */ + +package org.apache.shardingsphere.orchestration.distributed.lock.zookeeper.curator.test; + +import org.apache.shardingsphere.orchestration.distributed.lock.api.DistributedLockCenter; +import org.apache.shardingsphere.orchestration.distributed.lock.api.DistributedLockConfiguration; +import org.apache.shardingsphere.orchestration.distributed.lock.zookeeper.curator.CuratorZookeeperDistributedLockCenter; +import org.apache.shardingsphere.orchestration.distributed.lock.zookeeper.curator.util.EmbedTestingServer; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.Properties; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +public final class CuratorZookeeperDistributedLockCenterTest { + + private static DistributedLockCenter curatorZookeeperRegistryCenter = new CuratorZookeeperDistributedLockCenter(); + + @BeforeClass + public static void init() { + EmbedTestingServer.start(); + DistributedLockConfiguration configuration = new DistributedLockConfiguration(curatorZookeeperRegistryCenter.getType(), new Properties()); + configuration.setServerLists("127.0.0.1:3181"); + curatorZookeeperRegistryCenter.init(configuration); + } + + @Test + public void assertPersist() { + curatorZookeeperRegistryCenter.persist("/test", "value1"); + assertThat(curatorZookeeperRegistryCenter.get("/test"), is("value1")); + } + + @Test + public void assertUpdate() { + curatorZookeeperRegistryCenter.persist("/test", "value2"); + assertThat(curatorZookeeperRegistryCenter.get("/test"), is("value2")); + } + + @Test + public void assertPersistEphemeral() { + curatorZookeeperRegistryCenter.persist("/test/ephemeral", "value3"); + assertThat(curatorZookeeperRegistryCenter.get("/test/ephemeral"), is("value3")); + } + + @Test + public void assertLock() { + curatorZookeeperRegistryCenter.initLock("/test/lock1"); + assertThat(curatorZookeeperRegistryCenter.tryLock(), is(true)); + } + + @Test + public void assertRelease() { + curatorZookeeperRegistryCenter.initLock("/test/lock2"); + curatorZookeeperRegistryCenter.tryLock(); + curatorZookeeperRegistryCenter.tryRelease(); + } + + @Test(expected = IllegalMonitorStateException.class) + public void assertReleaseWithoutLock() { + curatorZookeeperRegistryCenter.initLock("/test/lock3"); + curatorZookeeperRegistryCenter.tryRelease(); + } +} diff --git a/sharding-orchestration/sharding-orchestration-distributed-lock/sharding-orchestration-distributed-lock-zookeeper-curator/src/test/java/org/apache/shardingsphere/orchestration/distributed/lock/zookeeper/curator/util/EmbedTestingServer.java b/sharding-orchestration/sharding-orchestration-distributed-lock/sharding-orchestration-distributed-lock-zookeeper-curator/src/test/java/org/apache/shardingsphere/orchestration/distributed/lock/zookeeper/curator/util/EmbedTestingServer.java new file mode 100644 index 0000000000000000000000000000000000000000..50cb185988e2657a5c8d87b15416338a7ff79b56 --- /dev/null +++ b/sharding-orchestration/sharding-orchestration-distributed-lock/sharding-orchestration-distributed-lock-zookeeper-curator/src/test/java/org/apache/shardingsphere/orchestration/distributed/lock/zookeeper/curator/util/EmbedTestingServer.java @@ -0,0 +1,67 @@ +/* + * 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. + */ + +package org.apache.shardingsphere.orchestration.distributed.lock.zookeeper.curator.util; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.apache.curator.test.TestingServer; +import org.apache.zookeeper.KeeperException; + +import java.io.File; +import java.io.IOException; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class EmbedTestingServer { + + private static final int PORT = 3181; + + private static volatile TestingServer testingServer; + + /** + * Start embed zookeeper server. + */ + public static void start() { + if (null != testingServer) { + return; + } + try { + testingServer = new TestingServer(PORT, new File(String.format("target/test_zk_data/%s/", System.nanoTime()))); + // CHECKSTYLE:OFF + } catch (final Exception ex) { + // CHECKSTYLE:ON + if (!isIgnoredException(ex)) { + throw new RuntimeException(ex); + } + } finally { + Runtime.getRuntime().addShutdownHook(new Thread() { + + @Override + public void run() { + try { + testingServer.close(); + } catch (final IOException ignored) { + } + } + }); + } + } + + private static boolean isIgnoredException(final Throwable cause) { + return cause instanceof KeeperException.ConnectionLossException || cause instanceof KeeperException.NoNodeException || cause instanceof KeeperException.NodeExistsException; + } +}