/* * Copyright Terracotta, Inc. * * 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 org.ehcache.clustered.server; import org.ehcache.clustered.common.internal.messages.EhcacheEntityMessage; import org.ehcache.clustered.common.internal.messages.EhcacheEntityResponse; import org.terracotta.entity.ActiveServerEntity; import org.terracotta.entity.ClientDescriptor; import org.terracotta.entity.ConcurrencyStrategy; import org.terracotta.entity.ConfigurationException; import org.terracotta.entity.EntityServerService; import org.terracotta.entity.ExecutionStrategy; import org.terracotta.entity.MessageCodec; import org.terracotta.entity.ServiceRegistry; import org.terracotta.entity.SyncMessageCodec; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; /** * Provides an alternative to {@link ClusterTierManagerServerEntityService} for unit tests to enable observing * the state of the {@link ClusterTierManagerActiveEntity} instances served. */ public class ObservableEhcacheServerEntityService implements EntityServerService<EhcacheEntityMessage, EhcacheEntityResponse> { private final ClusterTierManagerServerEntityService delegate = new ClusterTierManagerServerEntityService(); private final List<ClusterTierManagerActiveEntity> servedActiveEntities = new ArrayList<ClusterTierManagerActiveEntity>(); private final List<ClusterTierManagerPassiveEntity> servedPassiveEntities = new ArrayList<>(); /** * Gets a list of {@link ObservableEhcacheActiveEntity} instances wrapping the * {@link ClusterTierManagerActiveEntity} instances served by this {@link EntityServerService}. * * @return an unmodifiable list of {@code ObservableEhcacheActiveEntity} instances */ public List<ObservableEhcacheActiveEntity> getServedActiveEntities() throws NoSuchFieldException, IllegalAccessException { List<ObservableEhcacheActiveEntity> observables = new ArrayList<ObservableEhcacheActiveEntity>(servedActiveEntities.size()); for (ClusterTierManagerActiveEntity servedActiveEntity : servedActiveEntities) { observables.add(new ObservableEhcacheActiveEntity(servedActiveEntity)); } return Collections.unmodifiableList(observables); } @Override public long getVersion() { return delegate.getVersion(); } @Override public boolean handlesEntityType(String typeName) { return delegate.handlesEntityType(typeName); } @Override public ClusterTierManagerActiveEntity createActiveEntity(ServiceRegistry registry, byte[] configuration) throws ConfigurationException { ClusterTierManagerActiveEntity activeEntity = delegate.createActiveEntity(registry, configuration); servedActiveEntities.add(activeEntity); return activeEntity; } @Override public ClusterTierManagerPassiveEntity createPassiveEntity(ServiceRegistry registry, byte[] configuration) throws ConfigurationException { ClusterTierManagerPassiveEntity passiveEntity = delegate.createPassiveEntity(registry, configuration); servedPassiveEntities.add(passiveEntity); return passiveEntity; } @Override public ConcurrencyStrategy<EhcacheEntityMessage> getConcurrencyStrategy(byte[] config) { return delegate.getConcurrencyStrategy(config); } @Override public ExecutionStrategy<EhcacheEntityMessage> getExecutionStrategy(byte[] configuration) { return delegate.getExecutionStrategy(configuration); } @Override public MessageCodec<EhcacheEntityMessage, EhcacheEntityResponse> getMessageCodec() { return delegate.getMessageCodec(); } @Override public SyncMessageCodec<EhcacheEntityMessage> getSyncMessageCodec() { return delegate.getSyncMessageCodec(); } /** * Provides access to unit test state methods in an {@link ClusterTierManagerActiveEntity} instance. */ public static final class ObservableEhcacheActiveEntity { private final ClusterTierManagerActiveEntity activeEntity; private final EhcacheStateServiceImpl ehcacheStateService; private ObservableEhcacheActiveEntity(ClusterTierManagerActiveEntity activeEntity) throws NoSuchFieldException, IllegalAccessException { this.activeEntity = activeEntity; Field field = activeEntity.getClass().getDeclaredField("ehcacheStateService"); field.setAccessible(true); this.ehcacheStateService = (EhcacheStateServiceImpl)field.get(activeEntity); } public ActiveServerEntity<EhcacheEntityMessage, EhcacheEntityResponse> getActiveEntity() { return this.activeEntity; } public Set<ClientDescriptor> getConnectedClients() { return activeEntity.getConnectedClients(); } public Set<String> getStores() { return ehcacheStateService.getStores(); } public String getDefaultServerResource() { return ehcacheStateService.getDefaultServerResource(); } public Set<String> getSharedResourcePoolIds() { return ehcacheStateService.getSharedResourcePoolIds(); } public Set<String> getDedicatedResourcePoolIds() { return ehcacheStateService.getDedicatedResourcePoolIds(); } } }