diff --git a/hazelcast-spring/src/main/java/com/hazelcast/spring/HazelcastConfigBeanDefinitionParser.java b/hazelcast-spring/src/main/java/com/hazelcast/spring/HazelcastConfigBeanDefinitionParser.java
index d1ba154512a9..241056fadee5 100644
--- a/hazelcast-spring/src/main/java/com/hazelcast/spring/HazelcastConfigBeanDefinitionParser.java
+++ b/hazelcast-spring/src/main/java/com/hazelcast/spring/HazelcastConfigBeanDefinitionParser.java
@@ -41,6 +41,7 @@
import com.hazelcast.config.JoinConfig;
import com.hazelcast.config.ListConfig;
import com.hazelcast.config.ListenerConfig;
+import com.hazelcast.config.LockConfig;
import com.hazelcast.config.LoginModuleConfig;
import com.hazelcast.config.ManagementCenterConfig;
import com.hazelcast.config.MapAttributeConfig;
@@ -150,6 +151,7 @@ private class SpringXmlConfigBuilder extends SpringXmlBuilderHelper {
private ManagedMap mapConfigManagedMap;
private ManagedMap cacheConfigManagedMap;
private ManagedMap queueManagedMap;
+ private ManagedMap lockManagedMap;
private ManagedMap ringbufferManagedMap;
private ManagedMap reliableTopicManagedMap;
private ManagedMap semaphoreManagedMap;
@@ -170,6 +172,7 @@ public SpringXmlConfigBuilder(ParserContext parserContext) {
this.mapConfigManagedMap = createManagedMap("mapConfigs");
this.cacheConfigManagedMap = createManagedMap("cacheConfigs");
this.queueManagedMap = createManagedMap("queueConfigs");
+ this.lockManagedMap = createManagedMap("lockConfigs");
this.ringbufferManagedMap = createManagedMap("ringbufferConfigs");
this.reliableTopicManagedMap = createManagedMap("reliableTopicConfigs");
this.semaphoreManagedMap = createManagedMap("semaphoreConfigs");
@@ -212,6 +215,8 @@ public void handleConfig(final Element element) {
handleDurableExecutor(node);
} else if ("queue".equals(nodeName)) {
handleQueue(node);
+ } else if ("lock".equals(nodeName)) {
+ handleLock(node);
} else if ("ringbuffer".equals(nodeName)) {
handleRingbuffer(node);
} else if ("reliable-topic".equals(nodeName)) {
@@ -586,6 +591,18 @@ public void handleSemaphore(Node node) {
semaphoreManagedMap.put(getAttribute(node, "name"), builder.getBeanDefinition());
}
+ public void handleLock(Node node) {
+ final BeanDefinitionBuilder lockConfigBuilder = createBeanBuilder(LockConfig.class);
+ fillAttributeValues(node, lockConfigBuilder);
+ for (Node childNode : childElements(node)) {
+ final String nodeName = cleanNodeName(childNode);
+ if ("quorum-ref".equals(nodeName)) {
+ lockConfigBuilder.addPropertyValue("quorumName", getTextContent(childNode));
+ }
+ }
+ lockManagedMap.put(getAttribute(node, "name"), lockConfigBuilder.getBeanDefinition());
+ }
+
public void handleRingbuffer(Node node) {
final BeanDefinitionBuilder ringbufferConfigBuilder = createBeanBuilder(RingbufferConfig.class);
fillAttributeValues(node, ringbufferConfigBuilder);
diff --git a/hazelcast-spring/src/main/resources/hazelcast-spring-3.8.xsd b/hazelcast-spring/src/main/resources/hazelcast-spring-3.8.xsd
index b09a61ea8a0c..b369c6a4eccd 100644
--- a/hazelcast-spring/src/main/resources/hazelcast-spring-3.8.xsd
+++ b/hazelcast-spring/src/main/resources/hazelcast-spring-3.8.xsd
@@ -162,6 +162,14 @@
+
+
+
+
+
+
+
+
diff --git a/hazelcast-spring/src/test/java/com/hazelcast/spring/TestFullApplicationContext.java b/hazelcast-spring/src/test/java/com/hazelcast/spring/TestFullApplicationContext.java
index 6d9309d65940..13a362e6808c 100644
--- a/hazelcast-spring/src/test/java/com/hazelcast/spring/TestFullApplicationContext.java
+++ b/hazelcast-spring/src/test/java/com/hazelcast/spring/TestFullApplicationContext.java
@@ -33,6 +33,7 @@
import com.hazelcast.config.ItemListenerConfig;
import com.hazelcast.config.ListConfig;
import com.hazelcast.config.ListenerConfig;
+import com.hazelcast.config.LockConfig;
import com.hazelcast.config.ManagementCenterConfig;
import com.hazelcast.config.MapAttributeConfig;
import com.hazelcast.config.MapConfig;
@@ -389,7 +390,7 @@ public void testMapConfig() {
@Test
public void testQueueConfig() {
- QueueConfig testQConfig = config.getQueueConfig("testQ");
+ final QueueConfig testQConfig = config.getQueueConfig("testQ");
assertNotNull(testQConfig);
assertEquals("testQ", testQConfig.getName());
assertEquals(1000, testQConfig.getMaxSize());
@@ -398,12 +399,14 @@ public void testQueueConfig() {
ItemListenerConfig listenerConfig = testQConfig.getItemListenerConfigs().get(0);
assertEquals("com.hazelcast.spring.DummyItemListener", listenerConfig.getClassName());
assertTrue(listenerConfig.isIncludeValue());
- QueueConfig qConfig = config.getQueueConfig("q");
+
+ final QueueConfig qConfig = config.getQueueConfig("q");
assertNotNull(qConfig);
assertEquals("q", qConfig.getName());
assertEquals(2500, qConfig.getMaxSize());
assertFalse(qConfig.isStatisticsEnabled());
assertEquals(100, qConfig.getEmptyQueueTtl());
+ assertEquals("my-quorum", qConfig.getQuorumName());
final QueueConfig queueWithStore1 = config.getQueueConfig("queueWithStore1");
assertNotNull(queueWithStore1);
@@ -430,6 +433,14 @@ public void testQueueConfig() {
assertEquals(dummyQueueStoreFactory, storeConfig4.getFactoryImplementation());
}
+ @Test
+ public void testLockConfig() {
+ final LockConfig lockConfig = config.getLockConfig("lock");
+ assertNotNull(lockConfig);
+ assertEquals("lock", lockConfig.getName());
+ assertEquals("my-quorum", lockConfig.getQuorumName());
+ }
+
@Test
public void testRingbufferConfig() {
final RingbufferConfig testRingbuffer = config.getRingbufferConfig("testRingbuffer");
diff --git a/hazelcast-spring/src/test/resources/com/hazelcast/spring/fullConfig-applicationContext-hazelcast.xml b/hazelcast-spring/src/test/resources/com/hazelcast/spring/fullConfig-applicationContext-hazelcast.xml
index a924852d6ac6..af9c6a9c82f8 100644
--- a/hazelcast-spring/src/test/resources/com/hazelcast/spring/fullConfig-applicationContext-hazelcast.xml
+++ b/hazelcast-spring/src/test/resources/com/hazelcast/spring/fullConfig-applicationContext-hazelcast.xml
@@ -152,10 +152,7 @@
queue-capacity="300"
statistics-enabled="false"
/>
-
-
+
@@ -165,7 +162,9 @@
backup-count="1"
async-backup-count="1"
statistics-enabled="false"
- empty-queue-ttl="100"/>
+ empty-queue-ttl="100">
+ my-quorum
+
@@ -180,6 +179,10 @@
+
+ my-quorum
+
+
> constructors
= new ConcurrentHashMap>();
-
+ private final ConcurrentMap quorumConfigCache = new ConcurrentHashMap();
+ private final ContextMutexFactory quorumConfigCacheMutexFactory = new ContextMutexFactory();
private final long maxLeaseTimeInMillis;
public LockServiceImpl(NodeEngine nodeEngine) {
@@ -310,4 +315,17 @@ public void clientDisconnected(String clientUuid) {
public static long getMaxLeaseTimeInMillis(HazelcastProperties hazelcastProperties) {
return hazelcastProperties.getMillis(GroupProperty.LOCK_MAX_LEASE_TIME_SECONDS);
}
+
+ @Override
+ public String getQuorumName(final String name) {
+ // we use caching here because lock operations are often and we should avoid lock config lookup
+ return getOrPutSynchronized(quorumConfigCache, name, quorumConfigCacheMutexFactory,
+ new ConstructorFunction() {
+ @Override
+ public String createNew(String arg) {
+ final LockConfig lockConfig = nodeEngine.getConfig().findLockConfig(name);
+ return lockConfig.getQuorumName();
+ }
+ });
+ }
}
diff --git a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/AbstractLockOperation.java b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/AbstractLockOperation.java
index 06351989ac7b..afca45d63fed 100644
--- a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/AbstractLockOperation.java
+++ b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/AbstractLockOperation.java
@@ -23,6 +23,7 @@
import com.hazelcast.nio.ObjectDataOutput;
import com.hazelcast.nio.serialization.Data;
import com.hazelcast.nio.serialization.IdentifiedDataSerializable;
+import com.hazelcast.spi.NamedOperation;
import com.hazelcast.spi.ObjectNamespace;
import com.hazelcast.spi.Operation;
import com.hazelcast.spi.PartitionAwareOperation;
@@ -31,7 +32,7 @@
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
public abstract class AbstractLockOperation extends Operation
- implements PartitionAwareOperation, IdentifiedDataSerializable {
+ implements PartitionAwareOperation, IdentifiedDataSerializable, NamedOperation {
public static final int ANY_THREAD = 0;
@@ -123,6 +124,11 @@ public final Data getKey() {
return key;
}
+ @Override
+ public String getName() {
+ return namespace.getObjectName();
+ }
+
@Override
public final int getFactoryId() {
return LockDataSerializerHook.F_ID;
diff --git a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/AwaitBackupOperation.java b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/AwaitBackupOperation.java
index 48cc17f40738..141cddb773a8 100644
--- a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/AwaitBackupOperation.java
+++ b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/AwaitBackupOperation.java
@@ -24,11 +24,12 @@
import com.hazelcast.nio.serialization.Data;
import com.hazelcast.spi.BackupOperation;
import com.hazelcast.spi.ObjectNamespace;
+import com.hazelcast.spi.impl.MutatingOperation;
import java.io.IOException;
public class AwaitBackupOperation extends AbstractLockOperation
- implements BackupOperation {
+ implements BackupOperation, MutatingOperation {
private String originalCaller;
private String conditionId;
diff --git a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/AwaitOperation.java b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/AwaitOperation.java
index ac801c65367e..d7a177857df8 100644
--- a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/AwaitOperation.java
+++ b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/AwaitOperation.java
@@ -26,11 +26,12 @@
import com.hazelcast.spi.BlockingOperation;
import com.hazelcast.spi.ObjectNamespace;
import com.hazelcast.spi.Operation;
+import com.hazelcast.spi.impl.MutatingOperation;
import java.io.IOException;
public class AwaitOperation extends AbstractLockOperation
- implements BlockingOperation, BackupAwareOperation {
+ implements BlockingOperation, BackupAwareOperation, MutatingOperation {
private String conditionId;
private boolean expired;
diff --git a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/BeforeAwaitBackupOperation.java b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/BeforeAwaitBackupOperation.java
index 505bf94b5ad5..3c5ebb100b88 100644
--- a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/BeforeAwaitBackupOperation.java
+++ b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/BeforeAwaitBackupOperation.java
@@ -23,10 +23,11 @@
import com.hazelcast.nio.serialization.Data;
import com.hazelcast.spi.BackupOperation;
import com.hazelcast.spi.ObjectNamespace;
+import com.hazelcast.spi.impl.MutatingOperation;
import java.io.IOException;
-public class BeforeAwaitBackupOperation extends AbstractLockOperation implements BackupOperation {
+public class BeforeAwaitBackupOperation extends AbstractLockOperation implements BackupOperation, MutatingOperation {
private String conditionId;
private String originalCaller;
diff --git a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/BeforeAwaitOperation.java b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/BeforeAwaitOperation.java
index 7547fcd1bd12..9771b11327d6 100644
--- a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/BeforeAwaitOperation.java
+++ b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/BeforeAwaitOperation.java
@@ -26,10 +26,11 @@
import com.hazelcast.spi.ObjectNamespace;
import com.hazelcast.spi.Operation;
import com.hazelcast.spi.WaitNotifyKey;
+import com.hazelcast.spi.impl.MutatingOperation;
import java.io.IOException;
-public class BeforeAwaitOperation extends AbstractLockOperation implements Notifier, BackupAwareOperation {
+public class BeforeAwaitOperation extends AbstractLockOperation implements Notifier, BackupAwareOperation, MutatingOperation {
private String conditionId;
diff --git a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/GetLockCountOperation.java b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/GetLockCountOperation.java
index 740a0b1df972..ab2e5d982802 100644
--- a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/GetLockCountOperation.java
+++ b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/GetLockCountOperation.java
@@ -20,8 +20,9 @@
import com.hazelcast.concurrent.lock.LockStoreImpl;
import com.hazelcast.nio.serialization.Data;
import com.hazelcast.spi.ObjectNamespace;
+import com.hazelcast.spi.ReadonlyOperation;
-public class GetLockCountOperation extends AbstractLockOperation {
+public class GetLockCountOperation extends AbstractLockOperation implements ReadonlyOperation {
public GetLockCountOperation() {
}
diff --git a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/GetRemainingLeaseTimeOperation.java b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/GetRemainingLeaseTimeOperation.java
index c3b857e227ab..787035483a9e 100644
--- a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/GetRemainingLeaseTimeOperation.java
+++ b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/GetRemainingLeaseTimeOperation.java
@@ -20,8 +20,9 @@
import com.hazelcast.concurrent.lock.LockStoreImpl;
import com.hazelcast.nio.serialization.Data;
import com.hazelcast.spi.ObjectNamespace;
+import com.hazelcast.spi.ReadonlyOperation;
-public class GetRemainingLeaseTimeOperation extends AbstractLockOperation {
+public class GetRemainingLeaseTimeOperation extends AbstractLockOperation implements ReadonlyOperation {
public GetRemainingLeaseTimeOperation() {
}
diff --git a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/IsLockedOperation.java b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/IsLockedOperation.java
index a198bea4574f..ffd8879d1f51 100644
--- a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/IsLockedOperation.java
+++ b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/IsLockedOperation.java
@@ -20,8 +20,9 @@
import com.hazelcast.concurrent.lock.LockStoreImpl;
import com.hazelcast.nio.serialization.Data;
import com.hazelcast.spi.ObjectNamespace;
+import com.hazelcast.spi.ReadonlyOperation;
-public class IsLockedOperation extends AbstractLockOperation {
+public class IsLockedOperation extends AbstractLockOperation implements ReadonlyOperation {
public IsLockedOperation() {
}
diff --git a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/LockBackupOperation.java b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/LockBackupOperation.java
index 47b47d2d143e..f5ac0d200aee 100644
--- a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/LockBackupOperation.java
+++ b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/LockBackupOperation.java
@@ -23,10 +23,11 @@
import com.hazelcast.nio.serialization.Data;
import com.hazelcast.spi.BackupOperation;
import com.hazelcast.spi.ObjectNamespace;
+import com.hazelcast.spi.impl.MutatingOperation;
import java.io.IOException;
-public class LockBackupOperation extends AbstractLockOperation implements BackupOperation {
+public class LockBackupOperation extends AbstractLockOperation implements BackupOperation, MutatingOperation {
private String originalCallerUuid;
diff --git a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/LockOperation.java b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/LockOperation.java
index 2f3aefd66bdd..ad815616a3aa 100644
--- a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/LockOperation.java
+++ b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/LockOperation.java
@@ -26,8 +26,9 @@
import com.hazelcast.spi.ObjectNamespace;
import com.hazelcast.spi.Operation;
import com.hazelcast.spi.WaitNotifyKey;
+import com.hazelcast.spi.impl.MutatingOperation;
-public class LockOperation extends AbstractLockOperation implements BlockingOperation, BackupAwareOperation {
+public class LockOperation extends AbstractLockOperation implements BlockingOperation, BackupAwareOperation, MutatingOperation {
public LockOperation() {
}
diff --git a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/SignalBackupOperation.java b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/SignalBackupOperation.java
index 46453f2bece1..04e3265d4ae6 100644
--- a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/SignalBackupOperation.java
+++ b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/SignalBackupOperation.java
@@ -20,8 +20,9 @@
import com.hazelcast.nio.serialization.Data;
import com.hazelcast.spi.BackupOperation;
import com.hazelcast.spi.ObjectNamespace;
+import com.hazelcast.spi.impl.MutatingOperation;
-public class SignalBackupOperation extends BaseSignalOperation implements BackupOperation {
+public class SignalBackupOperation extends BaseSignalOperation implements BackupOperation, MutatingOperation {
public SignalBackupOperation() {
}
diff --git a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/SignalOperation.java b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/SignalOperation.java
index 785580c23255..12ebe4d5eb76 100644
--- a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/SignalOperation.java
+++ b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/SignalOperation.java
@@ -22,8 +22,9 @@
import com.hazelcast.spi.BackupAwareOperation;
import com.hazelcast.spi.ObjectNamespace;
import com.hazelcast.spi.Operation;
+import com.hazelcast.spi.impl.MutatingOperation;
-public class SignalOperation extends BaseSignalOperation implements BackupAwareOperation {
+public class SignalOperation extends BaseSignalOperation implements BackupAwareOperation, MutatingOperation {
public SignalOperation() {
}
diff --git a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/UnlockBackupOperation.java b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/UnlockBackupOperation.java
index fa65be7263f8..8efff143ae9e 100644
--- a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/UnlockBackupOperation.java
+++ b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/UnlockBackupOperation.java
@@ -23,10 +23,11 @@
import com.hazelcast.nio.serialization.Data;
import com.hazelcast.spi.BackupOperation;
import com.hazelcast.spi.ObjectNamespace;
+import com.hazelcast.spi.impl.MutatingOperation;
import java.io.IOException;
-public class UnlockBackupOperation extends AbstractLockOperation implements BackupOperation {
+public class UnlockBackupOperation extends AbstractLockOperation implements BackupOperation, MutatingOperation {
private boolean force;
private String originalCallerUuid;
diff --git a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/UnlockOperation.java b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/UnlockOperation.java
index d2b739457f91..c11c4d8fc921 100644
--- a/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/UnlockOperation.java
+++ b/hazelcast/src/main/java/com/hazelcast/concurrent/lock/operations/UnlockOperation.java
@@ -26,12 +26,13 @@
import com.hazelcast.spi.ObjectNamespace;
import com.hazelcast.spi.Operation;
import com.hazelcast.spi.WaitNotifyKey;
+import com.hazelcast.spi.impl.MutatingOperation;
import java.io.IOException;
import static java.lang.Boolean.TRUE;
-public class UnlockOperation extends AbstractLockOperation implements Notifier, BackupAwareOperation {
+public class UnlockOperation extends AbstractLockOperation implements Notifier, BackupAwareOperation, MutatingOperation {
private boolean force;
private boolean shouldNotify;
diff --git a/hazelcast/src/main/java/com/hazelcast/config/Config.java b/hazelcast/src/main/java/com/hazelcast/config/Config.java
index 552cf11c5ca3..8de564459e39 100644
--- a/hazelcast/src/main/java/com/hazelcast/config/Config.java
+++ b/hazelcast/src/main/java/com/hazelcast/config/Config.java
@@ -78,6 +78,8 @@ public class Config {
private final Map queueConfigs = new ConcurrentHashMap();
+ private final Map lockConfigs = new ConcurrentHashMap();
+
private final Map multiMapConfigs = new ConcurrentHashMap();
private final Map listConfigs = new ConcurrentHashMap();
@@ -386,6 +388,51 @@ public Config setQueueConfigs(Map queueConfigs) {
return this;
}
+ public LockConfig findLockConfig(String name) {
+ final String baseName = getBaseName(name);
+ final LockConfig config = lookupByPattern(lockConfigs, baseName);
+ if (config != null) {
+ return config.getAsReadOnly();
+ }
+ return getLockConfig("default").getAsReadOnly();
+ }
+
+ public LockConfig getLockConfig(String name) {
+ final String baseName = getBaseName(name);
+ LockConfig config = lookupByPattern(lockConfigs, baseName);
+ if (config != null) {
+ return config;
+ }
+ LockConfig defConfig = lockConfigs.get("default");
+ if (defConfig == null) {
+ defConfig = new LockConfig();
+ defConfig.setName("default");
+ addLockConfig(defConfig);
+ }
+ config = new LockConfig(defConfig);
+ config.setName(name);
+ addLockConfig(config);
+ return config;
+ }
+
+ public Config addLockConfig(LockConfig lockConfig) {
+ lockConfigs.put(lockConfig.getName(), lockConfig);
+ return this;
+ }
+
+ public Map getLockConfigs() {
+ return lockConfigs;
+ }
+
+ public Config setLockConfigs(Map lockConfigs) {
+ this.lockConfigs.clear();
+ this.lockConfigs.putAll(lockConfigs);
+ for (Entry entry : lockConfigs.entrySet()) {
+ entry.getValue().setName(entry.getKey());
+ }
+ return this;
+ }
+
public ListConfig findListConfig(String name) {
String baseName = getBaseName(name);
ListConfig config = lookupByPattern(listConfigs, baseName);
diff --git a/hazelcast/src/main/java/com/hazelcast/config/ConfigXmlGenerator.java b/hazelcast/src/main/java/com/hazelcast/config/ConfigXmlGenerator.java
index e43a439266b5..71b7442aef83 100644
--- a/hazelcast/src/main/java/com/hazelcast/config/ConfigXmlGenerator.java
+++ b/hazelcast/src/main/java/com/hazelcast/config/ConfigXmlGenerator.java
@@ -116,6 +116,8 @@ public String generate(Config config) {
semaphoreXmlGenerator(xml, config);
+ lockXmlGenerator(xml, config);
+
ringbufferXmlGenerator(xml, config);
executorXmlGenerator(xml, config);
@@ -298,9 +300,11 @@ private void queueXmlGenerator(StringBuilder xml, Config config) {
final Collection qCfgs = config.getQueueConfigs().values();
for (QueueConfig q : qCfgs) {
xml.append("");
+ xml.append("").append(q.isStatisticsEnabled()).append("");
xml.append("").append(q.getMaxSize()).append("");
xml.append("").append(q.getBackupCount()).append("");
xml.append("").append(q.getAsyncBackupCount()).append("");
+ xml.append("").append(q.getEmptyQueueTtl()).append("");
if (!q.getItemListenerConfigs().isEmpty()) {
xml.append("");
for (ItemListenerConfig lc : q.getItemListenerConfigs()) {
@@ -310,19 +314,57 @@ private void queueXmlGenerator(StringBuilder xml, Config config) {
}
xml.append("");
}
+ final QueueStoreConfig storeConfig = q.getQueueStoreConfig();
+ if (storeConfig != null) {
+ xml.append("");
+ if (storeConfig.getClassName() != null) {
+ xml.append("").append(storeConfig.getClassName()).append("");
+ }
+ if (storeConfig.getFactoryClassName() != null) {
+ xml.append("").append(storeConfig.getFactoryClassName()).append("");
+ }
+ appendProperties(xml, storeConfig.getProperties());
+ xml.append("");
+ }
+ if (q.getQuorumName() != null) {
+ xml.append("").append(q.getQuorumName()).append("");
+ }
xml.append("");
}
}
+ private void lockXmlGenerator(StringBuilder xml, Config config) {
+ final Collection configs = config.getLockConfigs().values();
+ for (LockConfig c : configs) {
+ xml.append("");
+ if (c.getQuorumName() != null) {
+ xml.append("").append(c.getQuorumName()).append("");
+ }
+ xml.append("");
+ }
+ }
+
private void ringbufferXmlGenerator(StringBuilder xml, Config config) {
final Collection configs = config.getRingbufferConfigs().values();
for (RingbufferConfig rbConfig : configs) {
xml.append("");
xml.append("").append(rbConfig.getCapacity()).append("");
+ xml.append("").append(rbConfig.getTimeToLiveSeconds()).append("");
xml.append("").append(rbConfig.getBackupCount()).append("");
xml.append("").append(rbConfig.getAsyncBackupCount()).append("");
- xml.append("").append(rbConfig.getTimeToLiveSeconds()).append("");
xml.append("").append(rbConfig.getInMemoryFormat().toString()).append("");
+ final RingbufferStoreConfig storeConfig = rbConfig.getRingbufferStoreConfig();
+ if (storeConfig != null) {
+ xml.append("");
+ if (storeConfig.getClassName() != null) {
+ xml.append("").append(storeConfig.getClassName()).append("");
+ }
+ if (storeConfig.getFactoryClassName() != null) {
+ xml.append("").append(storeConfig.getFactoryClassName()).append("");
+ }
+ appendProperties(xml, storeConfig.getProperties());
+ xml.append("");
+ }
xml.append("");
}
}
diff --git a/hazelcast/src/main/java/com/hazelcast/config/LockConfig.java b/hazelcast/src/main/java/com/hazelcast/config/LockConfig.java
new file mode 100644
index 000000000000..2f9617bb2d17
--- /dev/null
+++ b/hazelcast/src/main/java/com/hazelcast/config/LockConfig.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2008-2016, Hazelcast, Inc. All Rights Reserved.
+ *
+ * Licensed 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 com.hazelcast.config;
+
+import static com.hazelcast.util.Preconditions.checkHasText;
+import static com.hazelcast.util.Preconditions.checkNotNull;
+
+/**
+ * Contains the configuration for the {@link com.hazelcast.core.ILock}.
+ */
+public class LockConfig {
+
+
+ private String name;
+ private String quorumName;
+
+ public LockConfig() {
+ }
+
+ /**
+ * Creates a {@link LockConfig} with the provided name.
+ *
+ * @param name the name
+ * @throws NullPointerException if name is null
+ */
+ public LockConfig(String name) {
+ this.name = checkNotNull(name, "name can't be null");
+ }
+
+ /**
+ * Clones a {@link LockConfig}
+ *
+ * @param config the lock config to clone
+ * @throws NullPointerException if config is null
+ */
+ public LockConfig(LockConfig config) {
+ checkNotNull(config, "config can't be null");
+ this.name = config.name;
+ this.quorumName = config.quorumName;
+ }
+
+ /**
+ * Creates a new {@link LockConfig} by cloning an existing config and overriding the name.
+ *
+ * @param name the new name
+ * @param config the config.
+ * @throws NullPointerException if name or config is null.
+ */
+ public LockConfig(String name, LockConfig config) {
+ this(config);
+ this.name = checkNotNull(name, "name can't be null");
+ }
+
+ /**
+ * Sets the name of the lock.
+ *
+ * @param name the name of the lock
+ * @return the updated {@link LockConfig}
+ * @throws IllegalArgumentException if name is null or an empty string.
+ */
+ public LockConfig setName(String name) {
+ this.name = checkHasText(name, "name must contain text");
+ return this;
+ }
+
+ /**
+ * Returns the name of the lock.
+ *
+ * @return the name of the lock.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the quorum name for lock operations.
+ *
+ * @return the quorum name
+ */
+ public String getQuorumName() {
+ return quorumName;
+ }
+
+ /**
+ * Sets the quorum name for lock operations.
+ *
+ * @param quorumName the quorum name
+ * @return the updated lock configuration
+ */
+ public LockConfig setQuorumName(String quorumName) {
+ this.quorumName = quorumName;
+ return this;
+ }
+
+ /**
+ * Creates a readonly copy of this {@link LockConfig}.
+ *
+ * @return the readonly copy.
+ */
+ public LockConfig getAsReadOnly() {
+ return new LockConfigReadonly(this);
+ }
+
+
+ @Override
+ public String toString() {
+ return "LockConfig{"
+ + "name='" + name + '\''
+ + ", quorumName='" + quorumName + '\''
+ + '}';
+ }
+
+ /**
+ * A readonly version of the {@link LockConfig}.
+ */
+ private static class LockConfigReadonly extends LockConfig {
+
+ LockConfigReadonly(LockConfig config) {
+ super(config);
+ }
+
+ @Override
+ public LockConfig setName(String name) {
+ throw new UnsupportedOperationException("This config is read-only");
+ }
+
+
+ }
+}
diff --git a/hazelcast/src/main/java/com/hazelcast/config/XmlConfigBuilder.java b/hazelcast/src/main/java/com/hazelcast/config/XmlConfigBuilder.java
index e978e6ca6a05..b85d64437088 100644
--- a/hazelcast/src/main/java/com/hazelcast/config/XmlConfigBuilder.java
+++ b/hazelcast/src/main/java/com/hazelcast/config/XmlConfigBuilder.java
@@ -69,6 +69,7 @@
import static com.hazelcast.config.XmlElements.LIST;
import static com.hazelcast.config.XmlElements.LISTENERS;
import static com.hazelcast.config.XmlElements.LITE_MEMBER;
+import static com.hazelcast.config.XmlElements.LOCK;
import static com.hazelcast.config.XmlElements.MANAGEMENT_CENTER;
import static com.hazelcast.config.XmlElements.MAP;
import static com.hazelcast.config.XmlElements.MEMBER_ATTRIBUTES;
@@ -314,6 +315,8 @@ private boolean handleXmlNode(Node node, String nodeName) throws Exception {
handleJobTracker(node);
} else if (SEMAPHORE.isEqual(nodeName)) {
handleSemaphore(node);
+ } else if (LOCK.isEqual(nodeName)) {
+ handleLock(node);
} else if (RINGBUFFER.isEqual(nodeName)) {
handleRingbuffer(node);
} else if (LISTENERS.isEqual(nodeName)) {
@@ -877,6 +880,20 @@ private void handleOutboundPorts(Node child) {
}
}
+ private void handleLock(Node node) {
+ final String name = getAttribute(node, "name");
+ final LockConfig lockConfig = new LockConfig();
+ lockConfig.setName(name);
+ for (Node n : childElements(node)) {
+ final String nodeName = cleanNodeName(n);
+ final String value = getTextContent(n).trim();
+ if ("quorum-ref".equals(nodeName)) {
+ lockConfig.setQuorumName(value);
+ }
+ }
+ this.config.addLockConfig(lockConfig);
+ }
+
private void handleQueue(Node node) {
Node attName = node.getAttributes().getNamedItem("name");
String name = getTextContent(attName);
diff --git a/hazelcast/src/main/java/com/hazelcast/config/XmlElements.java b/hazelcast/src/main/java/com/hazelcast/config/XmlElements.java
index 6382b660cd1f..c07aebcb88b8 100644
--- a/hazelcast/src/main/java/com/hazelcast/config/XmlElements.java
+++ b/hazelcast/src/main/java/com/hazelcast/config/XmlElements.java
@@ -39,6 +39,7 @@ enum XmlElements {
RELIABLE_TOPIC("reliable-topic", true),
JOB_TRACKER("jobtracker", true),
SEMAPHORE("semaphore", true),
+ LOCK("lock", true),
RINGBUFFER("ringbuffer", true),
LISTENERS("listeners", false),
SERIALIZATION("serialization", false),
diff --git a/hazelcast/src/main/resources/hazelcast-config-3.8.xsd b/hazelcast/src/main/resources/hazelcast-config-3.8.xsd
index cf9346d3439c..60ecacd81623 100644
--- a/hazelcast/src/main/resources/hazelcast-config-3.8.xsd
+++ b/hazelcast/src/main/resources/hazelcast-config-3.8.xsd
@@ -52,6 +52,7 @@
+
@@ -1172,6 +1173,23 @@
+
+
+
+
+
+
+
+
+ Name of the lock.
+
+
+
+
+
+
+
+
diff --git a/hazelcast/src/main/resources/hazelcast-full-example.xml b/hazelcast/src/main/resources/hazelcast-full-example.xml
index 116f7ca0a52f..37ccdfa51d56 100644
--- a/hazelcast/src/main/resources/hazelcast-full-example.xml
+++ b/hazelcast/src/main/resources/hazelcast-full-example.xml
@@ -486,7 +486,10 @@ https://hazelcast.org/documentation/.
- bulk-load:
Size of the bulks loaded from QueueStore when the queue is initialized. Its default
value is 250.
--->
+ * :
+ Adds the quorum for this queue which you configure using the element. You should set the 's value
+ as the 's name.
+-->
true
0
@@ -494,18 +497,19 @@ https://hazelcast.org/documentation/.
0
-1
-
- com.hazelcast.examples.ItemListener
-
+
+ com.hazelcast.examples.ItemListener
+
- com.hazelcast.QueueStoreImpl
-
- false
- 1000
- 500
-
-
+ com.hazelcast.QueueStoreImpl
+
+ false
+ 1000
+ 500
+
+
+ quorumRuleWithThreeNodes
+
+
+ quorumRuleWithThreeNodes
+
+
-
@@ -175,6 +175,7 @@
com.hazelcast.examples.ItemListener
+ quorumRuleWithThreeMembers