/* * Copyright (c) 2008-2017, 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.partition; import com.hazelcast.collection.impl.list.ListService; import com.hazelcast.collection.impl.queue.QueueService; import com.hazelcast.collection.impl.set.SetService; import com.hazelcast.concurrent.atomiclong.AtomicLongService; import com.hazelcast.concurrent.countdownlatch.CountDownLatchService; import com.hazelcast.concurrent.lock.InternalLockNamespace; import com.hazelcast.concurrent.lock.LockServiceImpl; import com.hazelcast.concurrent.lock.LockStore; import com.hazelcast.concurrent.semaphore.SemaphoreService; import com.hazelcast.config.Config; import com.hazelcast.config.PartitioningStrategyConfig; import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.HazelcastInstanceAware; import com.hazelcast.core.IAtomicLong; import com.hazelcast.core.ICountDownLatch; import com.hazelcast.core.IExecutorService; import com.hazelcast.core.IList; import com.hazelcast.core.ILock; import com.hazelcast.core.IMap; import com.hazelcast.core.IQueue; import com.hazelcast.core.ISemaphore; import com.hazelcast.core.ISet; import com.hazelcast.core.IdGenerator; import com.hazelcast.core.Member; import com.hazelcast.core.Partition; import com.hazelcast.core.PartitioningStrategy; import com.hazelcast.instance.HazelcastInstanceFactory; import com.hazelcast.instance.Node; import com.hazelcast.instance.TestUtil; import com.hazelcast.nio.serialization.Data; import com.hazelcast.partition.strategy.StringAndPartitionAwarePartitioningStrategy; import com.hazelcast.partition.strategy.StringPartitioningStrategy; import com.hazelcast.ringbuffer.Ringbuffer; import com.hazelcast.ringbuffer.impl.RingbufferService; import com.hazelcast.spi.impl.NodeEngineImpl; import com.hazelcast.test.HazelcastParallelClassRunner; import com.hazelcast.test.HazelcastTestSupport; import com.hazelcast.test.TestHazelcastInstanceFactory; import com.hazelcast.test.annotation.ParallelTest; import com.hazelcast.test.annotation.QuickTest; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import java.io.Serializable; import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.Future; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @RunWith(HazelcastParallelClassRunner.class) @Category({QuickTest.class, ParallelTest.class}) public class PartitionControlledIdTest extends HazelcastTestSupport { private static HazelcastInstance[] instances; @BeforeClass public static void startHazelcastInstances() throws Exception { Config config = new Config(); PartitioningStrategy partitioningStrategy = StringAndPartitionAwarePartitioningStrategy.INSTANCE; config.getMapConfig("default") .setPartitioningStrategyConfig(new PartitioningStrategyConfig(partitioningStrategy)); TestHazelcastInstanceFactory instanceFactory = new TestHazelcastInstanceFactory(4); instances = instanceFactory.newInstances(config); warmUpPartitions(instances); } @AfterClass public static void killHazelcastInstances() { HazelcastInstanceFactory.terminateAll(); } private HazelcastInstance getHazelcastInstance(String partitionKey) { Partition partition = instances[0].getPartitionService().getPartition(partitionKey); Member owner = partition.getOwner(); assertNotNull(owner); HazelcastInstance hz = null; for (HazelcastInstance instance : instances) { if (instance.getCluster().getLocalMember().equals(owner)) { hz = instance; break; } } assertNotNull(hz); return hz; } public NodeEngineImpl getNodeEngine(HazelcastInstance hz) { Node node = getNode(hz); return node.nodeEngine; } @Test public void testLock() throws Exception { String partitionKey = "hazelcast"; HazelcastInstance hz = getHazelcastInstance(partitionKey); ILock lock = hz.getLock("lock@" + partitionKey); lock.lock(); assertEquals("lock@" + partitionKey, lock.getName()); assertEquals(partitionKey, lock.getPartitionKey()); Node node = getNode(hz); LockServiceImpl lockService = node.nodeEngine.getService(LockServiceImpl.SERVICE_NAME); Partition partition = instances[0].getPartitionService().getPartition(partitionKey); LockStore lockStore = lockService.getLockStore(partition.getPartitionId(), new InternalLockNamespace(lock.getName())); Data key = node.getSerializationService().toData(lock.getName(), StringPartitioningStrategy.INSTANCE); assertTrue(lockStore.isLocked(key)); } @Test public void testSemaphore() throws Exception { String partitionKey = "hazelcast"; HazelcastInstance hz = getHazelcastInstance(partitionKey); ISemaphore semaphore = hz.getSemaphore("semaphore@" + partitionKey); semaphore.release(); assertEquals("semaphore@" + partitionKey, semaphore.getName()); assertEquals(partitionKey, semaphore.getPartitionKey()); SemaphoreService service = getNodeEngine(hz).getService(SemaphoreService.SERVICE_NAME); assertTrue(service.containsSemaphore(semaphore.getName())); } @Test public void testRingbuffer() throws Exception { String partitionKey = "hazelcast"; HazelcastInstance hz = getHazelcastInstance(partitionKey); Ringbuffer ringbuffer = hz.getRingbuffer("ringbuffer@" + partitionKey); ringbuffer.add("foo"); assertEquals("ringbuffer@" + partitionKey, ringbuffer.getName()); assertEquals(partitionKey, ringbuffer.getPartitionKey()); RingbufferService service = getNodeEngine(hz).getService(RingbufferService.SERVICE_NAME); assertTrue(service.getContainers().containsKey(ringbuffer.getName())); } @Test public void testIdGenerator() throws Exception { String partitionKey = "hazelcast"; HazelcastInstance hz = getHazelcastInstance(partitionKey); IdGenerator idGenerator = hz.getIdGenerator("idgenerator@" + partitionKey); idGenerator.newId(); assertEquals("idgenerator@" + partitionKey, idGenerator.getName()); assertEquals(partitionKey, idGenerator.getPartitionKey()); AtomicLongService service = getNodeEngine(hz).getService(AtomicLongService.SERVICE_NAME); assertTrue(service.containsAtomicLong("hz:atomic:idGenerator:" + idGenerator.getName())); } @Test public void testAtomicLong() throws Exception { String partitionKey = "hazelcast"; HazelcastInstance hz = getHazelcastInstance(partitionKey); IAtomicLong atomicLong = hz.getAtomicLong("atomiclong@" + partitionKey); atomicLong.incrementAndGet(); assertEquals("atomiclong@" + partitionKey, atomicLong.getName()); assertEquals(partitionKey, atomicLong.getPartitionKey()); AtomicLongService service = getNodeEngine(hz).getService(AtomicLongService.SERVICE_NAME); assertTrue(service.containsAtomicLong(atomicLong.getName())); } @Test public void testQueue() throws Exception { String partitionKey = "hazelcast"; HazelcastInstance hz = getHazelcastInstance(partitionKey); IQueue queue = hz.getQueue("queue@" + partitionKey); queue.add(""); assertEquals("queue@" + partitionKey, queue.getName()); assertEquals(partitionKey, queue.getPartitionKey()); QueueService service = getNodeEngine(hz).getService(QueueService.SERVICE_NAME); assertTrue(service.containsQueue(queue.getName())); } @Test public void testList() throws Exception { String partitionKey = "hazelcast"; HazelcastInstance hz = getHazelcastInstance(partitionKey); IList list = hz.getList("list@" + partitionKey); list.add(""); assertEquals("list@" + partitionKey, list.getName()); assertEquals(partitionKey, list.getPartitionKey()); ListService service = getNodeEngine(hz).getService(ListService.SERVICE_NAME); assertTrue(service.getContainerMap().containsKey(list.getName())); } @Test public void testSet() throws Exception { String partitionKey = "hazelcast"; HazelcastInstance hz = getHazelcastInstance(partitionKey); ISet set = hz.getSet("set@" + partitionKey); set.add(""); assertEquals("set@" + partitionKey, set.getName()); assertEquals(partitionKey, set.getPartitionKey()); SetService service = getNodeEngine(hz).getService(SetService.SERVICE_NAME); assertTrue(service.getContainerMap().containsKey(set.getName())); } @Test public void testCountDownLatch() throws Exception { String partitionKey = "hazelcast"; HazelcastInstance hz = getHazelcastInstance(partitionKey); ICountDownLatch countDownLatch = hz.getCountDownLatch("countdownlatch@" + partitionKey); countDownLatch.trySetCount(1); assertEquals("countdownlatch@" + partitionKey, countDownLatch.getName()); assertEquals(partitionKey, countDownLatch.getPartitionKey()); CountDownLatchService service = getNodeEngine(hz).getService(CountDownLatchService.SERVICE_NAME); assertTrue(service.containsLatch(countDownLatch.getName())); } @Test public void testObjectWithPartitionKeyAndTask() throws Exception { HazelcastInstance instance = instances[0]; IExecutorService executorServices = instance.getExecutorService("executor"); String partitionKey = "hazelcast"; ISemaphore semaphore = instance.getSemaphore("foobar@" + partitionKey); semaphore.release(); ContainsSemaphoreTask task = new ContainsSemaphoreTask(semaphore.getName()); Future<Boolean> f = executorServices.submitToKeyOwner(task, semaphore.getPartitionKey()); assertTrue(f.get()); } private static class ContainsSemaphoreTask implements Callable<Boolean>, HazelcastInstanceAware, Serializable { private transient HazelcastInstance hz; private final String semaphoreName; private ContainsSemaphoreTask(String semaphoreName) { this.semaphoreName = semaphoreName; } @Override public void setHazelcastInstance(HazelcastInstance hazelcastInstance) { this.hz = hazelcastInstance; } @Override public Boolean call() { NodeEngineImpl nodeEngine = TestUtil.getNode(hz).nodeEngine; SemaphoreService service = nodeEngine.getService(SemaphoreService.SERVICE_NAME); return service.containsSemaphore(semaphoreName); } } @Test public void testObjectWithPartitionKeyAndMap() throws Exception { HazelcastInstance instance = instances[0]; IExecutorService executorServices = instance.getExecutorService("executor"); String partitionKey = "hazelcast"; String mapKey = "key@" + partitionKey; IMap map = instance.getMap("map"); map.put(mapKey, "foobar"); ISemaphore semaphore = instance.getSemaphore("s@" + partitionKey); semaphore.release(); ContainsSemaphoreAndMapEntryTask task = new ContainsSemaphoreAndMapEntryTask(semaphore.getName(), mapKey); Map<Member, Future<Boolean>> futures = executorServices.submitToAllMembers(task); int count = 0; for (Future<Boolean> f : futures.values()) { count += f.get() ? 1 : 0; } assertEquals(1, count); } private static class ContainsSemaphoreAndMapEntryTask implements Callable<Boolean>, HazelcastInstanceAware, Serializable { private final String mapKey; private transient HazelcastInstance hz; private final String semaphoreName; private ContainsSemaphoreAndMapEntryTask(String semaphoreName, String mapKey) { this.semaphoreName = semaphoreName; this.mapKey = mapKey; } @Override public void setHazelcastInstance(HazelcastInstance hazelcastInstance) { this.hz = hazelcastInstance; } @Override public Boolean call() { NodeEngineImpl nodeEngine = TestUtil.getNode(hz).nodeEngine; SemaphoreService service = nodeEngine.getService(SemaphoreService.SERVICE_NAME); IMap map = hz.getMap("map"); if (map.localKeySet().contains(mapKey)) { return service.containsSemaphore(semaphoreName); } else { return false; } } } }