/* * Copyright 2008-2009 LinkedIn, 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 voldemort.client; import java.io.StringReader; import java.util.List; import voldemort.cluster.failuredetector.FailureDetector; import voldemort.cluster.failuredetector.NoopFailureDetector; import voldemort.serialization.DefaultSerializerFactory; import voldemort.serialization.Serializer; import voldemort.store.StorageEngine; import voldemort.store.Store; import voldemort.store.StoreDefinition; import voldemort.store.StoreUtils; import voldemort.store.memory.InMemoryStorageEngine; import voldemort.store.serialized.SerializingStore; import voldemort.store.versioned.InconsistencyResolvingStore; import voldemort.store.versioned.VersionIncrementingStore; import voldemort.store.views.ViewStorageConfiguration; import voldemort.store.views.ViewStorageEngine; import voldemort.utils.SystemTime; import voldemort.utils.Time; import voldemort.versioning.ChainedResolver; import voldemort.versioning.InconsistencyResolver; import voldemort.versioning.TimeBasedInconsistencyResolver; import voldemort.versioning.VectorClockInconsistencyResolver; import voldemort.versioning.Versioned; import voldemort.xml.StoreDefinitionsMapper; /** * A store client that produces non-persistent, in-memory stores. This is useful * for unit testing. * * */ @SuppressWarnings("unchecked") public class MockStoreClientFactory implements StoreClientFactory { private final int nodeId; private final Serializer<?> keySerializer; private final Serializer<?> valueSerializer; private final Serializer<?> viewValueSerializer; private final Serializer<?> transformsSerializer; private final Time time; private final FailureDetector failureDetector; private static final StoreDefinitionsMapper storeMapper = new StoreDefinitionsMapper(); private String storesXml; public MockStoreClientFactory(Serializer<?> keySerializer, Serializer<?> valueSerializer, Serializer<?> transformsSerializer) { this(keySerializer, valueSerializer, null, transformsSerializer, 0, SystemTime.INSTANCE); } public MockStoreClientFactory(Serializer<?> keySerializer, Serializer<?> valueSerializer, Serializer<?> viewValueSerializer, Serializer<?> transformsSerializer, String storesXml) { this(keySerializer, valueSerializer, viewValueSerializer, transformsSerializer, 0, SystemTime.INSTANCE); this.storesXml = storesXml; } public MockStoreClientFactory(Serializer<?> keySerializer, Serializer<?> valueSerializer, Serializer<?> viewValueSerializer, Serializer<?> transformsSerializer, int nodeId, Time time) { this.nodeId = nodeId; this.keySerializer = keySerializer; this.valueSerializer = valueSerializer; this.viewValueSerializer = viewValueSerializer; this.transformsSerializer = transformsSerializer; this.time = time; failureDetector = new NoopFailureDetector(); } public <K, V> StoreClient<K, V> getStoreClient(String storeName) { return getStoreClient(storeName, new TimeBasedInconsistencyResolver<V>()); } public <K, V> StoreClient<K, V> getStoreClient(String storeName, InconsistencyResolver<Versioned<V>> resolver) { return new DefaultStoreClient(storeName, resolver, this, 3); } public <K1, V1, T1> Store<K1, V1, T1> getRawStore(String storeName, InconsistencyResolver<Versioned<V1>> resolver) { if(this.storesXml != null) return getRawStore(storeName); // Add inconsistency resolving decorator, using their inconsistency // resolver (if they gave us one) InconsistencyResolver<Versioned<V1>> secondaryResolver = new TimeBasedInconsistencyResolver(); if(resolver != null) secondaryResolver = resolver; Store store = new VersionIncrementingStore(new InMemoryStorageEngine(storeName), nodeId, time); if(isSerialized()) store = new SerializingStore(store, keySerializer, valueSerializer, transformsSerializer); Store<K1, V1, T1> consistentStore = new InconsistencyResolvingStore<K1, V1, T1>(store, new ChainedResolver<Versioned<V1>>(new VectorClockInconsistencyResolver(), secondaryResolver)); return consistentStore; } private <K1, V1, T1> Store<K1, V1, T1> getRawStore(String storeName) { List<StoreDefinition> storeDefs = storeMapper.readStoreList(new StringReader(storesXml)); StoreDefinition storeDef = null; for(StoreDefinition d: storeDefs) if(d.getName().equals(storeName)) storeDef = d; if(storeDef == null) throw new BootstrapFailureException("Unknown store '" + storeName + "'."); DefaultSerializerFactory serializerFactory = new DefaultSerializerFactory(); Serializer<K1> keySerializer = (Serializer<K1>) serializerFactory.getSerializer(storeDef.getKeySerializer()); Serializer<V1> valueSerializer = (Serializer<V1>) serializerFactory.getSerializer(storeDef.getValueSerializer()); Serializer<T1> transformsSerializer = null; if(storeDef.isView()) transformsSerializer = (Serializer<T1>) serializerFactory.getSerializer(storeDef.getTransformsSerializer()); // Add inconsistency resolving decorator, using their inconsistency // resolver (if they gave us one) InconsistencyResolver<Versioned<V1>> secondaryResolver = new TimeBasedInconsistencyResolver(); StorageEngine engine; if(storeDef.isView()) engine = new InMemoryStorageEngine(storeDef.getViewTargetStoreName()); else engine = new InMemoryStorageEngine(storeDef.getName()); if(storeDef.isView()) { // instantiate view String targetName = storeDef.getViewTargetStoreName(); StoreDefinition targetDef = StoreUtils.getStoreDef(storeDefs, targetName); engine = new ViewStorageEngine(storeName, engine, this.viewValueSerializer != null ? this.viewValueSerializer : serializerFactory.getSerializer(storeDef.getValueSerializer()), this.transformsSerializer != null ? this.transformsSerializer : serializerFactory.getSerializer(storeDef.getTransformsSerializer()), this.keySerializer != null ? this.keySerializer : serializerFactory.getSerializer(targetDef.getKeySerializer()), this.valueSerializer != null ? this.valueSerializer : serializerFactory.getSerializer(targetDef.getValueSerializer()), null, ViewStorageConfiguration.loadTransformation(storeDef.getValueTransformation())); } Store store = new VersionIncrementingStore(engine, nodeId, time); store = new SerializingStore(store, this.keySerializer != null ? this.keySerializer : keySerializer, this.valueSerializer != null ? this.valueSerializer : valueSerializer, this.transformsSerializer != null ? this.transformsSerializer : transformsSerializer); Store<K1, V1, T1> consistentStore = new InconsistencyResolvingStore<K1, V1, T1>(store, new ChainedResolver<Versioned<V1>>(new VectorClockInconsistencyResolver(), secondaryResolver)); return consistentStore; } private boolean isSerialized() { return keySerializer != null && valueSerializer != null; } public void close() { } public FailureDetector getFailureDetector() { return failureDetector; } }