@Test public void testOversizeChainReplicationMessage() throws Exception { ClusterTierPassiveEntity passiveEntity = new ClusterTierPassiveEntity(defaultRegistry, defaultConfiguration, DEFAULT_MAPPER); passiveEntity.createNew(); TestInvokeContext context = new TestInvokeContext(); long key = 2L; Chain oversizeChain = Util.getChain(true, createPayload(key, 1024 * 1024)); PassiveReplicationMessage oversizeMsg = new PassiveReplicationMessage.ChainReplicationMessage(key, oversizeChain, 2L, 1L, (long) 3); passiveEntity.invokePassive(context, oversizeMsg); // Should be cleared, the value is oversize. assertThat(passiveEntity.getStateService().getStore(passiveEntity.getStoreIdentifier()).get(key).isEmpty(), is(true)); }
@Test public void testDestroyServerStore() throws Exception { ClusterTierPassiveEntity passiveEntity = new ClusterTierPassiveEntity(defaultRegistry, defaultConfiguration, DEFAULT_MAPPER); passiveEntity.createNew(); passiveEntity.destroy(); assertThat(defaultRegistry.getStoreManagerService().getStores(), is(empty())); assertThat(defaultRegistry.getStoreManagerService().getDedicatedResourcePoolIds(), is(empty())); assertThat(defaultRegistry.getResource(defaultResource).getUsed(), is(0L)); }
@SuppressWarnings("try") private EhcacheEntityResponse invokePassiveInternal(InvokeContext context, EhcacheEntityMessage message) { if (message instanceof EhcacheOperationMessage) { EhcacheOperationMessage operationMessage = (EhcacheOperationMessage) message; try (EhcacheStateContext ignored = stateService.beginProcessing(operationMessage, storeIdentifier)) { EhcacheMessageType messageType = operationMessage.getMessageType(); if (isStoreOperationMessage(messageType)) { invokeServerStoreOperation((ServerStoreOpMessage) message); } else if (isStateRepoOperationMessage(messageType)) { return stateService.getStateRepositoryManager().invoke((StateRepositoryOpMessage) message); } else if (isPassiveReplicationMessage(messageType)) { return invokeRetirementMessages((PassiveReplicationMessage) message); } else { throw new AssertionError("Unsupported EhcacheOperationMessage: " + operationMessage.getMessageType()); } } catch (ClusterException | OversizeMappingException e) { // The above operations are not critical enough to fail a passive, so just log the exception LOGGER.error("Unexpected exception raised during operation: " + message, e); } } else if (message instanceof EhcacheSyncMessage) { invokeSyncOperation(context, (EhcacheSyncMessage) message); } else { throw new AssertionError("Unsupported EhcacheEntityMessage: " + message.getClass()); } // Default response for messages not returning anything specific return success(); }
@Test public void testCreateDedicatedServerStore() throws Exception { ClusterTierPassiveEntity passiveEntity = new ClusterTierPassiveEntity(defaultRegistry, defaultConfiguration, DEFAULT_MAPPER); passiveEntity.createNew(); assertThat(defaultRegistry.getStoreManagerService().getDedicatedResourcePoolIds(), containsInAnyOrder(defaultStoreName)); assertThat(defaultRegistry.getResource(defaultResource).getUsed(), is(MemoryUnit.MEGABYTES.toBytes(1L))); assertThat(defaultRegistry.getStoreManagerService().getStores(), containsInAnyOrder(defaultStoreName)); }
@Test public void testInvalidMessageThrowsError() throws Exception { ClusterTierPassiveEntity passiveEntity = new ClusterTierPassiveEntity(defaultRegistry, defaultConfiguration, DEFAULT_MAPPER); TestInvokeContext context = new TestInvokeContext(); try { passiveEntity.invokePassive(context, new InvalidMessage()); fail("Invalid message should result in AssertionError"); } catch (AssertionError e) { assertThat(e.getMessage(), containsString("Unsupported")); } }
@Override public ClusterTierPassiveEntity createPassiveEntity(ServiceRegistry registry, byte[] configuration) throws ConfigurationException { ClusterTierEntityConfiguration clusterTierEntityConfiguration = configCodec.decodeClusteredStoreConfiguration(configuration); return new ClusterTierPassiveEntity(registry, clusterTierEntityConfiguration, DEFAULT_MAPPER); }
private void invokeServerStoreOperation(ServerStoreOpMessage message) throws ClusterException { ServerSideServerStore cacheStore = stateService.getStore(storeIdentifier); if (cacheStore == null) { // An operation on a non-existent store should never get out of the client throw new LifecycleException("cluster tier does not exist : '" + storeIdentifier + "'"); } switch (message.getMessageType()) { case REPLACE: { ServerStoreOpMessage.ReplaceAtHeadMessage replaceAtHeadMessage = (ServerStoreOpMessage.ReplaceAtHeadMessage)message; cacheStore.replaceAtHead(replaceAtHeadMessage.getKey(), replaceAtHeadMessage.getExpect(), replaceAtHeadMessage.getUpdate()); break; } case CLEAR: { LOGGER.info("Clearing cluster tier {}", storeIdentifier); try { cacheStore.clear(); } catch (TimeoutException e) { throw new AssertionError("Server side store is not expected to throw timeout exception"); } if (isEventual()) { stateService.getInvalidationTracker(storeIdentifier).setClearInProgress(true); } break; } default: throw new AssertionError("Unsupported ServerStore operation : " + message.getMessageType()); } }
@Test public void testCreateSharedServerStore() throws Exception { defaultRegistry.addSharedPool(defaultSharedPool, MemoryUnit.MEGABYTES.toBytes(2), defaultResource); ServerStoreConfiguration storeConfiguration = new ServerStoreConfigBuilder().shared(defaultSharedPool).build(); ClusterTierPassiveEntity passiveEntity = new ClusterTierPassiveEntity(defaultRegistry, new ClusterTierEntityConfiguration(identifier, defaultStoreName, storeConfiguration), DEFAULT_MAPPER); passiveEntity.createNew(); assertThat(defaultRegistry.getStoreManagerService().getStores(), containsInAnyOrder(defaultStoreName)); assertThat(defaultRegistry.getStoreManagerService() .getSharedResourcePoolIds(), containsInAnyOrder(defaultSharedPool)); assertThat(defaultRegistry.getStoreManagerService().getDedicatedResourcePoolIds(), is(empty())); assertThat(defaultRegistry.getResource(defaultResource).getUsed(), is(MemoryUnit.MEGABYTES.toBytes(2L))); }
@Test(expected = ConfigurationException.class) public void testConfigNull() throws Exception { new ClusterTierPassiveEntity(mock(ServiceRegistry.class), null, DEFAULT_MAPPER); }
if (isEventual()) { stateService.getInvalidationTracker(storeIdentifier).trackHashInvalidation(retirementMessage.getKey()); if (isEventual()) { InvalidationCompleteMessage invalidationCompleteMessage = (InvalidationCompleteMessage) message; stateService.getInvalidationTracker(storeIdentifier).untrackHashInvalidation(invalidationCompleteMessage.getKey()); if (isEventual()) { stateService.getInvalidationTracker(storeIdentifier).setClearInProgress(false);
@Test public void testOversizeReplaceAtHeadMessage() throws Exception { ClusterTierPassiveEntity passiveEntity = new ClusterTierPassiveEntity(defaultRegistry, defaultConfiguration, DEFAULT_MAPPER); passiveEntity.createNew(); TestInvokeContext context = new TestInvokeContext(); int key = 2; Chain chain = Util.getChain(true, createPayload(1L)); PassiveReplicationMessage message = new PassiveReplicationMessage.ChainReplicationMessage(key, chain, 2L, 1L, 3L); passiveEntity.invokePassive(context, message); Chain oversizeChain = Util.getChain(true, createPayload(2L, 1024 * 1024)); ServerStoreOpMessage.ReplaceAtHeadMessage oversizeMsg = new ServerStoreOpMessage.ReplaceAtHeadMessage(key, chain, oversizeChain); passiveEntity.invokePassive(context, oversizeMsg); // Should be evicted, the value is oversize. assertThat(passiveEntity.getStateService().getStore(passiveEntity.getStoreIdentifier()).get(key).isEmpty(), is(true)); }
@Test public void testPassiveTracksMessageDuplication() throws Exception { ClusterTierPassiveEntity passiveEntity = new ClusterTierPassiveEntity(defaultRegistry, defaultConfiguration, DEFAULT_MAPPER); passiveEntity.createNew(); Chain chain = Util.getChain(true, createPayload(1L)); TestInvokeContext context = new TestInvokeContext(); long clientId = 3; PassiveReplicationMessage message1 = new PassiveReplicationMessage.ChainReplicationMessage(2, chain, 2L, 1L, clientId); passiveEntity.invokePassive(context, message1); // Should be added assertThat(passiveEntity.getStateService().getStore(passiveEntity.getStoreIdentifier()).get(2).isEmpty(), is(false)); Chain emptyChain = Util.getChain(true); PassiveReplicationMessage message2 = new PassiveReplicationMessage.ChainReplicationMessage(2, emptyChain, 2L, 1L, clientId); passiveEntity.invokePassive(context, message2); // Should not be cleared, message is a duplicate assertThat(passiveEntity.getStateService().getStore(passiveEntity.getStoreIdentifier()).get(2).isEmpty(), is(false)); PassiveReplicationMessage message3 = new PassiveReplicationMessage.ChainReplicationMessage(2, chain, 3L, 1L, clientId); passiveEntity.invokePassive(context, message3); // Should be added as well, different message id assertThat(passiveEntity.getStateService().getStore(passiveEntity.getStoreIdentifier()).get(2).isEmpty(), is(false)); }