getInProgress();
54 |
55 | /**
56 | * @return transaction id {@code X} such that any of the transactions newer than {@code X} might be invisible to
57 | * some of the currently in-progress transactions or to those that will be started
58 | * NOTE: the returned tx id can be invalid.
59 | */
60 | long getVisibilityUpperBound();
61 | }
62 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/persist/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2014 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | /**
18 | * This package contains interfaces and implementations for persisting transaction state.
19 | */
20 | package co.cask.tephra.persist;
21 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/rpc/RPCServiceHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2014 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 | package co.cask.tephra.rpc;
17 |
18 | /**
19 | * Defines lifecycle interface for all rpc handlers.
20 | */
21 | public interface RPCServiceHandler {
22 |
23 | void init() throws Exception;
24 |
25 | void destroy() throws Exception;
26 | }
27 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/rpc/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2014 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 | /**
17 | * This package contains class for writing RPC server and client in simple manner.
18 | */
19 | package co.cask.tephra.rpc;
20 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/runtime/ConfigModule.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2014 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.runtime;
18 |
19 | import com.google.inject.AbstractModule;
20 | import org.apache.hadoop.conf.Configuration;
21 |
22 | /**
23 | * Provides Guice bindings for {@link Configuration}.
24 | */
25 | public final class ConfigModule extends AbstractModule {
26 |
27 | private final Configuration configuration;
28 |
29 | public ConfigModule(Configuration configuration) {
30 | this.configuration = configuration;
31 | }
32 |
33 | @Override
34 | protected void configure() {
35 | bind(Configuration.class).toInstance(configuration);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/runtime/DiscoveryModules.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2014 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.runtime;
18 |
19 | import com.google.inject.AbstractModule;
20 | import com.google.inject.Module;
21 | import com.google.inject.PrivateModule;
22 | import com.google.inject.Provides;
23 | import com.google.inject.Singleton;
24 | import org.apache.twill.common.Cancellable;
25 | import org.apache.twill.discovery.Discoverable;
26 | import org.apache.twill.discovery.DiscoveryService;
27 | import org.apache.twill.discovery.DiscoveryServiceClient;
28 | import org.apache.twill.discovery.InMemoryDiscoveryService;
29 | import org.apache.twill.discovery.ServiceDiscovered;
30 | import org.apache.twill.discovery.ZKDiscoveryService;
31 | import org.apache.twill.zookeeper.ZKClientService;
32 |
33 | /**
34 | * Provides access to Google Guice modules for in-memory, single-node, and distributed operation for
35 | * {@link DiscoveryService} and {@link DiscoveryServiceClient}.
36 | */
37 | public final class DiscoveryModules {
38 |
39 | public Module getInMemoryModules() {
40 | return new InMemoryDiscoveryModule();
41 | }
42 |
43 | public Module getSingleNodeModules() {
44 | return new InMemoryDiscoveryModule();
45 | }
46 |
47 | public Module getDistributedModules() {
48 | return new ZKDiscoveryModule();
49 | }
50 |
51 | private static final class InMemoryDiscoveryModule extends AbstractModule {
52 |
53 | // ensuring to be singleton across JVM
54 | private static final InMemoryDiscoveryService IN_MEMORY_DISCOVERY_SERVICE = new InMemoryDiscoveryService();
55 |
56 | @Override
57 | protected void configure() {
58 | InMemoryDiscoveryService discovery = IN_MEMORY_DISCOVERY_SERVICE;
59 | bind(DiscoveryService.class).toInstance(discovery);
60 | bind(DiscoveryServiceClient.class).toInstance(discovery);
61 | }
62 | }
63 |
64 | private static final class ZKDiscoveryModule extends PrivateModule {
65 |
66 | @Override
67 | protected void configure() {
68 | expose(DiscoveryService.class);
69 | expose(DiscoveryServiceClient.class);
70 | }
71 |
72 | @Provides
73 | @Singleton
74 | private ZKDiscoveryService providesZKDiscoveryService(ZKClientService zkClient) {
75 | return new ZKDiscoveryService(zkClient);
76 | }
77 |
78 | @Provides
79 | @Singleton
80 | private DiscoveryService providesDiscoveryService(final ZKClientService zkClient,
81 | final ZKDiscoveryService delegate) {
82 | return new DiscoveryService() {
83 | @Override
84 | public Cancellable register(Discoverable discoverable) {
85 | if (!zkClient.isRunning()) {
86 | zkClient.startAndWait();
87 | }
88 | return delegate.register(discoverable);
89 | }
90 | };
91 | }
92 |
93 | @Provides
94 | @Singleton
95 | private DiscoveryServiceClient providesDiscoveryServiceClient(final ZKClientService zkClient,
96 | final ZKDiscoveryService delegate) {
97 | return new DiscoveryServiceClient() {
98 | @Override
99 | public ServiceDiscovered discover(String s) {
100 | if (!zkClient.isRunning()) {
101 | zkClient.startAndWait();
102 | }
103 | return delegate.discover(s);
104 | }
105 | };
106 | }
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/runtime/TransactionClientModule.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2014 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.runtime;
18 |
19 | import co.cask.tephra.TxConstants;
20 | import co.cask.tephra.distributed.PooledClientProvider;
21 | import co.cask.tephra.distributed.ThreadLocalClientProvider;
22 | import co.cask.tephra.distributed.ThriftClientProvider;
23 | import com.google.inject.AbstractModule;
24 | import com.google.inject.Inject;
25 | import com.google.inject.Provider;
26 | import com.google.inject.Singleton;
27 | import org.apache.hadoop.conf.Configuration;
28 | import org.apache.twill.discovery.DiscoveryServiceClient;
29 |
30 | /**
31 | * Provides Guice binding for {@link co.cask.tephra.distributed.ThriftClientProvider}.
32 | */
33 | public class TransactionClientModule extends AbstractModule {
34 |
35 | @Override
36 | protected void configure() {
37 | bind(ThriftClientProvider.class).toProvider(ThriftClientProviderSupplier.class);
38 | }
39 |
40 | /**
41 | * Provides implementation of {@link co.cask.tephra.distributed.ThriftClientProvider}
42 | * based on configuration.
43 | */
44 | @Singleton
45 | private static final class ThriftClientProviderSupplier implements Provider {
46 |
47 | private final Configuration cConf;
48 | private DiscoveryServiceClient discoveryServiceClient;
49 |
50 | @Inject
51 | ThriftClientProviderSupplier(Configuration cConf) {
52 | this.cConf = cConf;
53 | }
54 |
55 | @Inject(optional = true)
56 | void setDiscoveryServiceClient(DiscoveryServiceClient discoveryServiceClient) {
57 | this.discoveryServiceClient = discoveryServiceClient;
58 | }
59 |
60 | @Override
61 | public ThriftClientProvider get() {
62 | // configure the client provider
63 | String provider = cConf.get(TxConstants.Service.CFG_DATA_TX_CLIENT_PROVIDER,
64 | TxConstants.Service.DEFAULT_DATA_TX_CLIENT_PROVIDER);
65 | ThriftClientProvider clientProvider;
66 | if ("pool".equals(provider)) {
67 | clientProvider = new PooledClientProvider(cConf, discoveryServiceClient);
68 | } else if ("thread-local".equals(provider)) {
69 | clientProvider = new ThreadLocalClientProvider(cConf, discoveryServiceClient);
70 | } else {
71 | String message = "Unknown Transaction Service Client Provider '" + provider + "'.";
72 | throw new IllegalArgumentException(message);
73 | }
74 | return clientProvider;
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/runtime/TransactionDistributedModule.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2014 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.runtime;
18 |
19 | import co.cask.tephra.DefaultTransactionExecutor;
20 | import co.cask.tephra.TransactionExecutor;
21 | import co.cask.tephra.TransactionExecutorFactory;
22 | import co.cask.tephra.TransactionManager;
23 | import co.cask.tephra.TransactionSystemClient;
24 | import co.cask.tephra.distributed.TransactionServiceClient;
25 | import co.cask.tephra.metrics.DefaultMetricsCollector;
26 | import co.cask.tephra.metrics.MetricsCollector;
27 | import co.cask.tephra.persist.HDFSTransactionStateStorage;
28 | import co.cask.tephra.persist.TransactionStateStorage;
29 | import co.cask.tephra.snapshot.SnapshotCodecProvider;
30 | import com.google.inject.AbstractModule;
31 | import com.google.inject.Singleton;
32 | import com.google.inject.assistedinject.FactoryModuleBuilder;
33 | import com.google.inject.name.Names;
34 |
35 | /**
36 | * Guice bindings for running in distributed mode on a cluster.
37 | */
38 | final class TransactionDistributedModule extends AbstractModule {
39 |
40 | @Override
41 | protected void configure() {
42 | bind(SnapshotCodecProvider.class).in(Singleton.class);
43 | bind(TransactionStateStorage.class).annotatedWith(Names.named("persist"))
44 | .to(HDFSTransactionStateStorage.class).in(Singleton.class);
45 | bind(TransactionStateStorage.class).toProvider(TransactionStateStorageProvider.class).in(Singleton.class);
46 |
47 | bind(TransactionManager.class).in(Singleton.class);
48 | bind(TransactionSystemClient.class).to(TransactionServiceClient.class).in(Singleton.class);
49 | bind(MetricsCollector.class).to(DefaultMetricsCollector.class).in(Singleton.class);
50 |
51 | install(new FactoryModuleBuilder()
52 | .implement(TransactionExecutor.class, DefaultTransactionExecutor.class)
53 | .build(TransactionExecutorFactory.class));
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/runtime/TransactionInMemoryModule.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2014 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.runtime;
18 |
19 | import co.cask.tephra.DefaultTransactionExecutor;
20 | import co.cask.tephra.TransactionExecutor;
21 | import co.cask.tephra.TransactionExecutorFactory;
22 | import co.cask.tephra.TransactionManager;
23 | import co.cask.tephra.TransactionSystemClient;
24 | import co.cask.tephra.inmemory.InMemoryTxSystemClient;
25 | import co.cask.tephra.metrics.MetricsCollector;
26 | import co.cask.tephra.metrics.TxMetricsCollector;
27 | import co.cask.tephra.persist.NoOpTransactionStateStorage;
28 | import co.cask.tephra.persist.TransactionStateStorage;
29 | import co.cask.tephra.snapshot.SnapshotCodecProvider;
30 |
31 | import com.google.inject.AbstractModule;
32 | import com.google.inject.Singleton;
33 | import com.google.inject.assistedinject.FactoryModuleBuilder;
34 |
35 | /**
36 | * Guice bindings for running completely in-memory (no persistence). This should only be used for
37 | * test classes, as the transaction state cannot be recovered in the case of a failure.
38 | */
39 | public class TransactionInMemoryModule extends AbstractModule {
40 | public TransactionInMemoryModule() {
41 | }
42 |
43 | @Override
44 | protected void configure() {
45 | bind(SnapshotCodecProvider.class).in(Singleton.class);
46 | bind(TransactionStateStorage.class).to(NoOpTransactionStateStorage.class).in(Singleton.class);
47 | bind(TransactionManager.class).in(Singleton.class);
48 | bind(TransactionSystemClient.class).to(InMemoryTxSystemClient.class).in(Singleton.class);
49 | // no metrics output for in-memory
50 | bind(MetricsCollector.class).to(TxMetricsCollector.class);
51 |
52 | install(new FactoryModuleBuilder()
53 | .implement(TransactionExecutor.class, DefaultTransactionExecutor.class)
54 | .build(TransactionExecutorFactory.class));
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/runtime/TransactionLocalModule.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2014 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.runtime;
18 |
19 | import co.cask.tephra.DefaultTransactionExecutor;
20 | import co.cask.tephra.TransactionExecutor;
21 | import co.cask.tephra.TransactionExecutorFactory;
22 | import co.cask.tephra.TransactionManager;
23 | import co.cask.tephra.TransactionSystemClient;
24 | import co.cask.tephra.inmemory.InMemoryTxSystemClient;
25 | import co.cask.tephra.metrics.DefaultMetricsCollector;
26 | import co.cask.tephra.metrics.MetricsCollector;
27 | import co.cask.tephra.persist.LocalFileTransactionStateStorage;
28 | import co.cask.tephra.persist.TransactionStateStorage;
29 | import co.cask.tephra.snapshot.SnapshotCodecProvider;
30 |
31 | import com.google.inject.AbstractModule;
32 | import com.google.inject.Singleton;
33 | import com.google.inject.assistedinject.FactoryModuleBuilder;
34 | import com.google.inject.name.Names;
35 |
36 | /**
37 | * Guice bindings for running in single-node mode (persistence to local disk and in-memory client).
38 | */
39 | final class TransactionLocalModule extends AbstractModule {
40 |
41 | @Override
42 | protected void configure() {
43 | bind(SnapshotCodecProvider.class).in(Singleton.class);
44 | bind(TransactionStateStorage.class).annotatedWith(Names.named("persist"))
45 | .to(LocalFileTransactionStateStorage.class).in(Singleton.class);
46 | bind(TransactionStateStorage.class).toProvider(TransactionStateStorageProvider.class).in(Singleton.class);
47 |
48 | bind(TransactionManager.class).in(Singleton.class);
49 | bind(TransactionSystemClient.class).to(InMemoryTxSystemClient.class).in(Singleton.class);
50 | bind(MetricsCollector.class).to(DefaultMetricsCollector.class);
51 |
52 | install(new FactoryModuleBuilder()
53 | .implement(TransactionExecutor.class, DefaultTransactionExecutor.class)
54 | .build(TransactionExecutorFactory.class));
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/runtime/TransactionModules.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2014 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.runtime;
18 |
19 | import com.google.inject.Module;
20 |
21 | /**
22 | * Provides access to Google Guice modules for in-memory, single-node, and distributed operation.
23 | */
24 | public class TransactionModules {
25 | public TransactionModules() {
26 | }
27 |
28 | public Module getInMemoryModules() {
29 | return new TransactionInMemoryModule();
30 | }
31 |
32 | public Module getSingleNodeModules() {
33 | return new TransactionLocalModule();
34 | }
35 |
36 | public Module getDistributedModules() {
37 | return new TransactionDistributedModule();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/runtime/TransactionStateStorageProvider.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2014 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 | package co.cask.tephra.runtime;
17 |
18 | import co.cask.tephra.TxConstants;
19 | import co.cask.tephra.persist.NoOpTransactionStateStorage;
20 | import co.cask.tephra.persist.TransactionStateStorage;
21 | import com.google.inject.Inject;
22 | import com.google.inject.Injector;
23 | import com.google.inject.Key;
24 | import com.google.inject.Provider;
25 | import com.google.inject.Singleton;
26 | import com.google.inject.name.Names;
27 | import org.apache.hadoop.conf.Configuration;
28 |
29 | /**
30 | * A provider for {@link TransactionStateStorage} that provides different
31 | * {@link TransactionStateStorage} implementation based on configuration.
32 | */
33 | @Singleton
34 | public final class TransactionStateStorageProvider implements Provider {
35 |
36 | private final Configuration cConf;
37 | private final Injector injector;
38 |
39 | @Inject
40 | TransactionStateStorageProvider(Configuration cConf, Injector injector) {
41 | this.cConf = cConf;
42 | this.injector = injector;
43 | }
44 |
45 | @Override
46 | public TransactionStateStorage get() {
47 | if (cConf.getBoolean(TxConstants.Manager.CFG_DO_PERSIST, true)) {
48 | return injector.getInstance(Key.get(TransactionStateStorage.class, Names.named("persist")));
49 | } else {
50 | return injector.getInstance(NoOpTransactionStateStorage.class);
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/runtime/ZKModule.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2014 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.runtime;
18 |
19 | import co.cask.tephra.TxConstants;
20 | import co.cask.tephra.zookeeper.TephraZKClientService;
21 | import com.google.common.collect.ArrayListMultimap;
22 | import com.google.inject.AbstractModule;
23 | import com.google.inject.Provides;
24 | import com.google.inject.Singleton;
25 | import org.apache.hadoop.conf.Configuration;
26 | import org.apache.twill.zookeeper.RetryStrategies;
27 | import org.apache.twill.zookeeper.ZKClient;
28 | import org.apache.twill.zookeeper.ZKClientService;
29 | import org.apache.twill.zookeeper.ZKClientServices;
30 | import org.apache.twill.zookeeper.ZKClients;
31 |
32 | import java.util.concurrent.TimeUnit;
33 |
34 | /**
35 | * Provides Guice binding to {@link ZKClient} and {@link ZKClientService}.
36 | */
37 | public class ZKModule extends AbstractModule {
38 |
39 | @Override
40 | protected void configure() {
41 | /**
42 | * ZKClientService is provided by the provider method
43 | * {@link #provideZKClientService(org.apache.hadoop.conf.Configuration)}.
44 | */
45 | bind(ZKClient.class).to(ZKClientService.class);
46 | }
47 |
48 | @Provides
49 | @Singleton
50 | private ZKClientService provideZKClientService(Configuration conf) {
51 | String zkStr = conf.get(TxConstants.Service.CFG_DATA_TX_ZOOKEEPER_QUORUM);
52 | if (zkStr == null) {
53 | // Default to HBase one.
54 | zkStr = conf.get(TxConstants.HBase.ZOOKEEPER_QUORUM);
55 | }
56 |
57 | int timeOut = conf.getInt(TxConstants.HBase.ZK_SESSION_TIMEOUT, TxConstants.HBase.DEFAULT_ZK_SESSION_TIMEOUT);
58 | ZKClientService zkClientService = new TephraZKClientService(zkStr, timeOut, null,
59 | ArrayListMultimap.create());
60 | return ZKClientServices.delegate(
61 | ZKClients.reWatchOnExpire(
62 | ZKClients.retryOnFailure(zkClientService, RetryStrategies.exponentialDelay(500, 2000, TimeUnit.MILLISECONDS)
63 | )
64 | )
65 | );
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/snapshot/BinaryDecoder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2014 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.snapshot;
18 |
19 | import java.io.EOFException;
20 | import java.io.IOException;
21 | import java.io.InputStream;
22 |
23 | /**
24 | * An decoder to help read snapshots in binary format.
25 | */
26 | public final class BinaryDecoder {
27 |
28 | private final InputStream input;
29 |
30 | /**
31 | * @param input Stream to read from.
32 | */
33 | public BinaryDecoder(InputStream input) {
34 | this.input = input;
35 | }
36 |
37 | /**
38 | * Read one int from the input.
39 | * @return the read number
40 | * @throws java.io.IOException If there is IO error.
41 | * @throws java.io.EOFException If end of file reached.
42 | */
43 | public int readInt() throws IOException {
44 | int val = 0;
45 | int shift = 0;
46 | int b = readByte();
47 | while (b > 0x7f) {
48 | val ^= (b & 0x7f) << shift;
49 | shift += 7;
50 | b = readByte();
51 | }
52 | val ^= b << shift;
53 | return (val >>> 1) ^ -(val & 1);
54 | }
55 |
56 | /**
57 | * Read one long int from the input.
58 | * @return the read number
59 | * @throws java.io.IOException If there is IO error.
60 | * @throws java.io.EOFException If end of file reached.
61 | */
62 | public long readLong() throws IOException {
63 | long val = 0;
64 | int shift = 0;
65 | int b = readByte();
66 | while (b > 0x7f) {
67 | val ^= (long) (b & 0x7f) << shift;
68 | shift += 7;
69 | b = readByte();
70 | }
71 | val ^= (long) b << shift;
72 | return (val >>> 1) ^ -(val & 1);
73 | }
74 |
75 | /**
76 | * Read a byte sequence. First read an int to indicate how many bytes to read, then that many bytes.
77 | * @return the read bytes as a byte array
78 | * @throws java.io.IOException If there is IO error.
79 | * @throws java.io.EOFException If end of file reached.
80 | */
81 | public byte[] readBytes() throws IOException {
82 | int toRead = readInt();
83 | byte[] bytes = new byte[toRead];
84 | while (toRead > 0) {
85 | int byteRead = input.read(bytes, bytes.length - toRead, toRead);
86 | if (byteRead == -1) {
87 | throw new EOFException();
88 | }
89 | toRead -= byteRead;
90 | }
91 | return bytes;
92 | }
93 |
94 | /**
95 | * Reads a single byte value.
96 | *
97 | * @return The byte value read.
98 | * @throws java.io.IOException If there is IO error.
99 | * @throws java.io.EOFException If end of file reached.
100 | */
101 | private int readByte() throws IOException {
102 | int b = input.read();
103 | if (b == -1) {
104 | throw new EOFException();
105 | }
106 | return b;
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/snapshot/BinaryEncoder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2014 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.snapshot;
18 |
19 | import java.io.IOException;
20 | import java.io.OutputStream;
21 |
22 | /**
23 | * An encoder to help encode snapshots in binary format.
24 | */
25 | public final class BinaryEncoder {
26 |
27 | private final OutputStream output;
28 |
29 | /**
30 | * @param output stream to write to
31 | */
32 | public BinaryEncoder(OutputStream output) {
33 | this.output = output;
34 | }
35 |
36 | /**
37 | * write a single int value.
38 | * @throws java.io.IOException If there is IO error.
39 | */
40 | public BinaryEncoder writeInt(int i) throws IOException {
41 | // Compute the zig-zag value. First double the value and flip the bit if the input is negative.
42 | int val = (i << 1) ^ (i >> 31);
43 |
44 | if ((val & ~0x7f) != 0) {
45 | output.write(0x80 | val & 0x7f);
46 | val >>>= 7;
47 | while (val > 0x7f) {
48 | output.write(0x80 | val & 0x7f);
49 | val >>>= 7;
50 | }
51 | }
52 | output.write(val);
53 |
54 | return this;
55 | }
56 |
57 | /**
58 | * write a single long int value.
59 | * @throws java.io.IOException If there is IO error.
60 | */
61 | public BinaryEncoder writeLong(long l) throws IOException {
62 | // Compute the zig-zag value. First double the value and flip the bit if the input is negative.
63 | long val = (l << 1) ^ (l >> 63);
64 |
65 | if ((val & ~0x7f) != 0) {
66 | output.write((int) (0x80 | val & 0x7f));
67 | val >>>= 7;
68 | while (val > 0x7f) {
69 | output.write((int) (0x80 | val & 0x7f));
70 | val >>>= 7;
71 | }
72 | }
73 | output.write((int) val);
74 |
75 | return this;
76 | }
77 |
78 | /**
79 | * write a sequence of bytes. First writes the number of bytes as an int, then the bytes themselves.
80 | * @throws java.io.IOException If there is IO error.
81 | */
82 | public BinaryEncoder writeBytes(byte[] bytes) throws IOException {
83 | writeLong(bytes.length);
84 | output.write(bytes, 0, bytes.length);
85 | return this;
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/snapshot/SnapshotCodec.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2014 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.snapshot;
18 |
19 | import co.cask.tephra.persist.TransactionSnapshot;
20 | import co.cask.tephra.persist.TransactionVisibilityState;
21 |
22 | import java.io.InputStream;
23 | import java.io.OutputStream;
24 |
25 | /**
26 | * Interface to decode and encode a transaction snapshot. Each codec implements one version of the encoding.
27 | * It need not include the version when encoding the snapshot.
28 | */
29 | public interface SnapshotCodec {
30 |
31 | /**
32 | * @return the version of the encoding implemented by the codec.
33 | */
34 | int getVersion();
35 |
36 | /**
37 | * Encode a transaction snapshot into an output stream.
38 | * @param out the output stream to write to
39 | * @param snapshot the snapshot to encode
40 | */
41 | void encode(OutputStream out, TransactionSnapshot snapshot);
42 |
43 | /**
44 | * Decode a transaction snapshot from an input stream.
45 | * @param in the input stream to read from
46 | * @return the decoded snapshot
47 | */
48 | TransactionSnapshot decode(InputStream in);
49 |
50 | /**
51 | * Decode transaction visibility state from an input stream.
52 | * @param in the input stream to read from
53 | * @return {@link TransactionVisibilityState}
54 | */
55 | TransactionVisibilityState decodeTransactionVisibilityState(InputStream in);
56 | }
57 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/snapshot/SnapshotCodecV2.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2015 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.snapshot;
18 |
19 | import co.cask.tephra.TransactionManager;
20 | import co.cask.tephra.TransactionType;
21 | import com.google.common.collect.Maps;
22 | import it.unimi.dsi.fastutil.longs.LongArrayList;
23 |
24 | import java.io.IOException;
25 | import java.util.Map;
26 | import java.util.NavigableMap;
27 |
28 | /**
29 | * Handles serialization/deserialization of a {@link co.cask.tephra.persist.TransactionSnapshot}
30 | * and its elements to {@code byte[]}.
31 | */
32 | public class SnapshotCodecV2 extends DefaultSnapshotCodec {
33 | @Override
34 | public int getVersion() {
35 | return 2;
36 | }
37 |
38 | @Override
39 | protected void encodeInProgress(BinaryEncoder encoder, Map inProgress)
40 | throws IOException {
41 |
42 | if (!inProgress.isEmpty()) {
43 | encoder.writeInt(inProgress.size());
44 | for (Map.Entry entry : inProgress.entrySet()) {
45 | encoder.writeLong(entry.getKey()); // tx id
46 | encoder.writeLong(entry.getValue().getExpiration());
47 | encoder.writeLong(entry.getValue().getVisibilityUpperBound());
48 | encoder.writeInt(entry.getValue().getType().ordinal());
49 | }
50 | }
51 | encoder.writeInt(0); // zero denotes end of list as per AVRO spec
52 | }
53 |
54 | @Override
55 | protected NavigableMap decodeInProgress(BinaryDecoder decoder)
56 | throws IOException {
57 |
58 | int size = decoder.readInt();
59 | NavigableMap inProgress = Maps.newTreeMap();
60 | while (size != 0) { // zero denotes end of list as per AVRO spec
61 | for (int remaining = size; remaining > 0; --remaining) {
62 | long txId = decoder.readLong();
63 | long expiration = decoder.readLong();
64 | long visibilityUpperBound = decoder.readLong();
65 | int txTypeIdx = decoder.readInt();
66 | TransactionType txType;
67 | try {
68 | txType = TransactionType.values()[txTypeIdx];
69 | } catch (ArrayIndexOutOfBoundsException e) {
70 | throw new IOException("Type enum ordinal value is out of range: " + txTypeIdx);
71 | }
72 | inProgress.put(txId,
73 | new TransactionManager.InProgressTx(visibilityUpperBound, expiration, txType,
74 | new LongArrayList()));
75 | }
76 | size = decoder.readInt();
77 | }
78 | return inProgress;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/snapshot/SnapshotCodecV3.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2015 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.snapshot;
18 |
19 | /**
20 | * Handles serialization/deserialization of a {@link co.cask.tephra.persist.TransactionSnapshot}
21 | * and its elements to {@code byte[]}.
22 | *
23 | * The serialization/deserialization of this codec is the same as that performed by {@link SnapshotCodecV2},
24 | * but a new version number is used to allow easy migration from projects using deprecated codecs with
25 | * conflicting version numbers.
26 | */
27 | public class SnapshotCodecV3 extends SnapshotCodecV2 {
28 | @Override
29 | public int getVersion() {
30 | return 3;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/snapshot/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2014 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | /**
18 | * This package contains interfaces and implementations for encoding and decoding transaction snapshots.
19 | */
20 | package co.cask.tephra.snapshot;
21 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/util/ConfigurationFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2015 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.util;
18 |
19 | import com.google.inject.Provider;
20 | import org.apache.hadoop.conf.Configuration;
21 |
22 | /**
23 | * Provides {@code org.apache.hadoop.conf.Configuration} instances, constructed by the correct version used
24 | * for the runtime.
25 | */
26 | public class ConfigurationFactory implements Provider {
27 | private static class ConfigurationProviderFactory extends HBaseVersionSpecificFactory {
28 | @Override
29 | protected String getHBase96Classname() {
30 | return "co.cask.tephra.hbase96.HBase96ConfigurationProvider";
31 | }
32 |
33 | @Override
34 | protected String getHBase98Classname() {
35 | return "co.cask.tephra.hbase98.HBase98ConfigurationProvider";
36 | }
37 |
38 | @Override
39 | protected String getHBase10Classname() {
40 | return "co.cask.tephra.hbase10.HBase10ConfigurationProvider";
41 | }
42 |
43 | @Override
44 | protected String getHBase11Classname() {
45 | return "co.cask.tephra.hbase11.HBase11ConfigurationProvider";
46 | }
47 |
48 | @Override
49 | protected String getHBase10CDHClassname() {
50 | return "co.cask.tephra.hbase10cdh.HBase10ConfigurationProvider";
51 | }
52 | }
53 |
54 | private final ConfigurationProvider provider = new ConfigurationProviderFactory().get();
55 |
56 | /**
57 | * Returns a new {@link org.apache.hadoop.conf.Configuration} instance from the HBase version-specific factory.
58 | */
59 | @Override
60 | public Configuration get() {
61 | return provider.get();
62 | }
63 |
64 | /**
65 | * Returns a new {@link org.apache.hadoop.conf.Configuration} instance from the HBase version-specific factory.
66 | *
67 | * @param baseConf additional configuration properties to merge on to the classpath configuration
68 | * @return the merged configuration
69 | */
70 | public Configuration get(Configuration baseConf) {
71 | return provider.get(baseConf);
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/util/ConfigurationProvider.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2015 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.util;
18 |
19 | import com.google.inject.Provider;
20 | import org.apache.hadoop.conf.Configuration;
21 |
22 | /**
23 | * Provides {@code Configuration} instances, constructed by the HBase version on which we are running.
24 | */
25 | public abstract class ConfigurationProvider implements Provider {
26 | @Override
27 | public abstract Configuration get();
28 |
29 | public abstract Configuration get(Configuration baseConf);
30 | }
31 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/util/HBaseVersionSpecificFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2015-2016 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.util;
18 |
19 | import com.google.inject.Provider;
20 | import com.google.inject.ProvisionException;
21 | import org.apache.twill.internal.utils.Instances;
22 |
23 | /**
24 | * Common class factory behavior for classes which need specific implementations depending on HBase versions.
25 | * Specific factories can subclass this class and simply plug in the class names for their implementations.
26 | *
27 | * @param Version specific class provided by this factory.
28 | */
29 | public abstract class HBaseVersionSpecificFactory implements Provider {
30 | @Override
31 | public T get() {
32 | T instance = null;
33 | try {
34 | switch (HBaseVersion.get()) {
35 | case HBASE_94:
36 | throw new ProvisionException("HBase 0.94 is no longer supported. Please upgrade to HBase 0.96 or newer.");
37 | case HBASE_96:
38 | instance = createInstance(getHBase96Classname());
39 | break;
40 | case HBASE_98:
41 | instance = createInstance(getHBase98Classname());
42 | break;
43 | case HBASE_10:
44 | instance = createInstance(getHBase10Classname());
45 | break;
46 | case HBASE_10_CDH:
47 | instance = createInstance(getHBase10CDHClassname());
48 | break;
49 | case HBASE_11:
50 | case HBASE_12_CDH:
51 | instance = createInstance(getHBase11Classname());
52 | break;
53 | case UNKNOWN:
54 | throw new ProvisionException("Unknown HBase version: " + HBaseVersion.getVersionString());
55 | }
56 | } catch (ClassNotFoundException cnfe) {
57 | throw new ProvisionException(cnfe.getMessage(), cnfe);
58 | }
59 | return instance;
60 | }
61 |
62 | protected T createInstance(String className) throws ClassNotFoundException {
63 | Class clz = Class.forName(className);
64 | return (T) Instances.newInstance(clz);
65 | }
66 |
67 | protected abstract String getHBase96Classname();
68 | protected abstract String getHBase98Classname();
69 | protected abstract String getHBase10Classname();
70 | protected abstract String getHBase10CDHClassname();
71 | protected abstract String getHBase11Classname();
72 | }
73 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/visibility/DefaultFenceWait.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2016 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.visibility;
18 |
19 | import co.cask.tephra.TransactionContext;
20 | import co.cask.tephra.TransactionFailureException;
21 | import com.google.common.base.Stopwatch;
22 | import org.slf4j.Logger;
23 | import org.slf4j.LoggerFactory;
24 |
25 | import java.util.concurrent.TimeUnit;
26 | import java.util.concurrent.TimeoutException;
27 |
28 | /**
29 | * Default implementation of {@link FenceWait}.
30 | */
31 | public class DefaultFenceWait implements FenceWait {
32 | private static final Logger LOG = LoggerFactory.getLogger(DefaultFenceWait.class);
33 |
34 | private final TransactionContext txContext;
35 |
36 | DefaultFenceWait(TransactionContext txContext) {
37 | this.txContext = txContext;
38 | }
39 |
40 | @Override
41 | public void await(long timeout, TimeUnit timeUnit)
42 | throws TransactionFailureException, InterruptedException, TimeoutException {
43 | Stopwatch stopwatch = new Stopwatch();
44 | stopwatch.start();
45 | long sleepTimeMicros = timeUnit.toMicros(timeout) / 10;
46 | // Have sleep time to be within 1 microsecond and 500 milliseconds
47 | sleepTimeMicros = Math.max(Math.min(sleepTimeMicros, 500 * 1000), 1);
48 | while (stopwatch.elapsedTime(timeUnit) < timeout) {
49 | txContext.start();
50 | try {
51 | txContext.finish();
52 | return;
53 | } catch (TransactionFailureException e) {
54 | LOG.error("Got exception waiting for fence. Sleeping for {} microseconds", sleepTimeMicros, e);
55 | txContext.abort();
56 | TimeUnit.MICROSECONDS.sleep(sleepTimeMicros);
57 | }
58 | }
59 | throw new TimeoutException("Timeout waiting for fence");
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/visibility/FenceWait.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2016 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.visibility;
18 |
19 | import co.cask.tephra.TransactionFailureException;
20 |
21 | import java.util.concurrent.TimeUnit;
22 | import java.util.concurrent.TimeoutException;
23 |
24 | /**
25 | * Used by a writer to wait on a fence so that changes are visible to all readers with in-progress transactions.
26 | */
27 | public interface FenceWait {
28 | /**
29 | * Waits until the fence is complete, or till the timeout specified. The fence wait transaction will get re-tried
30 | * several times until the timeout.
31 | *
32 | *
33 | * If a fence wait times out then it means there are still some readers with in-progress transactions that have not
34 | * seen the change. In this case the wait will have to be retried using the same FenceWait object.
35 | *
36 | * @param timeout Maximum time to wait
37 | * @param timeUnit {@link TimeUnit} for timeout and sleepTime
38 | * @throws TransactionFailureException when not able to start fence wait transaction
39 | * @throws InterruptedException on any interrupt
40 | * @throws TimeoutException when timeout is reached
41 | */
42 | void await(long timeout, TimeUnit timeUnit)
43 | throws TransactionFailureException, InterruptedException, TimeoutException;
44 | }
45 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/visibility/ReadFence.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2015 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.visibility;
18 |
19 | import co.cask.tephra.Transaction;
20 | import co.cask.tephra.TransactionAware;
21 | import com.google.common.primitives.Bytes;
22 | import com.google.common.primitives.Longs;
23 |
24 | import java.util.Collection;
25 | import java.util.Collections;
26 |
27 | /**
28 | * Implementation of {@link VisibilityFence} used by reader.
29 | */
30 | class ReadFence implements TransactionAware {
31 | private final byte[] fenceId;
32 | private Transaction tx;
33 |
34 | public ReadFence(byte[] fenceId) {
35 | this.fenceId = fenceId;
36 | }
37 |
38 | @Override
39 | public void startTx(Transaction tx) {
40 | this.tx = tx;
41 | }
42 |
43 | @Override
44 | public void updateTx(Transaction tx) {
45 | // Fences only need original transaction
46 | }
47 |
48 | @Override
49 | public Collection getTxChanges() {
50 | if (tx == null) {
51 | throw new IllegalStateException("Transaction has not started yet");
52 | }
53 | return Collections.singleton(Bytes.concat(fenceId, Longs.toByteArray(tx.getTransactionId())));
54 | }
55 |
56 | @Override
57 | public boolean commitTx() throws Exception {
58 | // Nothing to persist
59 | return true;
60 | }
61 |
62 | @Override
63 | public void postTxCommit() {
64 | tx = null;
65 | }
66 |
67 | @Override
68 | public boolean rollbackTx() throws Exception {
69 | // Nothing to rollback
70 | return true;
71 | }
72 |
73 | @Override
74 | public String getTransactionAwareName() {
75 | return getClass().getSimpleName();
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/visibility/WriteFence.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2015 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.visibility;
18 |
19 | import co.cask.tephra.Transaction;
20 | import co.cask.tephra.TransactionAware;
21 | import com.google.common.primitives.Bytes;
22 | import com.google.common.primitives.Longs;
23 | import com.google.common.primitives.UnsignedBytes;
24 |
25 | import java.util.Collection;
26 | import java.util.TreeSet;
27 |
28 | /**
29 | * Implementation used by {@link FenceWait} to wait for a {@link VisibilityFence}.
30 | */
31 | class WriteFence implements TransactionAware {
32 | private final byte[] fenceId;
33 | private Transaction tx;
34 | private Collection inProgressChanges;
35 |
36 | public WriteFence(byte[] fenceId) {
37 | this.fenceId = fenceId;
38 | }
39 |
40 | @Override
41 | public void startTx(Transaction tx) {
42 | this.tx = tx;
43 | if (inProgressChanges == null) {
44 | inProgressChanges = new TreeSet<>(UnsignedBytes.lexicographicalComparator());
45 | for (long inProgressTx : tx.getInProgress()) {
46 | inProgressChanges.add(Bytes.concat(fenceId, Longs.toByteArray(inProgressTx)));
47 | }
48 | }
49 | }
50 |
51 | @Override
52 | public void updateTx(Transaction tx) {
53 | // Fences only need original transaction
54 | }
55 |
56 | @Override
57 | public Collection getTxChanges() {
58 | if (inProgressChanges == null || tx == null) {
59 | throw new IllegalStateException("Transaction has not started yet");
60 | }
61 | return inProgressChanges;
62 | }
63 |
64 | @Override
65 | public boolean commitTx() throws Exception {
66 | // Nothing to persist
67 | return true;
68 | }
69 |
70 | @Override
71 | public void postTxCommit() {
72 | tx = null;
73 | }
74 |
75 | @Override
76 | public boolean rollbackTx() throws Exception {
77 | // Nothing to rollback
78 | return true;
79 | }
80 |
81 | @Override
82 | public String getTransactionAwareName() {
83 | return getClass().getSimpleName();
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/zookeeper/BasicACLData.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2016 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.zookeeper;
18 |
19 | import org.apache.twill.zookeeper.ACLData;
20 | import org.apache.zookeeper.data.ACL;
21 | import org.apache.zookeeper.data.Stat;
22 |
23 | import java.util.List;
24 |
25 | /**
26 | * A straightforward implementation of {@link ACLData}.
27 | */
28 | final class BasicACLData implements ACLData {
29 |
30 | private final List acl;
31 | private final Stat stat;
32 |
33 | BasicACLData(List acl, Stat stat) {
34 | this.acl = acl;
35 | this.stat = stat;
36 | }
37 |
38 | @Override
39 | public List getACL() {
40 | return acl;
41 | }
42 |
43 | @Override
44 | public Stat getStat() {
45 | return stat;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/zookeeper/BasicNodeChildren.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2016 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.zookeeper;
18 |
19 | import com.google.common.base.Objects;
20 | import org.apache.twill.zookeeper.NodeChildren;
21 | import org.apache.zookeeper.data.Stat;
22 |
23 | import java.util.List;
24 |
25 | /**
26 | * Implementation of the {@link NodeChildren}.
27 | */
28 | final class BasicNodeChildren implements NodeChildren {
29 |
30 | private final Stat stat;
31 | private final List children;
32 |
33 | BasicNodeChildren(List children, Stat stat) {
34 | this.stat = stat;
35 | this.children = children;
36 | }
37 |
38 | @Override
39 | public Stat getStat() {
40 | return stat;
41 | }
42 |
43 | @Override
44 | public List getChildren() {
45 | return children;
46 | }
47 |
48 | @Override
49 | public boolean equals(Object o) {
50 | if (this == o) {
51 | return true;
52 | }
53 | if (o == null || !(o instanceof NodeChildren)) {
54 | return false;
55 | }
56 |
57 | NodeChildren that = (NodeChildren) o;
58 | return stat.equals(that.getStat()) && children.equals(that.getChildren());
59 | }
60 |
61 | @Override
62 | public int hashCode() {
63 | return Objects.hashCode(children, stat);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/tephra-core/src/main/java/co/cask/tephra/zookeeper/BasicNodeData.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2016 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.zookeeper;
18 |
19 | import com.google.common.base.Objects;
20 | import org.apache.twill.zookeeper.NodeData;
21 | import org.apache.zookeeper.data.Stat;
22 |
23 | import java.util.Arrays;
24 |
25 | /**
26 | * A straightforward implementation for {@link NodeData}.
27 | */
28 | final class BasicNodeData implements NodeData {
29 |
30 | private final byte[] data;
31 | private final Stat stat;
32 |
33 | BasicNodeData(byte[] data, Stat stat) {
34 | this.data = data;
35 | this.stat = stat;
36 | }
37 |
38 | @Override
39 | public Stat getStat() {
40 | return stat;
41 | }
42 |
43 | @Override
44 | public byte[] getData() {
45 | return data;
46 | }
47 |
48 | @Override
49 | public boolean equals(Object o) {
50 | if (this == o) {
51 | return true;
52 | }
53 | if (o == null || !(o instanceof NodeData)) {
54 | return false;
55 | }
56 |
57 | BasicNodeData that = (BasicNodeData) o;
58 |
59 | return stat.equals(that.getStat()) && Arrays.equals(data, that.getData());
60 | }
61 |
62 | @Override
63 | public int hashCode() {
64 | return Objects.hashCode(data, stat);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/tephra-core/src/main/thrift/README:
--------------------------------------------------------------------------------
1 | # Copyright © 2014 Cask Data, Inc.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 | # use this file except in compliance with the License. You may obtain a copy of
5 | # the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 | # License for the specific language governing permissions and limitations under
13 | # the License.
14 |
15 | To generate thrift classes:
16 | thrift --gen java --out ../java/ transaction.thrift
17 |
--------------------------------------------------------------------------------
/tephra-core/src/main/thrift/transaction.thrift:
--------------------------------------------------------------------------------
1 | # Copyright © 2012-2014 Cask Data, Inc.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 | # use this file except in compliance with the License. You may obtain a copy of
5 | # the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 | # License for the specific language governing permissions and limitations under
13 | # the License.
14 |
15 | namespace java co.cask.tephra.distributed.thrift
16 |
17 | enum TTransactionType {
18 | SHORT = 1,
19 | LONG = 2
20 | }
21 |
22 | enum TVisibilityLevel {
23 | SNAPSHOT = 1,
24 | SNAPSHOT_EXCLUDE_CURRENT = 2,
25 | SNAPSHOT_ALL = 3
26 | }
27 |
28 | struct TTransaction {
29 | 1: i64 transactionId,
30 | 2: i64 readPointer,
31 | 3: list invalids,
32 | 4: list inProgress,
33 | 5: i64 firstShort,
34 | 6: TTransactionType type,
35 | 7: i64 writePointer,
36 | 8: list checkpointWritePointers,
37 | 9: TVisibilityLevel visibilityLevel
38 | }
39 |
40 | exception TTransactionNotInProgressException {
41 | 1: string message
42 | }
43 |
44 | exception TTransactionCouldNotTakeSnapshotException {
45 | 1: string message
46 | }
47 |
48 | exception TInvalidTruncateTimeException {
49 | 1: string message
50 | }
51 |
52 | # workaround for THRIFT-1474
53 | struct TBoolean {
54 | 1: bool value
55 | }
56 |
57 | service TTransactionServer {
58 | // temporary tx2 stuff
59 | TTransaction startLong(),
60 | TTransaction startShort(),
61 | TTransaction startShortTimeout(1: i32 timeout),
62 | TBoolean canCommitTx(1: TTransaction tx, 2: set changes) throws (1:TTransactionNotInProgressException e),
63 | TBoolean commitTx(1: TTransaction tx) throws (1:TTransactionNotInProgressException e),
64 | void abortTx(1: TTransaction tx),
65 | bool invalidateTx(1: i64 tx),
66 | binary getSnapshot() throws (1:TTransactionCouldNotTakeSnapshotException e),
67 | void resetState(),
68 | string status(),
69 | TBoolean truncateInvalidTx(1: set txns),
70 | TBoolean truncateInvalidTxBefore(1: i64 time) throws (1: TInvalidTruncateTimeException e),
71 | i32 invalidTxSize(),
72 | TTransaction checkpoint(1: TTransaction tx) throws (1: TTransactionNotInProgressException e),
73 | }
74 |
--------------------------------------------------------------------------------
/tephra-core/src/test/java/co/cask/tephra/TransactionServiceMainTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2014 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra;
18 |
19 | import co.cask.tephra.distributed.TransactionServiceClient;
20 | import com.google.common.base.Throwables;
21 | import org.apache.hadoop.conf.Configuration;
22 | import org.apache.twill.internal.zookeeper.InMemoryZKServer;
23 | import org.junit.ClassRule;
24 | import org.junit.Test;
25 | import org.junit.rules.TemporaryFolder;
26 |
27 | import java.util.concurrent.CountDownLatch;
28 |
29 | /**
30 | * Test for verifying TransactionServiceMain works correctly.
31 | */
32 | public class TransactionServiceMainTest {
33 |
34 | @ClassRule
35 | public static TemporaryFolder tmpFolder = new TemporaryFolder();
36 |
37 | @Test
38 | public void testClientServer() throws Exception {
39 | // Simply start a transaction server and connect to it with the client.
40 | InMemoryZKServer zkServer = InMemoryZKServer.builder().setDataDir(tmpFolder.newFolder()).build();
41 | zkServer.startAndWait();
42 |
43 | try {
44 | Configuration conf = new Configuration();
45 | conf.set(TxConstants.Service.CFG_DATA_TX_ZOOKEEPER_QUORUM, zkServer.getConnectionStr());
46 | conf.set(TxConstants.Manager.CFG_TX_SNAPSHOT_DIR, tmpFolder.newFolder().getAbsolutePath());
47 |
48 | final TransactionServiceMain main = new TransactionServiceMain(conf);
49 | final CountDownLatch latch = new CountDownLatch(1);
50 | Thread t = new Thread() {
51 | @Override
52 | public void run() {
53 | try {
54 | main.start();
55 | latch.countDown();
56 | } catch (Exception e) {
57 | throw Throwables.propagate(e);
58 | }
59 | }
60 | };
61 |
62 | try {
63 | t.start();
64 | // Wait for service to startup
65 | latch.await();
66 | TransactionServiceClient.doMain(true, conf);
67 | } finally {
68 | main.stop();
69 | t.join();
70 | }
71 | } finally {
72 | zkServer.stopAndWait();
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/tephra-core/src/test/java/co/cask/tephra/hbase/AbstractTransactionVisibilityFilterTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2014 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.hbase;
18 |
19 | import co.cask.tephra.TransactionManager;
20 | import co.cask.tephra.TxConstants;
21 | import co.cask.tephra.util.ConfigurationFactory;
22 | import com.google.common.collect.Lists;
23 | import org.apache.hadoop.conf.Configuration;
24 | import org.junit.After;
25 | import org.junit.Before;
26 |
27 | import java.util.List;
28 |
29 | /**
30 | * Common test class for TransactionVisibilityFilter implementations.
31 | */
32 | public abstract class AbstractTransactionVisibilityFilterTest {
33 |
34 | protected static final byte[] FAM = new byte[] {'f'};
35 | protected static final byte[] FAM2 = new byte[] {'f', '2'};
36 | protected static final byte[] FAM3 = new byte[] {'f', '3'};
37 | protected static final byte[] COL = new byte[] {'c'};
38 | protected static final List EMPTY_CHANGESET = Lists.newArrayListWithCapacity(0);
39 |
40 | protected TransactionManager txManager;
41 |
42 | @Before
43 | public void setup() throws Exception {
44 | Configuration conf = new ConfigurationFactory().get();
45 | conf.unset(TxConstants.Persist.CFG_TX_SNAPHOT_CODEC_CLASSES);
46 | txManager = new TransactionManager(conf);
47 | txManager.startAndWait();
48 | }
49 |
50 | @After
51 | public void tearDown() throws Exception {
52 | txManager.stopAndWait();
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/tephra-core/src/test/java/co/cask/tephra/persist/HDFSTransactionStateStorageTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2012-2014 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.persist;
18 |
19 | import co.cask.tephra.TxConstants;
20 | import co.cask.tephra.metrics.TxMetricsCollector;
21 | import co.cask.tephra.snapshot.SnapshotCodecProvider;
22 | import org.apache.hadoop.conf.Configuration;
23 | import org.apache.hadoop.hdfs.MiniDFSCluster;
24 | import org.junit.AfterClass;
25 | import org.junit.BeforeClass;
26 | import org.junit.ClassRule;
27 | import org.junit.rules.TemporaryFolder;
28 |
29 | import java.io.IOException;
30 |
31 |
32 | /**
33 | * Tests persistence of transaction snapshots and write-ahead logs to HDFS storage, using the
34 | * {@link HDFSTransactionStateStorage} and {@link HDFSTransactionLog} implementations.
35 | */
36 | public class HDFSTransactionStateStorageTest extends AbstractTransactionStateStorageTest {
37 |
38 | @ClassRule
39 | public static TemporaryFolder tmpFolder = new TemporaryFolder();
40 |
41 | private static MiniDFSCluster dfsCluster;
42 | private static Configuration conf;
43 |
44 | @BeforeClass
45 | public static void setupBeforeClass() throws Exception {
46 | Configuration hConf = new Configuration();
47 | hConf.set(MiniDFSCluster.HDFS_MINIDFS_BASEDIR, tmpFolder.newFolder().getAbsolutePath());
48 |
49 | dfsCluster = new MiniDFSCluster.Builder(hConf).numDataNodes(1).build();
50 | conf = new Configuration(dfsCluster.getFileSystem().getConf());
51 | }
52 |
53 | @AfterClass
54 | public static void tearDownAfterClass() throws Exception {
55 | dfsCluster.shutdown();
56 | }
57 |
58 | @Override
59 | protected Configuration getConfiguration(String testName) throws IOException {
60 | // tests should use the current user for HDFS
61 | conf.unset(TxConstants.Manager.CFG_TX_HDFS_USER);
62 | conf.set(TxConstants.Manager.CFG_TX_SNAPSHOT_DIR, tmpFolder.newFolder().getAbsolutePath());
63 | return conf;
64 | }
65 |
66 | @Override
67 | protected AbstractTransactionStateStorage getStorage(Configuration conf) {
68 | return new HDFSTransactionStateStorage(conf, new SnapshotCodecProvider(conf), new TxMetricsCollector());
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/tephra-core/src/test/java/co/cask/tephra/util/AbstractConfigurationProviderTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2015 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.util;
18 |
19 | import org.apache.hadoop.conf.Configuration;
20 | import org.junit.Test;
21 |
22 | import static org.junit.Assert.assertEquals;
23 | import static org.junit.Assert.assertNotNull;
24 |
25 | /**
26 | *
27 | */
28 | public abstract class AbstractConfigurationProviderTest {
29 | @Test
30 | public void testVersionFactory() {
31 | HBaseVersion.Version foundVersion = HBaseVersion.get();
32 | assertEquals(getExpectedVersion(), foundVersion);
33 | }
34 |
35 | protected abstract HBaseVersion.Version getExpectedVersion();
36 |
37 | @Test
38 | public void testConfigurationProvider() {
39 | Configuration conf = new Configuration();
40 | conf.set("foo", "bar");
41 | Configuration newConf = new ConfigurationFactory().get(conf);
42 | assertNotNull(newConf);
43 | assertEquals("bar", newConf.get("foo"));
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/tephra-core/src/test/java/co/cask/tephra/util/TransactionEditUtil.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2015 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.util;
18 |
19 | import co.cask.tephra.ChangeId;
20 | import co.cask.tephra.TransactionType;
21 | import co.cask.tephra.persist.TransactionEdit;
22 | import com.google.common.collect.Lists;
23 | import com.google.common.collect.Sets;
24 |
25 | import java.util.List;
26 | import java.util.Random;
27 | import java.util.Set;
28 |
29 | /**
30 | * Util class for {@link TransactionEdit} related tests.
31 | */
32 | public final class TransactionEditUtil {
33 | private static Random random = new Random();
34 |
35 | /**
36 | * Generates a number of semi-random {@link TransactionEdit} instances.
37 | * These are just randomly selected from the possible states, so would not necessarily reflect a real-world
38 | * distribution.
39 | *
40 | * @param numEntries how many entries to generate in the returned list.
41 | * @return a list of randomly generated transaction log edits.
42 | */
43 | public static List createRandomEdits(int numEntries) {
44 | List edits = Lists.newArrayListWithCapacity(numEntries);
45 | for (int i = 0; i < numEntries; i++) {
46 | TransactionEdit.State nextType = TransactionEdit.State.values()[random.nextInt(6)];
47 | long writePointer = Math.abs(random.nextLong());
48 | switch (nextType) {
49 | case INPROGRESS:
50 | edits.add(
51 | TransactionEdit.createStarted(writePointer, writePointer - 1,
52 | System.currentTimeMillis() + 300000L, TransactionType.SHORT));
53 | break;
54 | case COMMITTING:
55 | edits.add(TransactionEdit.createCommitting(writePointer, generateChangeSet(10)));
56 | break;
57 | case COMMITTED:
58 | edits.add(TransactionEdit.createCommitted(writePointer, generateChangeSet(10), writePointer + 1,
59 | random.nextBoolean()));
60 | break;
61 | case INVALID:
62 | edits.add(TransactionEdit.createInvalid(writePointer));
63 | break;
64 | case ABORTED:
65 | edits.add(TransactionEdit.createAborted(writePointer, TransactionType.SHORT, null));
66 | break;
67 | case MOVE_WATERMARK:
68 | edits.add(TransactionEdit.createMoveWatermark(writePointer));
69 | break;
70 | }
71 | }
72 | return edits;
73 | }
74 |
75 | private static Set generateChangeSet(int numEntries) {
76 | Set changes = Sets.newHashSet();
77 | for (int i = 0; i < numEntries; i++) {
78 | byte[] bytes = new byte[8];
79 | random.nextBytes(bytes);
80 | changes.add(new ChangeId(bytes));
81 | }
82 | return changes;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/tephra-core/src/test/java/co/cask/tephra/util/TxUtilsTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2015 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.util;
18 |
19 | import co.cask.tephra.Transaction;
20 | import org.junit.Test;
21 |
22 | import static org.junit.Assert.assertEquals;
23 |
24 | /**
25 | * Test cases for {@link TxUtils} utility methods.
26 | */
27 | public class TxUtilsTest {
28 | @Test
29 | public void testMaxVisibleTimestamp() {
30 | // make sure we don't overflow with MAX_VALUE write pointer
31 | assertEquals(Long.MAX_VALUE, TxUtils.getMaxVisibleTimestamp(Transaction.ALL_VISIBLE_LATEST));
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/tephra-examples/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 | tephra
21 | co.cask.tephra
22 | 0.7.2-SNAPSHOT
23 |
24 | 4.0.0
25 |
26 | tephra-examples
27 | Tephra Examples
28 |
29 |
30 |
31 | 2.6.0
32 | 1.0.0-cdh5.4.2
33 |
34 |
35 |
36 |
37 | cloudera
38 | https://repository.cloudera.com/artifactory/cloudera-repos/
39 |
40 |
41 |
42 |
43 |
44 |
45 | co.cask.tephra
46 | tephra-api
47 | ${project.version}
48 |
49 |
50 | co.cask.tephra
51 | tephra-core
52 | ${project.version}
53 |
54 |
55 | co.cask.tephra
56 | tephra-hbase-compat-1.0-cdh
57 | ${project.version}
58 |
59 |
60 | org.apache.hbase
61 | hbase-common
62 | ${hbase10cdh.version}
63 | provided
64 |
65 |
66 | org.apache.hbase
67 | hbase-client
68 | ${hbase10cdh.version}
69 | provided
70 |
71 |
72 | org.apache.hbase
73 | hbase-protocol
74 | ${hbase10cdh.version}
75 | provided
76 |
77 |
78 | org.apache.hbase
79 | hbase-server
80 | ${hbase10cdh.version}
81 | provided
82 |
83 |
84 |
85 |
86 | co.cask.tephra
87 | tephra-core
88 | ${project.version}
89 | test-jar
90 | test
91 |
92 |
93 | junit
94 | junit
95 |
96 |
97 | org.apache.hbase
98 | hbase-server
99 | ${hbase10cdh.version}
100 | test-jar
101 | test
102 |
103 |
104 | org.apache.hbase
105 | hbase-testing-util
106 | ${hbase10cdh.version}
107 | test
108 |
109 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/tephra-examples/src/main/java/co/cask/tephra/examples/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2015 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | /**
18 | * This package contains example applications for Tephra designed to illustrate sample Tephra usage
19 | * and provide out-of-the-box sample applications which can be run to test cluster functionality.
20 | *
21 | * Currently the following applications are provided:
22 | *
23 | *
24 | * - BalanceBooks - this application runs a specified number of concurrent clients in separate
25 | * threads, which perform transactions to make withdrawals from each other's accounts and deposits to their own
26 | * accounts. At the end of the test, the total value of all account balances is verified to be equal to zero,
27 | * which confirms that transactional integrity was not violated.
28 | *
29 | *
30 | *
31 | *
32 | *
33 | * Note that, for simplicity, the examples package is currently hardcoded to compile against a specific HBase
34 | * version (currently 1.0-cdh). In the future, we should provide Maven profiles to allow compiling the examples
35 | * against each of the supported HBase versions.
36 | *
37 | */
38 | package co.cask.tephra.examples;
39 |
--------------------------------------------------------------------------------
/tephra-hbase-compat-0.96/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 | tephra
21 | co.cask.tephra
22 | 0.7.2-SNAPSHOT
23 |
24 | 4.0.0
25 |
26 | tephra-hbase-compat-0.96
27 | Tephra HBase 0.96 Compatibility
28 | Tephra Transaction System HBase 0.96 Compatibility Module
29 |
30 |
31 |
32 | co.cask.tephra
33 | tephra-api
34 | ${project.version}
35 |
36 |
37 | co.cask.tephra
38 | tephra-core
39 | ${project.version}
40 |
41 |
42 | org.apache.hbase
43 | hbase
44 |
45 |
46 |
47 |
48 | org.apache.hbase
49 | hbase-common
50 | ${hbase96.version}
51 | provided
52 |
53 |
54 | org.apache.hbase
55 | hbase-client
56 | ${hbase96.version}
57 | provided
58 |
59 |
60 | org.apache.hbase
61 | hbase-protocol
62 | ${hbase96.version}
63 | provided
64 |
65 |
66 | org.apache.hbase
67 | hbase-server
68 | ${hbase96.version}
69 | provided
70 |
71 |
72 |
73 |
74 | co.cask.tephra
75 | tephra-core
76 | ${project.version}
77 | test-jar
78 | test
79 |
80 |
81 | junit
82 | junit
83 |
84 |
85 | org.apache.hbase
86 | hbase-testing-util
87 | ${hbase96.version}
88 | test
89 |
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/tephra-hbase-compat-0.96/src/main/java/co/cask/tephra/hbase96/HBase96ConfigurationProvider.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2015 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.hbase96;
18 |
19 | import co.cask.tephra.util.ConfigurationProvider;
20 | import org.apache.hadoop.conf.Configuration;
21 | import org.apache.hadoop.hbase.HBaseConfiguration;
22 |
23 | /**
24 | * HBase 0.96 version of {@link co.cask.tephra.util.ConfigurationProvider}.
25 | */
26 | public class HBase96ConfigurationProvider extends ConfigurationProvider {
27 | @Override
28 | public Configuration get() {
29 | return HBaseConfiguration.create();
30 | }
31 |
32 | @Override
33 | public Configuration get(Configuration baseConf) {
34 | return HBaseConfiguration.create(baseConf);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/tephra-hbase-compat-0.96/src/main/java/co/cask/tephra/hbase96/coprocessor/TransactionFilters.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2016 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.hbase96.coprocessor;
18 |
19 | import co.cask.tephra.Transaction;
20 | import org.apache.hadoop.hbase.filter.Filter;
21 | import org.apache.hadoop.hbase.regionserver.ScanType;
22 |
23 | import java.util.Map;
24 | import javax.annotation.Nullable;
25 |
26 | /**
27 | * Factory class for providing {@link Filter} instances.
28 | */
29 | public class TransactionFilters {
30 | /**
31 | * Creates a new {@link org.apache.hadoop.hbase.filter.Filter} for returning data only from visible transactions.
32 | *
33 | * @param tx the current transaction to apply. Only data visible to this transaction will be returned.
34 | * @param ttlByFamily map of time-to-live (TTL) (in milliseconds) by column family name
35 | * @param allowEmptyValues if {@code true} cells with empty {@code byte[]} values will be returned, if {@code false}
36 | * these will be interpreted as "delete" markers and the column will be filtered out
37 | * @param scanType the type of scan operation being performed
38 | */
39 | public static Filter getVisibilityFilter(Transaction tx, Map ttlByFamily, boolean allowEmptyValues,
40 | ScanType scanType) {
41 | return new CellSkipFilter(new TransactionVisibilityFilter(tx, ttlByFamily, allowEmptyValues, scanType, null));
42 | }
43 |
44 | /**
45 | * Creates a new {@link org.apache.hadoop.hbase.filter.Filter} for returning data only from visible transactions.
46 | *
47 | * @param tx the current transaction to apply. Only data visible to this transaction will be returned.
48 | * @param ttlByFamily map of time-to-live (TTL) (in milliseconds) by column family name
49 | * @param allowEmptyValues if {@code true} cells with empty {@code byte[]} values will be returned, if {@code false}
50 | * these will be interpreted as "delete" markers and the column will be filtered out
51 | * @param scanType the type of scan operation being performed
52 | * @param cellFilter if non-null, this filter will be applied to all cells visible to the current transaction, by
53 | * calling {@link Filter#filterKeyValue(org.apache.hadoop.hbase.Cell)}. If null, then
54 | * {@link Filter.ReturnCode#INCLUDE_AND_NEXT_COL} will be returned instead.
55 | */
56 | public static Filter getVisibilityFilter(Transaction tx, Map ttlByFamily, boolean allowEmptyValues,
57 | ScanType scanType, @Nullable Filter cellFilter) {
58 | return new CellSkipFilter(new TransactionVisibilityFilter(tx, ttlByFamily, allowEmptyValues, scanType, cellFilter));
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/tephra-hbase-compat-0.96/src/test/java/co/cask/tephra/hbase96/HBase96ConfigurationProviderTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2015 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.hbase96;
18 |
19 | import co.cask.tephra.util.AbstractConfigurationProviderTest;
20 | import co.cask.tephra.util.HBaseVersion;
21 |
22 | /**
23 | * Test for HBase 0.96 version specific behavior.
24 | */
25 | public class HBase96ConfigurationProviderTest extends AbstractConfigurationProviderTest {
26 | @Override
27 | protected HBaseVersion.Version getExpectedVersion() {
28 | return HBaseVersion.Version.HBASE_96;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tephra-hbase-compat-0.98/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 | tephra
21 | co.cask.tephra
22 | 0.7.2-SNAPSHOT
23 |
24 | 4.0.0
25 |
26 | tephra-hbase-compat-0.98
27 | Tephra HBase 0.98 Compatibility
28 |
29 |
30 |
31 | co.cask.tephra
32 | tephra-api
33 | ${project.version}
34 |
35 |
36 | co.cask.tephra
37 | tephra-core
38 | ${project.version}
39 |
40 |
41 | org.apache.hbase
42 | hbase
43 |
44 |
45 |
46 |
47 | org.apache.hbase
48 | hbase-common
49 | ${hbase98.version}
50 | provided
51 |
52 |
53 | org.apache.hbase
54 | hbase-client
55 | ${hbase98.version}
56 | provided
57 |
58 |
59 | org.apache.hbase
60 | hbase-protocol
61 | ${hbase98.version}
62 | provided
63 |
64 |
65 | org.apache.hbase
66 | hbase-server
67 | ${hbase98.version}
68 | provided
69 |
70 |
71 |
72 |
73 | co.cask.tephra
74 | tephra-core
75 | ${project.version}
76 | test-jar
77 | test
78 |
79 |
80 | junit
81 | junit
82 |
83 |
84 | org.apache.hbase
85 | hbase-testing-util
86 | ${hbase98.version}
87 | test
88 |
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/tephra-hbase-compat-0.98/src/main/java/co/cask/tephra/hbase98/HBase98ConfigurationProvider.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2015 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.hbase98;
18 |
19 | import co.cask.tephra.util.ConfigurationProvider;
20 | import org.apache.hadoop.conf.Configuration;
21 | import org.apache.hadoop.hbase.HBaseConfiguration;
22 |
23 | /**
24 | * HBase 0.98 version of {@link co.cask.tephra.util.ConfigurationProvider}.
25 | */
26 | public class HBase98ConfigurationProvider extends ConfigurationProvider {
27 | @Override
28 | public Configuration get() {
29 | return HBaseConfiguration.create();
30 | }
31 |
32 | @Override
33 | public Configuration get(Configuration baseConf) {
34 | return HBaseConfiguration.create(baseConf);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/tephra-hbase-compat-0.98/src/main/java/co/cask/tephra/hbase98/coprocessor/TransactionFilters.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2016 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.hbase98.coprocessor;
18 |
19 | import co.cask.tephra.Transaction;
20 | import org.apache.hadoop.hbase.filter.Filter;
21 | import org.apache.hadoop.hbase.regionserver.ScanType;
22 |
23 | import java.util.Map;
24 | import javax.annotation.Nullable;
25 |
26 | /**
27 | * Factory class for providing {@link Filter} instances.
28 | */
29 | public class TransactionFilters {
30 | /**
31 | * Creates a new {@link org.apache.hadoop.hbase.filter.Filter} for returning data only from visible transactions.
32 | *
33 | * @param tx the current transaction to apply. Only data visible to this transaction will be returned.
34 | * @param ttlByFamily map of time-to-live (TTL) (in milliseconds) by column family name
35 | * @param allowEmptyValues if {@code true} cells with empty {@code byte[]} values will be returned, if {@code false}
36 | * these will be interpreted as "delete" markers and the column will be filtered out
37 | * @param scanType the type of scan operation being performed
38 | */
39 | public static Filter getVisibilityFilter(Transaction tx, Map ttlByFamily, boolean allowEmptyValues,
40 | ScanType scanType) {
41 | return new CellSkipFilter(new TransactionVisibilityFilter(tx, ttlByFamily, allowEmptyValues, scanType, null));
42 | }
43 |
44 | /**
45 | * Creates a new {@link org.apache.hadoop.hbase.filter.Filter} for returning data only from visible transactions.
46 | *
47 | * @param tx the current transaction to apply. Only data visible to this transaction will be returned.
48 | * @param ttlByFamily map of time-to-live (TTL) (in milliseconds) by column family name
49 | * @param allowEmptyValues if {@code true} cells with empty {@code byte[]} values will be returned, if {@code false}
50 | * these will be interpreted as "delete" markers and the column will be filtered out
51 | * @param scanType the type of scan operation being performed
52 | * @param cellFilter if non-null, this filter will be applied to all cells visible to the current transaction, by
53 | * calling {@link Filter#filterKeyValue(org.apache.hadoop.hbase.Cell)}. If null, then
54 | * {@link Filter.ReturnCode#INCLUDE_AND_NEXT_COL} will be returned instead.
55 | */
56 | public static Filter getVisibilityFilter(Transaction tx, Map ttlByFamily, boolean allowEmptyValues,
57 | ScanType scanType, @Nullable Filter cellFilter) {
58 | return new CellSkipFilter(new TransactionVisibilityFilter(tx, ttlByFamily, allowEmptyValues, scanType, cellFilter));
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/tephra-hbase-compat-0.98/src/test/java/co/cask/tephra/hbase98/HBase98ConfigurationProviderTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2015 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.hbase98;
18 |
19 | import co.cask.tephra.util.AbstractConfigurationProviderTest;
20 | import co.cask.tephra.util.HBaseVersion;
21 |
22 | /**
23 | * Test for HBase 0.98 version specific behavior.
24 | */
25 | public class HBase98ConfigurationProviderTest extends AbstractConfigurationProviderTest {
26 | @Override
27 | protected HBaseVersion.Version getExpectedVersion() {
28 | return HBaseVersion.Version.HBASE_98;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tephra-hbase-compat-1.0-cdh/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 | tephra
21 | co.cask.tephra
22 | 0.7.2-SNAPSHOT
23 |
24 | 4.0.0
25 |
26 | tephra-hbase-compat-1.0-cdh
27 | Tephra HBase 1.0 Compatibility for CDH
28 |
29 |
30 |
31 | 2.6.0
32 |
33 |
34 |
35 |
36 | cloudera
37 | https://repository.cloudera.com/artifactory/cloudera-repos/
38 |
39 |
40 |
41 |
42 |
43 |
44 | co.cask.tephra
45 | tephra-api
46 | ${project.version}
47 |
48 |
49 | co.cask.tephra
50 | tephra-core
51 | ${project.version}
52 |
53 |
54 | org.apache.hbase
55 | hbase-common
56 | ${hbase10cdh.version}
57 | provided
58 |
59 |
60 | org.apache.hbase
61 | hbase-client
62 | ${hbase10cdh.version}
63 | provided
64 |
65 |
66 | org.apache.hbase
67 | hbase-protocol
68 | ${hbase10cdh.version}
69 | provided
70 |
71 |
72 | org.apache.hbase
73 | hbase-server
74 | ${hbase10cdh.version}
75 | provided
76 |
77 |
78 |
79 |
80 | co.cask.tephra
81 | tephra-core
82 | ${project.version}
83 | test-jar
84 | test
85 |
86 |
87 | junit
88 | junit
89 |
90 |
91 | org.apache.hbase
92 | hbase-server
93 | ${hbase10cdh.version}
94 | test-jar
95 | test
96 |
97 |
98 | org.apache.hbase
99 | hbase-testing-util
100 | ${hbase10cdh.version}
101 | test
102 |
103 |
104 |
105 |
106 |
--------------------------------------------------------------------------------
/tephra-hbase-compat-1.0-cdh/src/main/java/co/cask/tephra/hbase10cdh/HBase10ConfigurationProvider.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2015 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.hbase10cdh;
18 |
19 | import co.cask.tephra.util.ConfigurationProvider;
20 | import org.apache.hadoop.conf.Configuration;
21 | import org.apache.hadoop.hbase.HBaseConfiguration;
22 |
23 | /**
24 | * HBase 1.0 version of {@link co.cask.tephra.util.ConfigurationProvider}.
25 | */
26 | public class HBase10ConfigurationProvider extends ConfigurationProvider {
27 | @Override
28 | public Configuration get() {
29 | return HBaseConfiguration.create();
30 | }
31 |
32 | @Override
33 | public Configuration get(Configuration baseConf) {
34 | return HBaseConfiguration.create(baseConf);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/tephra-hbase-compat-1.0-cdh/src/main/java/co/cask/tephra/hbase10cdh/coprocessor/TransactionFilters.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2016 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.hbase10cdh.coprocessor;
18 |
19 | import co.cask.tephra.Transaction;
20 | import org.apache.hadoop.hbase.filter.Filter;
21 | import org.apache.hadoop.hbase.regionserver.ScanType;
22 |
23 | import java.util.Map;
24 | import javax.annotation.Nullable;
25 |
26 | /**
27 | * Factory class for providing {@link Filter} instances.
28 | */
29 | public class TransactionFilters {
30 | /**
31 | * Creates a new {@link org.apache.hadoop.hbase.filter.Filter} for returning data only from visible transactions.
32 | *
33 | * @param tx the current transaction to apply. Only data visible to this transaction will be returned.
34 | * @param ttlByFamily map of time-to-live (TTL) (in milliseconds) by column family name
35 | * @param allowEmptyValues if {@code true} cells with empty {@code byte[]} values will be returned, if {@code false}
36 | * these will be interpreted as "delete" markers and the column will be filtered out
37 | * @param scanType the type of scan operation being performed
38 | */
39 | public static Filter getVisibilityFilter(Transaction tx, Map ttlByFamily, boolean allowEmptyValues,
40 | ScanType scanType) {
41 | return new CellSkipFilter(new TransactionVisibilityFilter(tx, ttlByFamily, allowEmptyValues, scanType, null));
42 | }
43 |
44 | /**
45 | * Creates a new {@link org.apache.hadoop.hbase.filter.Filter} for returning data only from visible transactions.
46 | *
47 | * @param tx the current transaction to apply. Only data visible to this transaction will be returned.
48 | * @param ttlByFamily map of time-to-live (TTL) (in milliseconds) by column family name
49 | * @param allowEmptyValues if {@code true} cells with empty {@code byte[]} values will be returned, if {@code false}
50 | * these will be interpreted as "delete" markers and the column will be filtered out
51 | * @param scanType the type of scan operation being performed
52 | * @param cellFilter if non-null, this filter will be applied to all cells visible to the current transaction, by
53 | * calling {@link Filter#filterKeyValue(org.apache.hadoop.hbase.Cell)}. If null, then
54 | * {@link Filter.ReturnCode#INCLUDE_AND_NEXT_COL} will be returned instead.
55 | */
56 | public static Filter getVisibilityFilter(Transaction tx, Map ttlByFamily, boolean allowEmptyValues,
57 | ScanType scanType, @Nullable Filter cellFilter) {
58 | return new CellSkipFilter(new TransactionVisibilityFilter(tx, ttlByFamily, allowEmptyValues, scanType, cellFilter));
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/tephra-hbase-compat-1.0-cdh/src/test/java/co/cask/tephra/hbase10cdh/HBase10ConfigurationProviderTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2015 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.hbase10cdh;
18 |
19 | import co.cask.tephra.util.AbstractConfigurationProviderTest;
20 | import co.cask.tephra.util.HBaseVersion;
21 |
22 | /**
23 | * Test for HBase 1.0 (CDH) version specific behavior.
24 | */
25 | public class HBase10ConfigurationProviderTest extends AbstractConfigurationProviderTest {
26 | @Override
27 | protected HBaseVersion.Version getExpectedVersion() {
28 | return HBaseVersion.Version.HBASE_10_CDH;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tephra-hbase-compat-1.0/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 | tephra
21 | co.cask.tephra
22 | 0.7.2-SNAPSHOT
23 |
24 | 4.0.0
25 |
26 | tephra-hbase-compat-1.0
27 | Tephra HBase 1.0 Compatibility
28 |
29 |
30 |
31 | 2.4.0
32 |
33 |
34 |
35 |
36 | co.cask.tephra
37 | tephra-api
38 | ${project.version}
39 |
40 |
41 | co.cask.tephra
42 | tephra-core
43 | ${project.version}
44 |
45 |
46 | org.apache.hbase
47 | hbase
48 |
49 |
50 |
51 |
52 | org.apache.hbase
53 | hbase-common
54 | ${hbase10.version}
55 | provided
56 |
57 |
58 | org.apache.hbase
59 | hbase-client
60 | ${hbase10.version}
61 | provided
62 |
63 |
64 | org.apache.hbase
65 | hbase-protocol
66 | ${hbase10.version}
67 | provided
68 |
69 |
70 | org.apache.hbase
71 | hbase-server
72 | ${hbase10.version}
73 | provided
74 |
75 |
76 |
77 |
78 | co.cask.tephra
79 | tephra-core
80 | ${project.version}
81 | test-jar
82 | test
83 |
84 |
85 | junit
86 | junit
87 |
88 |
89 | org.apache.hbase
90 | hbase-server
91 | ${hbase10.version}
92 | test-jar
93 | test
94 |
95 |
96 | org.apache.hbase
97 | hbase-testing-util
98 | ${hbase10.version}
99 | test
100 |
101 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/tephra-hbase-compat-1.0/src/main/java/co/cask/tephra/hbase10/HBase10ConfigurationProvider.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2015 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.hbase10;
18 |
19 | import co.cask.tephra.util.ConfigurationProvider;
20 | import org.apache.hadoop.conf.Configuration;
21 | import org.apache.hadoop.hbase.HBaseConfiguration;
22 |
23 | /**
24 | * HBase 1.0 version of {@link co.cask.tephra.util.ConfigurationProvider}.
25 | */
26 | public class HBase10ConfigurationProvider extends ConfigurationProvider {
27 | @Override
28 | public Configuration get() {
29 | return HBaseConfiguration.create();
30 | }
31 |
32 | @Override
33 | public Configuration get(Configuration baseConf) {
34 | return HBaseConfiguration.create(baseConf);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/tephra-hbase-compat-1.0/src/main/java/co/cask/tephra/hbase10/coprocessor/TransactionFilters.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2016 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.hbase10.coprocessor;
18 |
19 | import co.cask.tephra.Transaction;
20 | import org.apache.hadoop.hbase.filter.Filter;
21 | import org.apache.hadoop.hbase.regionserver.ScanType;
22 |
23 | import java.util.Map;
24 | import javax.annotation.Nullable;
25 |
26 | /**
27 | * Factory class for providing {@link Filter} instances.
28 | */
29 | public class TransactionFilters {
30 | /**
31 | * Creates a new {@link org.apache.hadoop.hbase.filter.Filter} for returning data only from visible transactions.
32 | *
33 | * @param tx the current transaction to apply. Only data visible to this transaction will be returned.
34 | * @param ttlByFamily map of time-to-live (TTL) (in milliseconds) by column family name
35 | * @param allowEmptyValues if {@code true} cells with empty {@code byte[]} values will be returned, if {@code false}
36 | * these will be interpreted as "delete" markers and the column will be filtered out
37 | * @param scanType the type of scan operation being performed
38 | */
39 | public static Filter getVisibilityFilter(Transaction tx, Map ttlByFamily, boolean allowEmptyValues,
40 | ScanType scanType) {
41 | return new CellSkipFilter(new TransactionVisibilityFilter(tx, ttlByFamily, allowEmptyValues, scanType, null));
42 | }
43 |
44 | /**
45 | * Creates a new {@link org.apache.hadoop.hbase.filter.Filter} for returning data only from visible transactions.
46 | *
47 | * @param tx the current transaction to apply. Only data visible to this transaction will be returned.
48 | * @param ttlByFamily map of time-to-live (TTL) (in milliseconds) by column family name
49 | * @param allowEmptyValues if {@code true} cells with empty {@code byte[]} values will be returned, if {@code false}
50 | * these will be interpreted as "delete" markers and the column will be filtered out
51 | * @param scanType the type of scan operation being performed
52 | * @param cellFilter if non-null, this filter will be applied to all cells visible to the current transaction, by
53 | * calling {@link Filter#filterKeyValue(org.apache.hadoop.hbase.Cell)}. If null, then
54 | * {@link Filter.ReturnCode#INCLUDE_AND_NEXT_COL} will be returned instead.
55 | */
56 | public static Filter getVisibilityFilter(Transaction tx, Map ttlByFamily, boolean allowEmptyValues,
57 | ScanType scanType, @Nullable Filter cellFilter) {
58 | return new CellSkipFilter(new TransactionVisibilityFilter(tx, ttlByFamily, allowEmptyValues, scanType, cellFilter));
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/tephra-hbase-compat-1.0/src/test/java/co/cask/tephra/hbase10/HBase10ConfigurationProviderTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2015 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.hbase10;
18 |
19 | import co.cask.tephra.util.AbstractConfigurationProviderTest;
20 | import co.cask.tephra.util.HBaseVersion;
21 |
22 | /**
23 | * Test for HBase 1.0 version specific behavior.
24 | */
25 | public class HBase10ConfigurationProviderTest extends AbstractConfigurationProviderTest {
26 | @Override
27 | protected HBaseVersion.Version getExpectedVersion() {
28 | return HBaseVersion.Version.HBASE_10;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tephra-hbase-compat-1.1/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 | tephra
21 | co.cask.tephra
22 | 0.7.2-SNAPSHOT
23 |
24 | 4.0.0
25 |
26 | tephra-hbase-compat-1.1
27 | Tephra HBase 1.1 Compatibility
28 |
29 |
30 |
31 | 2.4.0
32 |
33 |
34 |
35 |
36 | co.cask.tephra
37 | tephra-api
38 | ${project.version}
39 |
40 |
41 | co.cask.tephra
42 | tephra-core
43 | ${project.version}
44 |
45 |
46 | org.apache.hbase
47 | hbase
48 |
49 |
50 |
51 |
52 | org.apache.hbase
53 | hbase-common
54 | ${hbase11.version}
55 | provided
56 |
57 |
58 | org.apache.hbase
59 | hbase-client
60 | ${hbase11.version}
61 | provided
62 |
63 |
64 | org.apache.hbase
65 | hbase-protocol
66 | ${hbase11.version}
67 | provided
68 |
69 |
70 | org.apache.hbase
71 | hbase-server
72 | ${hbase11.version}
73 | provided
74 |
75 |
76 |
77 |
78 | co.cask.tephra
79 | tephra-core
80 | ${project.version}
81 | test-jar
82 | test
83 |
84 |
85 | junit
86 | junit
87 |
88 |
89 | org.apache.hbase
90 | hbase-server
91 | ${hbase11.version}
92 | test-jar
93 | test
94 |
95 |
96 | org.apache.hbase
97 | hbase-testing-util
98 | ${hbase11.version}
99 | test
100 |
101 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/tephra-hbase-compat-1.1/src/main/java/co/cask/tephra/hbase11/HBase11ConfigurationProvider.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2015 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.hbase11;
18 |
19 | import co.cask.tephra.util.ConfigurationProvider;
20 | import org.apache.hadoop.conf.Configuration;
21 | import org.apache.hadoop.hbase.HBaseConfiguration;
22 |
23 | /**
24 | * HBase 1.1 version of {@link ConfigurationProvider}.
25 | */
26 | public class HBase11ConfigurationProvider extends ConfigurationProvider {
27 | @Override
28 | public Configuration get() {
29 | return HBaseConfiguration.create();
30 | }
31 |
32 | @Override
33 | public Configuration get(Configuration baseConf) {
34 | return HBaseConfiguration.create(baseConf);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/tephra-hbase-compat-1.1/src/main/java/co/cask/tephra/hbase11/coprocessor/TransactionFilters.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2016 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.hbase11.coprocessor;
18 |
19 | import co.cask.tephra.Transaction;
20 | import org.apache.hadoop.hbase.filter.Filter;
21 | import org.apache.hadoop.hbase.regionserver.ScanType;
22 |
23 | import java.util.Map;
24 | import javax.annotation.Nullable;
25 |
26 | /**
27 | * Factory class for providing {@link Filter} instances.
28 | */
29 | public class TransactionFilters {
30 | /**
31 | * Creates a new {@link org.apache.hadoop.hbase.filter.Filter} for returning data only from visible transactions.
32 | *
33 | * @param tx the current transaction to apply. Only data visible to this transaction will be returned.
34 | * @param ttlByFamily map of time-to-live (TTL) (in milliseconds) by column family name
35 | * @param allowEmptyValues if {@code true} cells with empty {@code byte[]} values will be returned, if {@code false}
36 | * these will be interpreted as "delete" markers and the column will be filtered out
37 | * @param scanType the type of scan operation being performed
38 | */
39 | public static Filter getVisibilityFilter(Transaction tx, Map ttlByFamily, boolean allowEmptyValues,
40 | ScanType scanType) {
41 | return new CellSkipFilter(new TransactionVisibilityFilter(tx, ttlByFamily, allowEmptyValues, scanType, null));
42 | }
43 |
44 | /**
45 | * Creates a new {@link org.apache.hadoop.hbase.filter.Filter} for returning data only from visible transactions.
46 | *
47 | * @param tx the current transaction to apply. Only data visible to this transaction will be returned.
48 | * @param ttlByFamily map of time-to-live (TTL) (in milliseconds) by column family name
49 | * @param allowEmptyValues if {@code true} cells with empty {@code byte[]} values will be returned, if {@code false}
50 | * these will be interpreted as "delete" markers and the column will be filtered out
51 | * @param scanType the type of scan operation being performed
52 | * @param cellFilter if non-null, this filter will be applied to all cells visible to the current transaction, by
53 | * calling {@link Filter#filterKeyValue(org.apache.hadoop.hbase.Cell)}. If null, then
54 | * {@link Filter.ReturnCode#INCLUDE_AND_NEXT_COL} will be returned instead.
55 | */
56 | public static Filter getVisibilityFilter(Transaction tx, Map ttlByFamily, boolean allowEmptyValues,
57 | ScanType scanType, @Nullable Filter cellFilter) {
58 | return new CellSkipFilter(new TransactionVisibilityFilter(tx, ttlByFamily, allowEmptyValues, scanType, cellFilter));
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/tephra-hbase-compat-1.1/src/test/java/co/cask/tephra/hbase11/HBase11ConfigurationProviderTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2015 Cask Data, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package co.cask.tephra.hbase11;
18 |
19 | import co.cask.tephra.util.AbstractConfigurationProviderTest;
20 | import co.cask.tephra.util.HBaseVersion;
21 |
22 | /**
23 | * Test for HBase 1.1 version specific behavior.
24 | */
25 | public class HBase11ConfigurationProviderTest extends AbstractConfigurationProviderTest {
26 | @Override
27 | protected HBaseVersion.Version getExpectedVersion() {
28 | return HBaseVersion.Version.HBASE_11;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------