/smart-hbase/smart-hbase-dao/src/test/java/com/smartitengineering/dao/impl/hbase/CommonDaoWriteTest.java
Java | 290 lines | 239 code | 21 blank | 30 comment | 0 complexity | fb4d2590e4d50ccbe8699652913f0387 MD5 | raw file
1/*
2 * This is a common dao with basic CRUD operations and is not limited to any
3 * persistent layer implementation
4 *
5 * Copyright (C) 2010 Imran M Yousuf (imyousuf@smartitengineering.com)
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 3 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19package com.smartitengineering.dao.impl.hbase;
20
21import com.google.inject.AbstractModule;
22import com.google.inject.Guice;
23import com.google.inject.Inject;
24import com.google.inject.Injector;
25import com.google.inject.PrivateModule;
26import com.google.inject.Scopes;
27import com.google.inject.Singleton;
28import com.google.inject.TypeLiteral;
29import com.google.inject.name.Named;
30import com.google.inject.name.Names;
31import com.google.inject.util.Providers;
32import com.smartitengineering.dao.hbase.ddl.HBaseTableConfiguration;
33import com.smartitengineering.dao.hbase.ddl.HBaseTableGenerator;
34import com.smartitengineering.dao.hbase.ddl.config.json.ConfigurationJsonParser;
35import com.smartitengineering.dao.impl.hbase.data.SampleDomain;
36import com.smartitengineering.dao.impl.hbase.data.SampleDomainObjectCoverter;
37import com.smartitengineering.dao.impl.hbase.spi.AsyncExecutorService;
38import com.smartitengineering.dao.impl.hbase.spi.DomainIdInstanceProvider;
39import com.smartitengineering.dao.impl.hbase.spi.FilterConfigs;
40import com.smartitengineering.dao.impl.hbase.spi.LockAttainer;
41import com.smartitengineering.dao.impl.hbase.spi.LockType;
42import com.smartitengineering.dao.impl.hbase.spi.MergeService;
43import com.smartitengineering.dao.impl.hbase.spi.ObjectRowConverter;
44import com.smartitengineering.dao.impl.hbase.spi.SchemaInfoProvider;
45import com.smartitengineering.dao.impl.hbase.spi.impl.LockAttainerImpl;
46import com.smartitengineering.dao.impl.hbase.spi.impl.MixedExecutorServiceImpl;
47import com.smartitengineering.dao.impl.hbase.spi.impl.SchemaInfoProviderBaseConfig;
48import com.smartitengineering.dao.impl.hbase.spi.impl.SchemaInfoProviderImpl;
49import com.smartitengineering.dao.impl.hbase.spi.impl.guice.GenericBaseConfigProvider;
50import com.smartitengineering.dao.impl.hbase.spi.impl.guice.GenericFilterConfigsProvider;
51import java.io.InputStream;
52import java.util.Collection;
53import java.util.concurrent.ExecutorService;
54import java.util.concurrent.Executors;
55import java.util.concurrent.TimeUnit;
56import org.apache.hadoop.hbase.HBaseTestingUtility;
57import org.junit.AfterClass;
58import org.junit.Assert;
59import org.junit.BeforeClass;
60import org.junit.Test;
61import org.slf4j.Logger;
62import org.slf4j.LoggerFactory;
63
64/**
65 *
66 * @author imyousuf
67 */
68public class CommonDaoWriteTest {
69
70 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
71 private static final Logger LOGGER = LoggerFactory.getLogger(CommonDaoWriteTest.class);
72 private static Injector injector;
73 private static CommonDaos commonDaos;
74
75 @BeforeClass
76 public static void globalSetup() throws Exception {
77 /*
78 * Start HBase and initialize tables
79 */
80 //-Djavax.xml.parsers.DocumentBuilderFactory=com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
81 System.setProperty("javax.xml.parsers.DocumentBuilderFactory",
82 "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
83 try {
84 TEST_UTIL.startMiniCluster();
85 }
86 catch (Exception ex) {
87 LOGGER.error(ex.getMessage(), ex);
88 }
89 //Create table for testing
90 InputStream classpathResource = CommonDaoWriteTest.class.getClassLoader().getResourceAsStream(
91 "com/smartitengineering/dao/impl/hbase/domain/ddl-config-sample.json");
92 Collection<HBaseTableConfiguration> configs = ConfigurationJsonParser.getConfigurations(classpathResource);
93 try {
94 new HBaseTableGenerator(configs, TEST_UTIL.getConfiguration(), true).generateTables();
95 }
96 catch (Exception ex) {
97 LOGGER.error("Could not create table!", ex);
98 Assert.fail(ex.getMessage());
99 }
100 /*
101 * Perform injection for different types of common dao
102 */
103 injector = Guice.createInjector(new TestModule(), new TestNoModule(), new TestOpModule(), new TestPesModule());
104 commonDaos = injector.getInstance(CommonDaos.class);
105 Assert.assertNotNull("Common Daos not initialized properly!", commonDaos);
106 }
107
108 @AfterClass
109 public static void globalTearDown() {
110 try {
111 TEST_UTIL.shutdownMiniCluster();
112 }
113 catch (Exception ex) {
114 LOGGER.warn("Error shutting down!", ex);
115 }
116 }
117
118 @Test
119 public void testOptimisticPersist() {
120 com.smartitengineering.dao.common.CommonDao<SampleDomain, Long> dao = commonDaos.optimisticDao;
121 SampleDomain domain = new SampleDomain();
122 domain.setName("Name 1");
123 domain.setId(1l);
124 dao.save(domain);
125 domain.setName("Name 1 `2");
126 try {
127 dao.update(domain);
128 Assert.fail("Should have failed!");
129 }
130 catch (Exception ex) {
131 LOGGER.info(ex.getMessage(), ex);
132 }
133 domain.setVersion(1l);
134 dao.update(domain);
135 domain.setVersion(3l);
136 try {
137 dao.delete(domain);
138 Assert.fail("Should have failed!");
139 }
140 catch (Exception ex) {
141 LOGGER.info(ex.getMessage(), ex);
142 }
143 domain.setVersion(0l);
144 try {
145 dao.delete(domain);
146 Assert.fail("Should have failed!");
147 }
148 catch (Exception ex) {
149 LOGGER.info(ex.getMessage(), ex);
150 }
151 domain.setVersion(2l);
152 dao.delete(domain);
153 }
154
155 @Test
156 public void testPessimisticPersist() {
157 com.smartitengineering.dao.common.CommonDao<SampleDomain, Long> dao = commonDaos.pessimisticDao;
158 SampleDomain domain = new SampleDomain();
159 domain.setName("Name 2");
160 domain.setId(2l);
161 dao.save(domain);
162 domain.setName("Name 2 `2");
163 try {
164 dao.update(domain);
165 }
166 catch (Exception ex) {
167 LOGGER.info(ex.getMessage(), ex);
168 Assert.fail("Should not have failed!");
169 }
170 domain.setVersion(1l);
171 dao.update(domain);
172 dao.delete(domain);
173 }
174
175 private static class CommonDaos {
176
177 public static final String NO_LOCK = "noLockDao";
178 public static final String PESSIMISTIC_LOCK = "pessimisticDao";
179 public static final String OPTIMISTIC_LOCK = "optimistic";
180 @Inject
181 @Named(OPTIMISTIC_LOCK)
182 private com.smartitengineering.dao.common.CommonDao<SampleDomain, Long> optimisticDao;
183 @Inject
184 @Named(NO_LOCK)
185 private com.smartitengineering.dao.common.CommonDao<SampleDomain, Long> noLockDao;
186 @Inject
187 @Named(PESSIMISTIC_LOCK)
188 private com.smartitengineering.dao.common.CommonDao<SampleDomain, Long> pessimisticDao;
189
190 public com.smartitengineering.dao.common.CommonDao<SampleDomain, Long> getNoLockDao() {
191 return noLockDao;
192 }
193
194 public com.smartitengineering.dao.common.CommonDao<SampleDomain, Long> getOptimisticDao() {
195 return optimisticDao;
196 }
197
198 public com.smartitengineering.dao.common.CommonDao<SampleDomain, Long> getPessimisticDao() {
199 return pessimisticDao;
200 }
201 }
202 private static final TypeLiteral<SchemaInfoProviderImpl<SampleDomain, Long>> vTypeLiteral = new TypeLiteral<SchemaInfoProviderImpl<SampleDomain, Long>>() {
203 };
204 private static final TypeLiteral<com.smartitengineering.dao.common.CommonDao<SampleDomain, Long>> l = new TypeLiteral<com.smartitengineering.dao.common.CommonDao<SampleDomain, Long>>() {
205 };
206 private static final TypeLiteral<CommonDao<SampleDomain, Long>> p = new TypeLiteral<CommonDao<SampleDomain, Long>>() {
207 };
208
209 private static class TestModule extends AbstractModule {
210
211 @Override
212 protected void configure() {
213 bind(new TypeLiteral<FilterConfigs<SampleDomain>>() {
214 }).toProvider(new GenericFilterConfigsProvider<SampleDomain>(
215 "com/smartitengineering/dao/impl/hbase/domain/Configs.json")).in(Scopes.SINGLETON);
216 bind(AsyncExecutorService.class).to(MixedExecutorServiceImpl.class).in(Singleton.class);
217 bind(ExecutorService.class).toInstance(Executors.newCachedThreadPool());
218 bind(Integer.class).annotatedWith(Names.named("maxRows")).toInstance(new Integer(100));
219 bind(Long.class).annotatedWith(Names.named("waitTime")).toInstance(new Long(10));
220 bind(TimeUnit.class).annotatedWith(Names.named("unit")).toInstance(TimeUnit.SECONDS);
221 bind(Boolean.class).annotatedWith(Names.named("mergeEnabled")).toInstance(Boolean.FALSE);
222 bind(DomainIdInstanceProvider.class).toProvider(Providers.<DomainIdInstanceProvider>of(null));
223 bind(new TypeLiteral<MergeService<SampleDomain, Long>>() {
224 }).toProvider(Providers.<MergeService<SampleDomain, Long>>of(null));
225 bind(new TypeLiteral<Class<Long>>() {
226 }).toInstance(Long.class);
227 }
228 }
229
230 private static class TestOpModule extends PrivateModule {
231
232 @Override
233 protected void configure() {
234 bind(new TypeLiteral<ObjectRowConverter<SampleDomain>>() {
235 }).to(SampleDomainObjectCoverter.class).in(Singleton.class);
236 bind(new TypeLiteral<LockAttainer<SampleDomain, Long>>() {
237 }).to(new TypeLiteral<LockAttainerImpl<SampleDomain, Long>>() {
238 }).in(Scopes.SINGLETON);
239 bind(new TypeLiteral<SchemaInfoProviderBaseConfig<SampleDomain>>() {
240 }).toProvider(new GenericBaseConfigProvider<SampleDomain>(
241 "com/smartitengineering/dao/impl/hbase/domain/BaseConfigOptimistic.json")).in(Scopes.SINGLETON);
242 bind(LockType.class).toInstance(LockType.OPTIMISTIC);
243 bind(new TypeLiteral<SchemaInfoProvider<SampleDomain, Long>>() {
244 }).to(vTypeLiteral).in(Singleton.class);
245
246 bind(l).annotatedWith(Names.named(CommonDaos.OPTIMISTIC_LOCK)).to(p).in(Scopes.SINGLETON);
247 binder().expose(l).annotatedWith(Names.named(CommonDaos.OPTIMISTIC_LOCK));
248 }
249 }
250
251 private static class TestNoModule extends PrivateModule {
252
253 @Override
254 protected void configure() {
255 bind(new TypeLiteral<ObjectRowConverter<SampleDomain>>() {
256 }).to(SampleDomainObjectCoverter.class).in(Singleton.class);
257 bind(new TypeLiteral<LockAttainer<SampleDomain, Long>>() {
258 }).to(new TypeLiteral<LockAttainerImpl<SampleDomain, Long>>() {
259 }).in(Scopes.SINGLETON);
260 bind(new TypeLiteral<SchemaInfoProvider<SampleDomain, Long>>() {
261 }).to(vTypeLiteral).in(Singleton.class);
262 bind(new TypeLiteral<SchemaInfoProviderBaseConfig<SampleDomain>>() {
263 }).toProvider(new GenericBaseConfigProvider<SampleDomain>(
264 "com/smartitengineering/dao/impl/hbase/domain/BaseConfigNonOptimistic.json")).in(Scopes.SINGLETON);
265 bind(LockType.class).toInstance(LockType.NONE);
266 bind(l).annotatedWith(Names.named(CommonDaos.NO_LOCK)).to(p).in(Scopes.SINGLETON);
267 binder().expose(l).annotatedWith(Names.named(CommonDaos.NO_LOCK));
268 }
269 }
270
271 private static class TestPesModule extends PrivateModule {
272
273 @Override
274 protected void configure() {
275 bind(new TypeLiteral<ObjectRowConverter<SampleDomain>>() {
276 }).to(SampleDomainObjectCoverter.class).in(Singleton.class);
277 bind(new TypeLiteral<LockAttainer<SampleDomain, Long>>() {
278 }).to(new TypeLiteral<LockAttainerImpl<SampleDomain, Long>>() {
279 }).in(Scopes.SINGLETON);
280 bind(new TypeLiteral<SchemaInfoProvider<SampleDomain, Long>>() {
281 }).to(vTypeLiteral).in(Singleton.class);
282 bind(new TypeLiteral<SchemaInfoProviderBaseConfig<SampleDomain>>() {
283 }).toProvider(new GenericBaseConfigProvider<SampleDomain>(
284 "com/smartitengineering/dao/impl/hbase/domain/BaseConfigNonOptimistic.json")).in(Scopes.SINGLETON);
285 bind(LockType.class).toInstance(LockType.PESSIMISTIC);
286 bind(l).annotatedWith(Names.named(CommonDaos.PESSIMISTIC_LOCK)).to(p).in(Scopes.SINGLETON);
287 binder().expose(l).annotatedWith(Names.named(CommonDaos.PESSIMISTIC_LOCK));
288 }
289 }
290}