private VoltronReadWriteLockClient createClientEntity() { try { while (true) { try { reference.create(null); LOGGER.debug("Created lock entity " + reference.getName()); } catch (EntityAlreadyExistsException f) { //ignore } catch (EntityConfigurationException e) { LOGGER.error("Error creating lock entity - configuration exception", e); throw new AssertionError(e); } try { return reference.fetchEntity(null); } catch (EntityNotFoundException e) { //ignore } } } catch (EntityVersionMismatchException | EntityNotProvidedException e) { throw new IllegalStateException(e); } }
@Override public void create() throws EntityAlreadyExistsException { EntityRef<E, C, U> ref = getEntityRef(); try { while (true) { ref.create(configuration); try { ref.fetchEntity(null).close(); return; } catch (EntityNotFoundException e) { //continue; } } } catch (EntityNotProvidedException | EntityVersionMismatchException e) { LOGGER.error("Unable to create entity {} for id {}", entityType.getName(), entityIdentifier, e); throw new AssertionError(e); } catch (EntityConfigurationException e) { LOGGER.error("Unable to create entity - configuration exception", e); throw new AssertionError(e); } }
@Test public void testFetchExistingLockEntityWhenExists() throws Exception { doThrow(EntityAlreadyExistsException.class).when(entityRef).create(any(Void.class)); when(entityRef.fetchEntity(null)).thenReturn(client); when(connection.<VoltronReadWriteLockClient, Void, Void>getEntityRef(VoltronReadWriteLockClient.class, 1, "VoltronReadWriteLock-TestLock")).thenReturn(entityRef); VoltronReadWriteLock lock = new VoltronReadWriteLock(connection, "TestLock"); lock.readLock(); }
@Test public void testDestroyedEntityAllowsRecreation() throws Throwable { try (Connection client = CLUSTER.newConnection()) { EntityRef<ClusterTierManagerClientEntity, ClusterTierManagerConfiguration, Void> ref = getEntityRef(client); ref.create(blankConfiguration); ref.destroy(); ref.create(blankConfiguration); assertThat(ref.fetchEntity(null), not(nullValue())); } }
@Test public void testCreateLockEntityWhenNotExisting() throws Exception { when(entityRef.fetchEntity(null)).thenReturn(client); when(connection.<VoltronReadWriteLockClient, Void, Void>getEntityRef(VoltronReadWriteLockClient.class, 1, "VoltronReadWriteLock-TestLock")).thenReturn(entityRef); VoltronReadWriteLock lock = new VoltronReadWriteLock(connection, "TestLock"); lock.readLock(); verify(entityRef).create(isNull()); }
@Test public void testCreateWhenExisting() throws Exception { doThrow(EntityAlreadyExistsException.class).when(entityRef).create(any()); when(getEntityRef(ClusterTierManagerClientEntity.class)).thenReturn(entityRef); addMockUnlockedLock(connection, "VoltronReadWriteLock-ClusterTierManagerClientEntityFactory-AccessLock-test"); ClusterTierManagerClientEntityFactory factory = new ClusterTierManagerClientEntityFactory(connection); try { factory.create("test", null); fail("Expected EntityAlreadyExistsException"); } catch (EntityAlreadyExistsException e) { //expected } }
@Test public void testCreateBadConfig() throws Exception { doThrow(EntityConfigurationException.class).when(entityRef).create(any(ClusterTierManagerConfiguration.class)); when(getEntityRef(ClusterTierManagerClientEntity.class)).thenReturn(entityRef); addMockUnlockedLock(connection, "VoltronReadWriteLock-ClusterTierManagerClientEntityFactory-AccessLock-test"); ClusterTierManagerClientEntityFactory factory = new ClusterTierManagerClientEntityFactory(connection); try { factory.create("test", null); fail("Expecting ClusterTierManagerCreationException"); } catch (ClusterTierManagerCreationException e) { // expected } }
@Test @SuppressWarnings("unchecked") public void testRetrieveWhenNotExisting() throws Exception { when(entityRef.fetchEntity(null)).thenThrow(EntityNotFoundException.class); doThrow(EntityAlreadyExistsException.class).when(entityRef).create(any()); when(getEntityRef(ClusterTierManagerClientEntity.class)).thenReturn(entityRef); addMockUnlockedLock(connection, "VoltronReadWriteLock-ClusterTierManagerClientEntityFactory-AccessLock-test"); ClusterTierManagerClientEntityFactory factory = new ClusterTierManagerClientEntityFactory(connection); try { factory.retrieve("test", null); fail("Expected EntityNotFoundException"); } catch (EntityNotFoundException e) { //expected } }
@Test public void testCreate() throws Exception { when(getEntityRef(ClusterTierManagerClientEntity.class)).thenReturn(entityRef); addMockUnlockedLock(connection, "VoltronReadWriteLock-ClusterTierManagerClientEntityFactory-AccessLock-test"); ClusterTierManagerClientEntityFactory factory = new ClusterTierManagerClientEntityFactory(connection); factory.create("test", null); verify(entityRef).create(isA(ClusterTierManagerConfiguration.class)); verifyNoMoreInteractions(entityRef); }
@Test public void testAbsentEntityCreationSucceeds() throws Throwable { try (Connection client = CLUSTER.newConnection()) { EntityRef<ClusterTierManagerClientEntity, ClusterTierManagerConfiguration, Void> ref = getEntityRef(client); ref.create(blankConfiguration); assertThat(ref.fetchEntity(null), not(Matchers.nullValue())); } }
@Test public void testPresentEntityCreationFails() throws Throwable { try (Connection client = CLUSTER.newConnection()) { EntityRef<ClusterTierManagerClientEntity, ClusterTierManagerConfiguration, Void> ref = getEntityRef(client); ref.create(blankConfiguration); try { try { ref.create(blankConfiguration); fail("Expected EntityAlreadyExistsException"); } catch (EntityAlreadyExistsException e) { //expected } ClusterTierManagerConfiguration otherConfiguration = new ClusterTierManagerConfiguration("different", new ServerSideConfiguration(emptyMap())); try { ref.create(otherConfiguration); fail("Expected EntityAlreadyExistsException"); } catch (EntityAlreadyExistsException e) { //expected } } finally { ref.destroy(); } } }
@Test public void testReadLockExcludesWrite() throws Exception { try (Connection connection = ConnectionFactory.connect(TEST_URI, new Properties())) { EntityRef<VoltronReadWriteLockClient, Void, Void> ref = getEntityReference(connection); ref.create(null); VoltronReadWriteLockClient locker = ref.fetchEntity(null); locker.lock(READ); try { VoltronReadWriteLockClient tester = ref.fetchEntity(null); assertThat(tester.tryLock(WRITE), is(false)); } finally { locker.unlock(READ); } } }
@Test public void testWriteLockExcludesRead() throws Exception { try (Connection connection = ConnectionFactory.connect(TEST_URI, new Properties())) { EntityRef<VoltronReadWriteLockClient, Void, Void> ref = getEntityReference(connection); ref.create(null); VoltronReadWriteLockClient locker = ref.fetchEntity(null); locker.lock(WRITE); try { VoltronReadWriteLockClient tester = ref.fetchEntity(null); assertThat(tester.tryLock(READ), is(false)); } finally { locker.unlock(WRITE); } } }
@Test public void testWriteLockExcludesWrite() throws Exception { try (Connection connection = ConnectionFactory.connect(TEST_URI, new Properties())) { EntityRef<VoltronReadWriteLockClient, Void, Void> ref = getEntityReference(connection); ref.create(null); VoltronReadWriteLockClient locker = ref.fetchEntity(null); locker.lock(WRITE); try { VoltronReadWriteLockClient tester = ref.fetchEntity(null); assertThat(tester.tryLock(WRITE), is(false)); } finally { locker.unlock(WRITE); } } }
@Test @Ignore @SuppressWarnings("try") public void testPresentEntityDestroyBlockedByHeldReferenceSucceeds() throws Throwable { try (Connection client = CLUSTER.newConnection()) { EntityRef<ClusterTierManagerClientEntity, ClusterTierManagerConfiguration, Void> ref = getEntityRef(client); ref.create(blankConfiguration); try (ClusterTierManagerClientEntity entity = ref.fetchEntity(null)) { ref.destroy(); } } }
@Test public void testPresentEntityDestroyNotBlockedByReleasedReferenceSucceeds() throws Throwable { try (Connection client = CLUSTER.newConnection()) { EntityRef<ClusterTierManagerClientEntity, ClusterTierManagerConfiguration, Void> ref = getEntityRef(client); ref.create(blankConfiguration); ref.fetchEntity(null).close(); ref.destroy(); } }
@Test public void testReadLockAllowsRead() throws Exception { try (Connection connection = ConnectionFactory.connect(TEST_URI, new Properties())) { EntityRef<VoltronReadWriteLockClient, Void, Void> ref = getEntityReference(connection); ref.create(null); VoltronReadWriteLockClient locker = ref.fetchEntity(null); locker.lock(READ); try { VoltronReadWriteLockClient tester = ref.fetchEntity(null); assertThat(tester.tryLock(READ), is(true)); tester.unlock(READ); } finally { locker.unlock(READ); } } }
@Test public void testPresentEntityDestroySucceeds() throws Throwable { try (Connection client = CLUSTER.newConnection()) { EntityRef<ClusterTierManagerClientEntity, ClusterTierManagerConfiguration, Void> ref = getEntityRef(client); ref.create(blankConfiguration); ref.destroy(); try { ref.fetchEntity(null); fail("Expected EntityNotFoundException"); } catch (EntityNotFoundException e) { //expected } } }
@Test public void testReadUnblocksAfterWriteReleased() throws Exception { try (Connection connection = ConnectionFactory.connect(TEST_URI, new Properties())) { final EntityRef<VoltronReadWriteLockClient, Void, Void> ref = getEntityReference(connection); ref.create(null); Future<Void> success; final VoltronReadWriteLockClient tester; VoltronReadWriteLockClient locker = ref.fetchEntity(null); locker.lock(WRITE); try { tester = ref.fetchEntity(null); success = async(() -> { tester.lock(READ); return null; }); try { success.get(50, TimeUnit.MILLISECONDS); fail("Expected TimeoutException"); } catch (TimeoutException e) { //expected } } finally { locker.unlock(WRITE); } success.get(2, TimeUnit.MINUTES); tester.unlock(READ); } }
@Test public void testWriteUnblocksAfterReadReleased() throws Exception { try (Connection connection = ConnectionFactory.connect(TEST_URI, new Properties())) { final EntityRef<VoltronReadWriteLockClient, Void, Void> ref = getEntityReference(connection); ref.create(null); Future<Void> success; final VoltronReadWriteLockClient tester; VoltronReadWriteLockClient locker = ref.fetchEntity(null); locker.lock(READ); try { tester = ref.fetchEntity(null); success = async(() -> { tester.lock(WRITE); return null; }); try { success.get(50, TimeUnit.MILLISECONDS); fail("Expected TimeoutException"); } catch (TimeoutException e) { //expected } } finally { locker.unlock(READ); } success.get(2, TimeUnit.MINUTES); tester.unlock(WRITE); } }