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
The following commit(s) were added to refs/heads/metaclient by this push:
new f5d99b55e Implementing LockInfo Object for LockClient in MetaClient
f5d99b55e is described below
commit f5d99b55e5c5584580a837622eee631fbe59716e
Author: Marcos Rico Peng <[email protected]>
AuthorDate: Mon Apr 10 15:31:31 2023 -0400
Implementing LockInfo Object for LockClient in MetaClient
Implementing LockInfo Object for LockClient in MetaClient
---------
Co-authored-by: mapeng <[email protected]>
---
.../LockInfo.java => datamodel/DataRecord.java} | 13 +-
.../helix/metaclient/recipes/lock/LockInfo.java | 229 +++++++++++++++++++++
.../metaclient/recipes/lock/LockInfoTest.java | 70 +++++++
3 files changed, 310 insertions(+), 2 deletions(-)
diff --git
a/meta-client/src/main/java/org/apache/helix/metaclient/recipes/lock/LockInfo.java
b/meta-client/src/main/java/org/apache/helix/metaclient/datamodel/DataRecord.java
similarity index 69%
copy from
meta-client/src/main/java/org/apache/helix/metaclient/recipes/lock/LockInfo.java
copy to
meta-client/src/main/java/org/apache/helix/metaclient/datamodel/DataRecord.java
index 85006cdf1..00fe44118 100644
---
a/meta-client/src/main/java/org/apache/helix/metaclient/recipes/lock/LockInfo.java
+++
b/meta-client/src/main/java/org/apache/helix/metaclient/datamodel/DataRecord.java
@@ -1,4 +1,4 @@
-package org.apache.helix.metaclient.recipes.lock;
+package org.apache.helix.metaclient.datamodel;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -19,6 +19,15 @@ package org.apache.helix.metaclient.recipes.lock;
* under the License.
*/
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
-public class LockInfo {
+/**
+ * The DataRecord object is a wrapper around ZNRecord.
+ * TODO: Create an interface to decouple DataRecord and have a pluggable
record store.
+ */
+public class DataRecord extends ZNRecord {
+ public DataRecord(String znodeId) {
+ super(znodeId);
+ }
}
+
diff --git
a/meta-client/src/main/java/org/apache/helix/metaclient/recipes/lock/LockInfo.java
b/meta-client/src/main/java/org/apache/helix/metaclient/recipes/lock/LockInfo.java
index 85006cdf1..d579427a9 100644
---
a/meta-client/src/main/java/org/apache/helix/metaclient/recipes/lock/LockInfo.java
+++
b/meta-client/src/main/java/org/apache/helix/metaclient/recipes/lock/LockInfo.java
@@ -19,6 +19,235 @@ package org.apache.helix.metaclient.recipes.lock;
* under the License.
*/
+import java.time.Duration;
+import java.time.temporal.ChronoUnit;
+import org.apache.helix.metaclient.datamodel.DataRecord;
+
+
+/**
+ * This structure represents a Lock node information, implemented using
DataRecord
+ */
public class LockInfo {
+
+ // Default values for each attribute if there are no current values set by
user
+ public static final String DEFAULT_LOCK_ID_TEXT = "";
+ public static final String DEFAULT_OWNER_ID_TEXT = "";
+ public static final String DEFAULT_CLIENT_ID_TEXT = "";
+ public static final String DEFAULT_CLIENT_DATA = "";
+ public static final long DEFAULT_GRANTED_AT_LONG = -1L;
+ public static final long DEFAULT_LAST_RENEWED_AT_LONG = -1L;
+ public static final Duration DEFAULT_TIMEOUT_DURATION =
Duration.ofMillis(-1L);
+ private static final String ZNODE_ID = "LOCK";
+ private final DataRecord _record;
+
+ /**
+ * The keys to lock information
+ */
+ public enum LockInfoAttribute {
+ LOCK_ID,
+ OWNER_ID,
+ CLIENT_ID,
+ CLIENT_DATA,
+ GRANTED_AT,
+ LAST_RENEWED_AT,
+ TIMEOUT
+ }
+
+ /**
+ * Initialize a default LockInfo instance
+ */
+ private LockInfo() {
+ _record = new DataRecord(ZNODE_ID);
+ setLockInfoFields(DEFAULT_LOCK_ID_TEXT, DEFAULT_OWNER_ID_TEXT,
DEFAULT_CLIENT_ID_TEXT, DEFAULT_CLIENT_DATA, DEFAULT_GRANTED_AT_LONG,
+ DEFAULT_LAST_RENEWED_AT_LONG, DEFAULT_TIMEOUT_DURATION);
+ }
+
+ /**
+ * Initialize a LockInfo with a ZNRecord, set all info fields to default data
+ * @param dataRecord The dataRecord contains lock node data that used to
initialize the LockInfo
+ */
+ public LockInfo(DataRecord dataRecord) {
+ this();
+ if (dataRecord != null) {
+ String lockId =
dataRecord.getSimpleField(LockInfoAttribute.LOCK_ID.name());
+ String ownerId =
dataRecord.getSimpleField(LockInfoAttribute.OWNER_ID.name());
+ String clientId =
dataRecord.getSimpleField(LockInfoAttribute.CLIENT_ID.name());
+ String clientData =
dataRecord.getSimpleField(LockInfoAttribute.CLIENT_DATA.name());
+ long grantTime =
dataRecord.getLongField(LockInfoAttribute.GRANTED_AT.name(),
DEFAULT_GRANTED_AT_LONG);
+ long lastRenewalTime =
+ dataRecord.getLongField(LockInfoAttribute.LAST_RENEWED_AT.name(),
DEFAULT_LAST_RENEWED_AT_LONG);
+ long timeout = dataRecord.getLongField(LockInfoAttribute.TIMEOUT.name(),
DEFAULT_TIMEOUT_DURATION.toMillis());
+ Duration duration = Duration.of(timeout, ChronoUnit.MILLIS);
+ setLockInfoFields(lockId,ownerId, clientId, clientData, grantTime,
+ lastRenewalTime, duration);
+ }
+ }
+
+ /**
+ * Initialize a LockInfo with data for each field, set all null info fields
to default data
+ * @param lockId value of LOCK_ID attribute
+ * @param ownerId value of OWNER_ID attribute
+ * @param clientId value of CLIENT_ID attribute
+ * @param clientData value of CLIENT_DATA attribute
+ * @param grantTime the time the lock was granted
+ * @param lastRenewalTime the last time the lock was renewed
+ * @param timeout value of TIMEOUT attribute
+ */
+ public LockInfo(String lockId, String ownerId, String clientId,
+ String clientData, long grantTime, long lastRenewalTime,
Duration timeout) {
+ this();
+ setLockInfoFields(lockId, ownerId, clientId, clientData, grantTime,
lastRenewalTime, timeout);
+ }
+
+ /**
+ * Set each field of lock info to user provided values if the values
+ * are not null, null values are set to default values
+ * @param lockId value of LOCK_ID attribute
+ * @param ownerId value of OWNER_ID attribute
+ * @param clientId value of CLIENT_ID attribute
+ * @param clientData value of CLIENT_DATA attribute
+ * @param grantTime the time the lock was granted
+ * @param lastRenewalTime the last time the lock was renewed
+ * @param timeout value of TIMEOUT attribute
+ */
+ private void setLockInfoFields(String lockId, String ownerId, String
clientId, String clientData, long grantTime, long lastRenewalTime,
+ Duration timeout) {
+ setLockId(lockId);
+ setOwnerId(ownerId);
+ setClientId(clientId);
+ setClientData(clientData);
+ setGrantedAt(grantTime);
+ setLastRenewedAt(lastRenewalTime);
+ setTimeout(timeout);
+ }
+
+ /**
+ * Set the value for LOCK_ID attribute of the lock
+ * @param lockId Is a unique identifier representing the lock.
+ * It is created by the lockClient and a new one is created
for each time the lock is acquired.
+ */
+ public void setLockId(String lockId) {
+ _record.setSimpleField(LockInfoAttribute.LOCK_ID.name(), lockId == null ?
DEFAULT_LOCK_ID_TEXT : lockId);
+ }
+
+ /**
+ * Get the value for OWNER_ID attribute of the lock
+ * @param ownerId Represents the initiator of the lock, created by the
client.
+ * A service can have multiple ownerId's as long as acquire
and release are called
+ * by the same owner.
+ */
+ public void setOwnerId(String ownerId) {
+ _record.setSimpleField(LockInfoAttribute.OWNER_ID.name(), ownerId == null
? DEFAULT_OWNER_ID_TEXT : ownerId);
+ }
+
+ /**
+ * Get the value for CLIENT_ID attribute of the lock
+ * @param clientId Unique identifier that represents who will get the lock
(the client).
+ */
+ public void setClientId(String clientId) {
+ _record.setSimpleField(LockInfoAttribute.CLIENT_ID.name(), clientId ==
null ? DEFAULT_CLIENT_ID_TEXT : clientId);
+ }
+
+ /**
+ * Get the value for CLIENT_DATA attribute of the lock
+ * @param clientData String representing the serialized data object
+ */
+ public void setClientData(String clientData) {
+ _record.setSimpleField(LockInfoAttribute.CLIENT_DATA.name(), clientData ==
null ? DEFAULT_CLIENT_DATA : clientData);
+ }
+
+ /**
+ * Get the value for GRANTED_AT attribute of the lock
+ * @param grantTime Long representing the time at which the lock was granted
+ */
+ public void setGrantedAt(Long grantTime) {
+ _record.setLongField(LockInfoAttribute.GRANTED_AT.name(), grantTime);
+ }
+
+ /**
+ * Get the value for LAST_RENEWED_AT attribute of the lock
+ * @param lastRenewalTime Long representing the time at which the lock was
last renewed
+ */
+ public void setLastRenewedAt(Long lastRenewalTime) {
+ _record.setLongField(LockInfoAttribute.LAST_RENEWED_AT.name(),
lastRenewalTime);
+ }
+
+ /**
+ * Get the value for TIMEOUT attribute of the lock
+ * @param timeout Duration object representing the duration of a lock.
+ */
+ public void setTimeout(Duration timeout) {
+ // Always store the timeout value in milliseconds for the sake of
simplicity
+ _record.setLongField(LockInfoAttribute.TIMEOUT.name(), timeout.toMillis());
+ }
+
+ /**
+ * Get the value for OWNER_ID attribute of the lock
+ * @return the owner id of the lock, {@link #DEFAULT_OWNER_ID_TEXT} if there
is no owner id set
+ */
+ public String getOwnerId() {
+ return _record.getStringField(LockInfoAttribute.OWNER_ID.name(),
DEFAULT_OWNER_ID_TEXT);
+ }
+
+ /**
+ * Get the value for CLIENT_ID attribute of the lock
+ * @return the client id of the lock, {@link #DEFAULT_CLIENT_ID_TEXT} if
there is no client id set
+ */
+ public String getClientId() {
+ return _record.getStringField(LockInfoAttribute.CLIENT_ID.name(),
DEFAULT_CLIENT_ID_TEXT);
+ }
+
+ /**
+ * Get the value for LOCK_ID attribute of the lock
+ * @return the id of the lock, {@link #DEFAULT_LOCK_ID_TEXT} if there is no
lock id set
+ */
+ public String getLockId() {
+ return _record.getStringField(LockInfoAttribute.LOCK_ID.name(),
DEFAULT_LOCK_ID_TEXT);
+ }
+
+ /**
+ * Get value of CLIENT_DATA
+ * @return the string representing the serialized client data, {@link
#DEFAULT_CLIENT_DATA}
+ * if there is no client data set.
+ */
+ public String getClientData() {
+ return _record.getStringField(LockInfoAttribute.CLIENT_DATA.name(),
DEFAULT_CLIENT_DATA);
+ }
+
+ /**
+ * Get the time the lock was granted on
+ * @return the grant time of the lock, {@link #DEFAULT_GRANTED_AT_LONG}
+ * if there is no grant time set
+ */
+ public Long getGrantedAt() {
+ return _record.getLongField(LockInfoAttribute.GRANTED_AT.name(),
DEFAULT_GRANTED_AT_LONG);
+ }
+
+ /**
+ * Get the last time the lock was renewed
+ * @return the last renewal time of the lock, {@link
#DEFAULT_LAST_RENEWED_AT_LONG}
+ * if there is no renewal time set
+ */
+ public Long getLastRenewedAt() {
+ return _record
+ .getLongField(LockInfoAttribute.LAST_RENEWED_AT.name(),
DEFAULT_LAST_RENEWED_AT_LONG);
+ }
+
+ /**
+ * Get the value for TIMEOUT attribute of the lock
+ * @return the expiring time of the lock, {@link #DEFAULT_TIMEOUT_DURATION}
if there is no timeout set
+ */
+ public Duration getTimeout() {
+ long timeout = _record.getLongField(LockInfoAttribute.TIMEOUT.name(),
DEFAULT_TIMEOUT_DURATION.toMillis());
+ return Duration.of(timeout, ChronoUnit.MILLIS);
+ }
+
+ /**
+ * Get the underlying DataRecord in a LockInfo
+ * @return lock information contained in a DataRecord
+ */
+ public DataRecord getRecord() {
+ return _record;
+ }
}
diff --git
a/meta-client/src/test/java/org/apache/helix/metaclient/recipes/lock/LockInfoTest.java
b/meta-client/src/test/java/org/apache/helix/metaclient/recipes/lock/LockInfoTest.java
new file mode 100644
index 000000000..c7f132174
--- /dev/null
+++
b/meta-client/src/test/java/org/apache/helix/metaclient/recipes/lock/LockInfoTest.java
@@ -0,0 +1,70 @@
+package org.apache.helix.metaclient.recipes.lock;
+
+/*
+ * 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.time.Duration;
+
+import org.apache.helix.metaclient.datamodel.DataRecord;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class LockInfoTest {
+ private static final String OWNER_ID = "urn:li:principal:UNKNOWN";
+ private static final String CLIENT_ID = "test_client_id";
+ private static final String CLIENT_DATA = "client_data";
+ private static final String LOCK_ID = "794c8a4c-c14b-4c23-b83f-4e1147fc6978";
+ private static final long GRANT_TIME = System.currentTimeMillis();
+ private static final long LAST_RENEWAL_TIME = System.currentTimeMillis();
+ private static final Duration TIMEOUT = Duration.ofMillis(100000);
+
+ public static final String DEFAULT_LOCK_ID_TEXT = "";
+ public static final String DEFAULT_OWNER_ID_TEXT = "";
+ public static final String DEFAULT_CLIENT_ID_TEXT = "";
+ public static final String DEFAULT_CLIENT_DATA = "";
+ public static final long DEFAULT_GRANTED_AT_LONG = -1L;
+ public static final long DEFAULT_LAST_RENEWED_AT_LONG = -1L;
+ public static final Duration DEFAULT_TIMEOUT_DURATION =
Duration.ofMillis(-1L);
+
+ @Test
+ public void testLockInfo() {
+ LockInfo lockInfo =
+ new LockInfo(LOCK_ID, OWNER_ID, CLIENT_ID, CLIENT_DATA, GRANT_TIME,
+ LAST_RENEWAL_TIME, TIMEOUT);
+
+ Assert.assertEquals(LOCK_ID, lockInfo.getLockId());
+ Assert.assertEquals(OWNER_ID, lockInfo.getOwnerId());
+ Assert.assertEquals(CLIENT_ID, lockInfo.getClientId());
+ Assert.assertEquals(CLIENT_DATA, lockInfo.getClientData());
+ Assert.assertEquals(GRANT_TIME, (long) lockInfo.getGrantedAt());
+ Assert.assertEquals(LAST_RENEWAL_TIME, (long) lockInfo.getLastRenewedAt());
+ Assert.assertEquals(TIMEOUT, lockInfo.getTimeout());
+
+ DataRecord dataRecord = new DataRecord("dataRecord");
+ LockInfo lockInfo1 = new LockInfo(dataRecord);
+ Assert.assertEquals(DEFAULT_LOCK_ID_TEXT, lockInfo1.getLockId());
+ Assert.assertEquals(DEFAULT_OWNER_ID_TEXT, lockInfo1.getOwnerId());
+ Assert.assertEquals(DEFAULT_CLIENT_ID_TEXT, lockInfo1.getClientId());
+ Assert.assertEquals(DEFAULT_CLIENT_DATA, lockInfo1.getClientData());
+ Assert.assertEquals(DEFAULT_GRANTED_AT_LONG, (long)
lockInfo1.getGrantedAt());
+ Assert.assertEquals(DEFAULT_LAST_RENEWED_AT_LONG, (long)
lockInfo1.getLastRenewedAt());
+ Assert.assertEquals(DEFAULT_TIMEOUT_DURATION, lockInfo1.getTimeout());
+ }
+}