├── .gitignore
├── README.md
├── dropwizard-extra-curator
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── com
│ │ └── datasift
│ │ └── dropwizard
│ │ └── curator
│ │ ├── CuratorFactory.java
│ │ ├── ManagedCuratorFramework.java
│ │ ├── ensemble
│ │ ├── DropwizardConfiguredEnsembleProvider.java
│ │ └── DropwizardConfiguredZooKeeperFactory.java
│ │ └── health
│ │ └── CuratorHealthCheck.java
│ └── test
│ ├── java
│ └── com
│ │ └── datasift
│ │ └── dropwizard
│ │ └── curator
│ │ ├── CuratorFactoryTest.java
│ │ └── ensemble
│ │ └── DynamicZooKeeperConfigurationTest.java
│ └── resources
│ └── yaml
│ └── curator.yaml
├── dropwizard-extra-hbase
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── com
│ │ └── datasift
│ │ └── dropwizard
│ │ └── hbase
│ │ ├── BoundedHBaseClient.java
│ │ ├── HBaseClient.java
│ │ ├── HBaseClientFactory.java
│ │ ├── HBaseClientProxy.java
│ │ ├── HBaseHealthCheck.java
│ │ ├── InstrumentedHBaseClient.java
│ │ ├── ManagedHBaseClient.java
│ │ ├── metrics
│ │ ├── HBaseInstrumentation.java
│ │ └── ScannerInstrumentation.java
│ │ ├── scanner
│ │ ├── BoundedRowScanner.java
│ │ ├── InstrumentedRowScanner.java
│ │ ├── RowScanner.java
│ │ └── RowScannerProxy.java
│ │ └── util
│ │ ├── PermitReleasingCallback.java
│ │ └── TimerStoppingCallback.java
│ └── test
│ ├── java
│ └── com
│ │ └── datasift
│ │ └── dropwizard
│ │ └── hbase
│ │ ├── BoundedHBaseClientTest.java
│ │ ├── HBaseClientFactoryTest.java
│ │ ├── HBaseClientProxyTest.java
│ │ ├── InstrumentedHBaseClientTest.java
│ │ └── util
│ │ ├── PermitReleasingCallbackTest.java
│ │ └── TimerStoppingCallbackTest.java
│ └── resources
│ └── yaml
│ └── hbase.yml
├── dropwizard-extra-kafka
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── com
│ │ └── datasift
│ │ └── dropwizard
│ │ └── kafka
│ │ ├── KafkaClientFactory.java
│ │ ├── KafkaConsumerFactory.java
│ │ ├── KafkaProducerFactory.java
│ │ ├── consumer
│ │ ├── KafkaConsumer.java
│ │ ├── KafkaConsumerHealthCheck.java
│ │ ├── MessageProcessor.java
│ │ ├── StreamProcessor.java
│ │ └── SynchronousConsumer.java
│ │ ├── producer
│ │ ├── InstrumentedProducer.java
│ │ ├── KafkaProducer.java
│ │ ├── ManagedProducer.java
│ │ └── ProxyProducer.java
│ │ ├── serializer
│ │ ├── JacksonDecoder.java
│ │ └── JacksonEncoder.java
│ │ └── util
│ │ └── Compression.java
│ └── test
│ ├── java
│ └── com
│ │ └── datasift
│ │ └── dropwizard
│ │ └── kafka
│ │ ├── KafkaConsumerFactoryTest.java
│ │ ├── KafkaProducerFactoryTest.java
│ │ ├── consumer
│ │ └── SynchronousConsumerTest.java
│ │ └── util
│ │ └── CompressionTest.java
│ └── resources
│ └── yaml
│ ├── consumer.yaml
│ └── producer.yaml
├── dropwizard-extra-kafka7
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── com
│ │ └── datasift
│ │ └── dropwizard
│ │ └── kafka
│ │ ├── KafkaClientFactory.java
│ │ ├── KafkaConsumerFactory.java
│ │ ├── KafkaProducerFactory.java
│ │ ├── consumer
│ │ ├── KafkaConsumer.java
│ │ ├── KafkaConsumerHealthCheck.java
│ │ ├── MessageProcessor.java
│ │ ├── StreamProcessor.java
│ │ └── SynchronousConsumer.java
│ │ ├── producer
│ │ ├── InstrumentedProducer.java
│ │ ├── KafkaProducer.java
│ │ ├── ManagedProducer.java
│ │ └── ProxyProducer.java
│ │ ├── serializer
│ │ ├── JacksonDecoder.java
│ │ └── JacksonEncoder.java
│ │ └── util
│ │ └── Compression.java
│ └── test
│ ├── java
│ └── com
│ │ └── datasift
│ │ └── dropwizard
│ │ └── kafka
│ │ ├── KafkaConsumerFactoryTest.java
│ │ ├── KafkaProducerFactoryTest.java
│ │ ├── consumer
│ │ └── SynchronousConsumerTest.java
│ │ └── util
│ │ └── CompressionTest.java
│ └── resources
│ └── yaml
│ ├── consumer.yaml
│ └── producer.yaml
├── dropwizard-extra-util
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── com
│ │ └── datasift
│ │ └── dropwizard
│ │ ├── health
│ │ └── SocketHealthCheck.java
│ │ └── util
│ │ ├── Classes.java
│ │ ├── Exceptions.java
│ │ └── Primitives.java
│ └── test
│ └── java
│ └── com
│ └── datasift
│ └── dropwizard
│ └── util
│ └── ClassesTest.java
├── dropwizard-extra-zookeeper
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── com
│ │ └── datasift
│ │ └── dropwizard
│ │ └── zookeeper
│ │ ├── ManagedZooKeeper.java
│ │ ├── ZooKeeperFactory.java
│ │ └── health
│ │ └── ZooKeeperHealthCheck.java
│ └── test
│ ├── java
│ └── com
│ │ └── datasift
│ │ └── dropwizard
│ │ └── zookeeper
│ │ └── ZooKeeperFactoryTest.java
│ └── resources
│ └── yaml
│ └── zookeeper.yaml
├── pom.xml
└── src
└── site
└── site.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | target/
3 | *.iml
4 | *.ipr
5 | release.properties
6 | *atlassian*
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Dropwizard Extra
2 | ================
3 |
4 | *For those not content with the already excellent [Dropwizard](http://github.com/codahale/dropwizard)*
5 |
6 | This is a bunch of additional abstractions and utilities that extend Dropwizard.
7 |
8 | To keep the nightmare of transitive dependencies at bay, there are several
9 | modules:
10 |
11 | * [dropwizard-extra-core](http://github.com/datasift/dropwizard-extra/tree/develop/dropwizard-extra-core)
12 | contains several simple but useful abstractions with no real external dependencies.
13 | * [dropwizard-extra-curator](http://github.com/datasift/dropwizard-extra/tree/develop/dropwizard-extra-curator)
14 | integrates [NetFlix's Curator](http://github.com/netflix/curator) high-level [ZooKeeper](http://zookeeper.apache.org)
15 | client with Dropwizard for working with ZooKeeper directly.
16 | * [dropwizard-extra-hbase](http://github.com/datasift/dropwizard-extra/tree/develop/dropwizard-extra-hbase)
17 | integrates [StumbleUpon's asynchbase](http://github.com/stumbleupon/asynchbase) with Dropwizard for
18 | working with [HBase](http://hbase.apache.org)
19 | * [dropwizard-extra-kafka](http://github.com/datasift/dropwizard-extra/tree/develop/dropwizard-extra-kafka) for
20 | working with [Apache Kafka](http://incubator.apache.org/kafka).
21 | * [dropwizard-extra-scala](http://github.com/datasift/dropwizard-extra/tree/develop/dropwizard-extra-scala) provides
22 | Scala integrations for Dropwizard and a more idiomatic Scala API to the other Dropwizard Extra modules.
23 | * [dropwizard-extra-zookeeper](http://github.com/datasift/dropwizard-extra/tree/develop/dropwizard-extra-zookeeper)
24 | integrates the low-level [Apache ZooKeeper](http://zookeeper.apache.org/) client in to Dropwizards life-cycle. If
25 | you're using ZooKeeper directly in your application, it's strongly recommended that you use the higher-level
26 | [dropwizard-extra-curator](http://github.com/datasift/dropwizard-extra/tree/develop/dropwizard-extra-curator)
27 | instead.
28 |
29 | Full documentation for the latest release is available on the
30 | [generated Maven Site](http://datasift.github.com/dropwizard-extra/).
31 |
32 | Usage
33 | -----
34 |
35 | Dropwizard Extra is published to [Maven Central](http://search.maven.org/#search|ga|1|g%3Acom.datasift.dropwizard),
36 | so just add the module(s) you wish to use to your `pom.xml`:
37 |
38 | ```xml
39 |
40 |
41 | com.datasift.dropwizard
42 | dropwizard-extra-core
43 | 0.6.2-1
44 |
45 |
46 | ```
47 |
48 | Or whatever you need to do to make SBT/Gradle/Ivy/Buildr/etc. happy.
49 |
50 | Versioning
51 | ----------
52 |
53 | Dropwizard Extra is versioned in lock-step with upstream Dropwizard.
54 |
55 | All Dropwizard Extra modules have a transitive dependency on the version of Dropwizard they're built against. The
56 | versioning scheme for Dropwizard Extra is as follows:
57 |
58 | ${dropwizard.version}-{dw-extra.release.number}
59 |
60 | The "release number" signifies the differences between two builds of Dropwizard Extra that are built against the same
61 | upstream version of Dropwizard.
62 |
63 | The practical consequence of this is that an upgrade of Dropwizard Extra will often require an upgrade of Dropwizard
64 | itself, however, this is always clearly indicated by the version number of Dropwizard Extra itself.
65 |
66 | License
67 | -------
68 |
69 | This software is licensed under the [Apache License Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
70 |
71 |
--------------------------------------------------------------------------------
/dropwizard-extra-curator/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 4.0.0
5 |
6 | com.datasift.dropwizard
7 | dropwizard-extra
8 | 0.7.1-2-SNAPSHOT
9 | ../pom.xml
10 |
11 |
12 | dropwizard-extra-curator
13 |
14 | Dropwizard Extra Curator
15 | http://datasift.github.com/dropwizard-extra/dropwizard-extra-curator
16 |
17 | Dropwizard integration for working with ZooKeeper using Netflix's Curator client.
18 |
19 |
20 |
21 |
22 | io.dropwizard
23 | dropwizard-core
24 |
25 |
26 | com.datasift.dropwizard
27 | dropwizard-extra-zookeeper
28 | ${project.version}
29 |
30 |
31 | org.apache.curator
32 | curator-framework
33 | 2.0.1-incubating
34 |
35 |
36 |
37 | com.google.guava
38 | guava
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | maven-javadoc-plugin
48 |
49 |
50 | http://netflix.github.com/curator/doc/
51 | http://zookeeper.apache.org/doc/current/api/
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/dropwizard-extra-curator/src/main/java/com/datasift/dropwizard/curator/CuratorFactory.java:
--------------------------------------------------------------------------------
1 | package com.datasift.dropwizard.curator;
2 |
3 | import io.dropwizard.util.Duration;
4 | import com.datasift.dropwizard.curator.ensemble.DropwizardConfiguredEnsembleProvider;
5 | import com.datasift.dropwizard.curator.ensemble.DropwizardConfiguredZooKeeperFactory;
6 | import com.datasift.dropwizard.curator.health.CuratorHealthCheck;
7 | import com.datasift.dropwizard.zookeeper.ZooKeeperFactory;
8 | import com.fasterxml.jackson.annotation.JsonProperty;
9 | import com.google.common.util.concurrent.ThreadFactoryBuilder;
10 | import org.apache.curator.RetryPolicy;
11 | import org.apache.curator.framework.CuratorFramework;
12 | import org.apache.curator.framework.CuratorFrameworkFactory;
13 | import io.dropwizard.setup.Environment;
14 | import org.apache.curator.framework.api.CompressionProvider;
15 | import org.apache.curator.framework.imps.GzipCompressionProvider;
16 | import org.apache.curator.retry.ExponentialBackoffRetry;
17 |
18 | import javax.validation.Valid;
19 | import javax.validation.constraints.Min;
20 | import javax.validation.constraints.NotNull;
21 |
22 | /**
23 | * A factory for creating and managing {@link CuratorFramework} instances.
24 | *
25 | * The resulting {@link CuratorFramework} will have its lifecycle managed by the {@link Environment}
26 | * and will have {@link com.codahale.metrics.health.HealthCheck}s installed for the underlying ZooKeeper
27 | * ensemble.
28 | *
29 | * @see CuratorFramework
30 | */
31 | public class CuratorFactory {
32 |
33 | private static final String DEFAULT_NAME = "curator-default";
34 |
35 | /**
36 | * An enumeration of the available compression codecs available for compressed entries.
37 | *
38 | * @see #getCompressionProvider()
39 | * @see CompressionProvider
40 | */
41 | enum CompressionCodec {
42 |
43 | /**
44 | * GZIP compression.
45 | *
46 | * @see GzipCompressionProvider
47 | */
48 | GZIP(new GzipCompressionProvider());
49 |
50 | final private CompressionProvider provider;
51 |
52 | CompressionCodec(final CompressionProvider provider) {
53 | this.provider = provider;
54 | }
55 |
56 | /**
57 | * Gets the {@link CompressionProvider} for this codec.
58 | *
59 | * @return the provider for this codec.
60 | */
61 | public CompressionProvider getProvider() {
62 | return provider;
63 | }
64 | }
65 |
66 | @Valid
67 | @NotNull
68 | protected ZooKeeperFactory ensemble = new ZooKeeperFactory();
69 |
70 | @Min(0)
71 | protected int maxRetries = 1;
72 |
73 | @NotNull
74 | protected Duration backOffBaseTime = Duration.seconds(1);
75 |
76 | @NotNull
77 | protected CompressionCodec compression = CompressionCodec.GZIP;
78 |
79 | /**
80 | * Returns a {@link ZooKeeperFactory} for the ZooKeeper ensemble to connect to.
81 | *
82 | * @return a factory for the ZooKeeper ensemble for the client.
83 | */
84 | @JsonProperty("ensemble")
85 | public ZooKeeperFactory getZooKeeperFactory() {
86 | return ensemble;
87 | }
88 |
89 | /**
90 | * Sets the {@link ZooKeeperFactory} for the ZooKeeper ensemble to connect to.
91 | *
92 | * @param factory the factory for the ZooKeeper ensemble for the client.
93 | */
94 | @JsonProperty("ensemble")
95 | public void setZooKeeperFactory(final ZooKeeperFactory factory) {
96 | this.ensemble = factory;
97 | }
98 |
99 | /**
100 | * Returns the maximum number of retries to attempt to connect to the ensemble.
101 | *
102 | * @return the maximum number of connection attempts.
103 | */
104 | @JsonProperty
105 | public int getMaxRetries() {
106 | return maxRetries;
107 | }
108 |
109 | /**
110 | * Sets the maximum number of retries to attempt to connect to the ensemble.
111 | *
112 | * @param maxRetries the maximum number of connection attempts.
113 | */
114 | @JsonProperty
115 | public void setMaxRetries(final int maxRetries) {
116 | this.maxRetries = maxRetries;
117 | }
118 |
119 | /**
120 | * Returns the initial time to wait before retrying a failed connection.
121 | *
122 | * Subsequent retries will wait an exponential amount of time more than this.
123 | *
124 | * @return the initial time to wait before trying to connect again.
125 | */
126 | @JsonProperty
127 | public Duration getBackOffBaseTime() {
128 | return backOffBaseTime;
129 | }
130 |
131 | /**
132 | * Sets the initial time to wait before retrying a failed connection.
133 | *
134 | * Subsequent retries will wait an exponential amount of time more than this.
135 | *
136 | * @param backOffBaseTime the initial time to wait before trying to connect again.
137 | */
138 | @JsonProperty
139 | public void setBackOffBaseTime(final Duration backOffBaseTime) {
140 | this.backOffBaseTime = backOffBaseTime;
141 | }
142 |
143 | /**
144 | * Returns a {@link RetryPolicy} for handling failed connection attempts.
145 | *
146 | * Always configures an {@link ExponentialBackoffRetry} based on the {@link #getMaxRetries()
147 | * maximum retries} and {@link #getBackOffBaseTime() initial back-off} configured.
148 | *
149 | * @return a {@link RetryPolicy} for handling failed connection attempts.
150 | *
151 | * @see #getMaxRetries()
152 | * @see #getBackOffBaseTime()
153 | */
154 | public RetryPolicy getRetryPolicy() {
155 | return new ExponentialBackoffRetry((int) backOffBaseTime.toMilliseconds(), maxRetries);
156 | }
157 |
158 | /**
159 | * Returns the {@link CompressionCodec} to compress values with.
160 | *
161 | * @return the compression codec to compress values with.
162 | *
163 | * @see CompressionCodec
164 | */
165 | @JsonProperty("compression")
166 | public CompressionCodec getCompressionCodec() {
167 | return compression;
168 | }
169 |
170 | /**
171 | * Sets a {@link CompressionCodec} to compress values with.
172 | *
173 | * @param codec the compression codec to compress values with.
174 | *
175 | * @see CompressionCodec
176 | */
177 | @JsonProperty("compression")
178 | public void setCompressionCodec(final CompressionCodec codec) {
179 | this.compression = codec;
180 | }
181 |
182 | /**
183 | * Returns a {@link CompressionProvider} to compress values with.
184 | *
185 | * @return the compression provider used to compress values.
186 | *
187 | * @see CompressionCodec
188 | */
189 | public CompressionProvider getCompressionProvider() {
190 | return getCompressionCodec().getProvider();
191 | }
192 |
193 | /**
194 | * Builds a default {@link CuratorFramework} for the given {@link Environment}.
195 | *
196 | * @param environment the {@link Environment} to build the {@link CuratorFramework} for.
197 | *
198 | * @return a {@link CuratorFramework} instance, managed and configured.
199 | */
200 | public CuratorFramework build(final Environment environment) {
201 | return build(environment, DEFAULT_NAME);
202 | }
203 |
204 | /**
205 | * Builds a {@link CuratorFramework} instance with the given {@code name} for an {@link
206 | * Environment}.
207 | *
208 | * @param environment the {@link Environment} to build the {@link CuratorFramework} for.
209 | * @param name the name for the {@link CuratorFramework} instance.
210 | *
211 | * @return a {@link CuratorFramework} instance, managed and configured.
212 | */
213 | public CuratorFramework build(final Environment environment, final String name) {
214 | final ZooKeeperFactory factory = getZooKeeperFactory();
215 | final String namespace = factory.getNamespace();
216 | final CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder()
217 | .zookeeperFactory(new DropwizardConfiguredZooKeeperFactory(environment, name))
218 | .ensembleProvider(new DropwizardConfiguredEnsembleProvider(factory))
219 | .connectionTimeoutMs((int) factory.getConnectionTimeout().toMilliseconds())
220 | .threadFactory(new ThreadFactoryBuilder().setNameFormat(name + "-%d").build())
221 | .sessionTimeoutMs((int) factory.getSessionTimeout().toMilliseconds())
222 | .namespace(namespace.startsWith("/") ? namespace.substring(1) : namespace)
223 | .compressionProvider(getCompressionProvider())
224 | .retryPolicy(getRetryPolicy())
225 | .canBeReadOnly(factory.isReadOnly());
226 |
227 | // add optional auth details
228 | final ZooKeeperFactory.Auth auth = factory.getAuth();
229 | if (auth != null) {
230 | builder.authorization(auth.getScheme(), auth.getId().getBytes());
231 | }
232 |
233 | final CuratorFramework framework = builder.build();
234 |
235 | environment.healthChecks().register(name, new CuratorHealthCheck(framework));
236 | environment.lifecycle().manage(new ManagedCuratorFramework(framework));
237 |
238 | return framework;
239 | }
240 | }
241 |
--------------------------------------------------------------------------------
/dropwizard-extra-curator/src/main/java/com/datasift/dropwizard/curator/ManagedCuratorFramework.java:
--------------------------------------------------------------------------------
1 | package com.datasift.dropwizard.curator;
2 |
3 | import org.apache.curator.framework.CuratorFramework;
4 | import io.dropwizard.lifecycle.Managed;
5 |
6 | /**
7 | * Manages the lifecycle of a {@link CuratorFramework} instance.
8 | */
9 | class ManagedCuratorFramework implements Managed {
10 |
11 | private final CuratorFramework framework;
12 |
13 | /**
14 | * Manage the given {@link CuratorFramework} instance.
15 | *
16 | * @param framework the Curator instance to manage.
17 | */
18 | public ManagedCuratorFramework(final CuratorFramework framework) {
19 | this.framework = framework;
20 | }
21 |
22 | @Override
23 | public void start() throws Exception {
24 | framework.start();
25 | }
26 |
27 | @Override
28 | public void stop() throws Exception {
29 | framework.close();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/dropwizard-extra-curator/src/main/java/com/datasift/dropwizard/curator/ensemble/DropwizardConfiguredEnsembleProvider.java:
--------------------------------------------------------------------------------
1 | package com.datasift.dropwizard.curator.ensemble;
2 |
3 | import com.datasift.dropwizard.zookeeper.ZooKeeperFactory;
4 | import org.apache.curator.ensemble.EnsembleProvider;
5 |
6 | import java.io.IOException;
7 |
8 | /**
9 | * An {@link EnsembleProvider} for a fixed ensemble, configured by a {@link ZooKeeperFactory}.
10 | */
11 | public class DropwizardConfiguredEnsembleProvider implements EnsembleProvider {
12 |
13 | private final ZooKeeperFactory factory;
14 |
15 | /**
16 | * Initializes this provider with the given {@code configuration}.
17 | *
18 | * @param factory a factory for ZooKeeper client instances.
19 | */
20 | public DropwizardConfiguredEnsembleProvider(final ZooKeeperFactory factory) {
21 | this.factory = factory;
22 | }
23 |
24 | @Override
25 | public void start() throws Exception {
26 | // nothing to do
27 | }
28 |
29 | @Override
30 | public String getConnectionString() {
31 | return factory.getQuorumSpec();
32 | }
33 |
34 | @Override
35 | public void close() throws IOException {
36 | // nothing to do
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/dropwizard-extra-curator/src/main/java/com/datasift/dropwizard/curator/ensemble/DropwizardConfiguredZooKeeperFactory.java:
--------------------------------------------------------------------------------
1 | package com.datasift.dropwizard.curator.ensemble;
2 |
3 | import io.dropwizard.setup.Environment;
4 | import com.datasift.dropwizard.zookeeper.ZooKeeperFactory;
5 | import org.apache.curator.utils.ZookeeperFactory;
6 | import io.dropwizard.util.Duration;
7 | import org.apache.zookeeper.Watcher;
8 | import org.apache.zookeeper.ZooKeeper;
9 |
10 | import java.util.regex.Matcher;
11 | import java.util.regex.Pattern;
12 |
13 | /**
14 | * Provides integration for Dropwizard's ZooKeeper functionality with Curator.
15 | *
16 | * This ensures that {@link ZooKeeper} instances created by Curator integrate properly with the
17 | * Dropwizard application life-cycle.
18 | */
19 | public class DropwizardConfiguredZooKeeperFactory implements ZookeeperFactory {
20 |
21 | private static final Pattern PORT_PATTERN = Pattern.compile(":(\\d+)");
22 |
23 | private final String name;
24 | private final Environment environment;
25 |
26 | /**
27 | * Initializes this factory with the {@link ZooKeeperFactory} to create {@link ZooKeeper}
28 | * clients from.
29 | *
30 | * @param name the name of the Curator instance creating {@link ZooKeeper} clients.
31 | */
32 | public DropwizardConfiguredZooKeeperFactory(final Environment environment, final String name) {
33 | this.environment = environment;
34 | this.name = name;
35 | }
36 |
37 | @Override
38 | public ZooKeeper newZooKeeper(final String connectString,
39 | final int sessionTimeout,
40 | final Watcher watcher,
41 | final boolean canBeReadOnly) throws Exception {
42 |
43 | return new DynamicZooKeeperFactory(connectString, sessionTimeout, canBeReadOnly)
44 | .build(environment, watcher, String.format("curator-%s", name));
45 | }
46 |
47 | static class DynamicZooKeeperFactory extends ZooKeeperFactory {
48 |
49 | DynamicZooKeeperFactory(final String connectString,
50 | final int sessionTimeout,
51 | final boolean canBeReadOnly) {
52 | final int idx = connectString.indexOf('/');
53 | final int hostLength = idx == -1 ? connectString.length() : idx;
54 | final String authority = connectString.substring(0, hostLength);
55 | final Matcher matcher = PORT_PATTERN.matcher(authority);
56 | this.port = matcher.find() ? Integer.parseInt(matcher.group(1)) : port;
57 | this.hosts = matcher.replaceAll("").split(",");
58 | this.namespace = idx == -1 ? "/" : connectString.substring(idx);
59 | this.sessionTimeout = Duration.milliseconds(sessionTimeout);
60 | this.readOnly = canBeReadOnly;
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/dropwizard-extra-curator/src/main/java/com/datasift/dropwizard/curator/health/CuratorHealthCheck.java:
--------------------------------------------------------------------------------
1 | package com.datasift.dropwizard.curator.health;
2 |
3 | import org.apache.curator.framework.CuratorFramework;
4 | import com.codahale.metrics.health.HealthCheck;
5 | import org.apache.curator.framework.imps.CuratorFrameworkState;
6 |
7 | /**
8 | * A {@link HealthCheck} that ensures a {@link CuratorFramework} is started and that the configured
9 | * root namespace exists.
10 | */
11 | public class CuratorHealthCheck extends HealthCheck {
12 |
13 | private final CuratorFramework framework;
14 |
15 | /**
16 | * Create a new {@link HealthCheck} instance with the given name.
17 | *
18 | * @param framework The {@link CuratorFramework} instance to check the health of.
19 | */
20 | public CuratorHealthCheck(final CuratorFramework framework) {
21 | this.framework = framework;
22 | }
23 |
24 | /**
25 | * Checks that the {@link CuratorFramework} instance is started and that the configured root
26 | * namespace exists.
27 | *
28 | * @return {@link Result#unhealthy(String)} if the {@link CuratorFramework} is not started or
29 | * the configured root namespace does not exist; otherwise, {@link Result#healthy()}.
30 | * @throws Exception if an error occurs checking the health of the ZooKeeper ensemble.
31 | */
32 | @Override
33 | protected Result check() throws Exception {
34 | final String namespace = framework.getNamespace();
35 | if (framework.getState() != CuratorFrameworkState.STARTED) {
36 | return Result.unhealthy("Client not started");
37 | } else if (framework.checkExists().forPath(namespace.isEmpty() ? "/" : "") == null) {
38 | return Result.unhealthy("Root for namespace does not exist");
39 | }
40 |
41 | return Result.healthy();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/dropwizard-extra-curator/src/test/java/com/datasift/dropwizard/curator/CuratorFactoryTest.java:
--------------------------------------------------------------------------------
1 | package com.datasift.dropwizard.curator;
2 |
3 | import io.dropwizard.configuration.ConfigurationFactory;
4 | import io.dropwizard.jackson.Jackson;
5 | import com.datasift.dropwizard.zookeeper.ZooKeeperFactory;
6 | import com.google.common.io.Resources;
7 | import org.apache.curator.framework.api.CompressionProvider;
8 | import org.apache.curator.retry.ExponentialBackoffRetry;
9 | import org.junit.Before;
10 | import org.junit.Test;
11 |
12 | import javax.validation.Validation;
13 | import javax.validation.Validator;
14 | import java.io.File;
15 |
16 | import static org.hamcrest.Matchers.*;
17 | import static org.junit.Assert.assertThat;
18 |
19 | /** Tests {@link CuratorConfiguration} */
20 | public class CuratorFactoryTest {
21 |
22 | private CuratorFactory factory = null;
23 |
24 | @Before
25 | public void setup() throws Exception {
26 | final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
27 | factory = new ConfigurationFactory<>(CuratorFactory.class, validator, Jackson.newObjectMapper(), "dw")
28 | .build(new File(Resources.getResource("yaml/curator.yaml").toURI()));
29 | }
30 |
31 | @Test
32 | public void testZooKeeper() {
33 | assertThat("has ZooKeeperConfiguration",
34 | factory.getZooKeeperFactory(),
35 | instanceOf(ZooKeeperFactory.class));
36 | }
37 |
38 | @Test
39 | public void testRetryPolicy() {
40 | assertThat("has RetryPolicy",
41 | factory.getRetryPolicy(),
42 | instanceOf(ExponentialBackoffRetry.class));
43 | }
44 |
45 | @Test
46 | public void testCompressionCodec() {
47 | assertThat("has CompressionCodec",
48 | factory.getCompressionCodec(),
49 | is(CuratorFactory.CompressionCodec.GZIP));
50 | }
51 |
52 | @Test
53 | public void testCompressionProvider() {
54 | assertThat("supplied CompressionProvider",
55 | factory.getCompressionProvider(),
56 | instanceOf(CompressionProvider.class));
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/dropwizard-extra-curator/src/test/java/com/datasift/dropwizard/curator/ensemble/DynamicZooKeeperConfigurationTest.java:
--------------------------------------------------------------------------------
1 | package com.datasift.dropwizard.curator.ensemble;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 | import static org.hamcrest.Matchers.*;
7 |
8 | /**
9 | * Tests {@link DropwizardConfiguredZooKeeperFactory.DynamicZooKeeperFactory}.
10 | */
11 | public class DynamicZooKeeperConfigurationTest {
12 |
13 | @Test
14 | public void parsesFullConnectionString() {
15 | final String hostname = "zookeeper.lan";
16 | final int port = 2182;
17 | final DropwizardConfiguredZooKeeperFactory.DynamicZooKeeperFactory factory
18 | = new DropwizardConfiguredZooKeeperFactory.DynamicZooKeeperFactory(
19 | hostname + ":" + port, 0, true);
20 |
21 | assertThat("parses hostname from connection string",
22 | factory.getHosts(),
23 | is(equalTo(new String[] { hostname })));
24 |
25 | assertThat("parses port from connection string",
26 | factory.getPort(),
27 | is(port));
28 | }
29 |
30 | @Test
31 | public void parsesConnectionStringWithDefaultPort() {
32 | final String hostname = "zookeeper.lan";
33 | final int port = 2181;
34 | final DropwizardConfiguredZooKeeperFactory.DynamicZooKeeperFactory conf
35 | = new DropwizardConfiguredZooKeeperFactory.DynamicZooKeeperFactory(
36 | hostname, 0, true);
37 |
38 | assertThat("parses hostname from connection string",
39 | conf.getHosts(),
40 | is(equalTo(new String[] { hostname })));
41 |
42 | assertThat("uses default port", conf.getPort(), is(port));
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/dropwizard-extra-curator/src/test/resources/yaml/curator.yaml:
--------------------------------------------------------------------------------
1 | ensemble:
2 | hosts:
3 | - test1
4 | - test2
5 | port: 2182
6 | sessionTimeout: 30 seconds
7 | maxRetries: 5
8 | backOffBaseTime: 2 seconds
9 | compression: gzip
10 |
--------------------------------------------------------------------------------
/dropwizard-extra-hbase/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 4.0.0
5 |
6 | com.datasift.dropwizard
7 | dropwizard-extra
8 | 0.7.1-2-SNAPSHOT
9 | ../pom.xml
10 |
11 |
12 | dropwizard-extra-hbase
13 |
14 | Dropwizard Extra HBase
15 | http://datasift.github.com/dropwizard-extra/dropwizard-extra-hbase
16 |
17 | Dropwizard integration for working with HBase in Scala.
18 |
19 |
20 |
21 |
22 | io.dropwizard
23 | dropwizard-core
24 |
25 |
26 | com.datasift.dropwizard
27 | dropwizard-extra-zookeeper
28 | ${project.version}
29 |
30 |
31 | org.hbase
32 | asynchbase
33 | 1.4.1
34 |
35 |
36 |
37 |
38 |
39 |
40 | maven-javadoc-plugin
41 |
42 |
43 | http://tsunanet.net/~tsuna/async/api/
44 | http://tsunanet.net/~tsuna/asynchbase/api/
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/dropwizard-extra-hbase/src/main/java/com/datasift/dropwizard/hbase/HBaseClient.java:
--------------------------------------------------------------------------------
1 | package com.datasift.dropwizard.hbase;
2 |
3 | import com.datasift.dropwizard.hbase.scanner.RowScanner;
4 | import com.stumbleupon.async.Deferred;
5 | import io.dropwizard.util.Duration;
6 | import io.dropwizard.util.Size;
7 | import org.hbase.async.*;
8 | import org.jboss.netty.util.Timer;
9 |
10 | import java.util.ArrayList;
11 |
12 | /**
13 | * Client for interacting with an HBase cluster.
14 | *
15 | * To create an instance, use {@link HBaseClientFactory}.
16 | *
17 | * All implementations are wrapper proxies around {@link org.hbase.async.HBaseClient} providing
18 | * additional functionality.
19 | *
20 | * @see HBaseClientFactory
21 | * @see org.hbase.async.HBaseClient
22 | */
23 | public interface HBaseClient {
24 |
25 | /**
26 | * Get the maximum time for which edits may be buffered before being flushed.
27 | *
28 | * @return the maximum time for which edits may be buffered.
29 | *
30 | * @see org.hbase.async.HBaseClient#getFlushInterval()
31 | */
32 | public Duration getFlushInterval();
33 |
34 | /**
35 | * Get the capacity of the increment buffer.
36 | *
37 | * @return the capacity of the increment buffer.
38 | *
39 | * @see org.hbase.async.HBaseClient#getIncrementBufferSize()
40 | */
41 | public Size getIncrementBufferSize();
42 |
43 | /**
44 | * Sets the maximum time for which edits may be buffered before being flushed.
45 | *
46 | * @param flushInterval the maximum time for which edits may be buffered.
47 | *
48 | * @return the previous flush interval.
49 | *
50 | * @see org.hbase.async.HBaseClient#setFlushInterval(short)
51 | */
52 | public Duration setFlushInterval(Duration flushInterval);
53 |
54 | /**
55 | * Sets the capacity of the increment buffer.
56 | *
57 | * @param incrementBufferSize the capacity of the increment buffer.
58 | *
59 | * @return the previous increment buffer capacity.
60 | *
61 | * @see org.hbase.async.HBaseClient#setIncrementBufferSize(int)
62 | */
63 | public Size setIncrementBufferSize(Size incrementBufferSize);
64 |
65 | /**
66 | * Atomically creates a cell if, and only if, it doesn't already exist.
67 | *
68 | * @param edit the new cell to create.
69 | *
70 | * @return true if the cell was created, false if the cell already exists.
71 | *
72 | * @see org.hbase.async.HBaseClient#atomicCreate(org.hbase.async.PutRequest)
73 | */
74 | public Deferred create(PutRequest edit);
75 |
76 | /**
77 | * Buffer a durable increment for coalescing.
78 | *
79 | * @param request the increment to buffer
80 | *
81 | * @return the new value of the cell, after the increment.
82 | *
83 | * @see org.hbase.async.HBaseClient#bufferAtomicIncrement(org.hbase.async.AtomicIncrementRequest)
84 | */
85 | public Deferred bufferIncrement(AtomicIncrementRequest request);
86 |
87 | /**
88 | * Atomically and durably increment a cell value.
89 | *
90 | * @param request the increment to make.
91 | *
92 | * @return the new value of the cell, after the increment.
93 | *
94 | * @see org.hbase.async.HBaseClient#atomicIncrement(org.hbase.async.AtomicIncrementRequest)
95 | */
96 | public Deferred increment(AtomicIncrementRequest request);
97 |
98 | /**
99 | * Atomically increment a cell value, with optional durability.
100 | *
101 | * @param request the increment to make.
102 | * @param durable whether to guarantee this increment succeeded durably.
103 | *
104 | * @return the new value of the cell, after the increment.
105 | *
106 | * @see org.hbase.async.HBaseClient#atomicIncrement(org.hbase.async.AtomicIncrementRequest, boolean)
107 | */
108 | public Deferred increment(AtomicIncrementRequest request, Boolean durable);
109 |
110 | /**
111 | * Atomically compares and sets (CAS) a single cell
112 | *
113 | * @param edit the cell to set.
114 | * @param expected the expected current value.
115 | *
116 | * @return true if the expectation was met and the cell was set, otherwise, false.
117 | *
118 | * @see org.hbase.async.HBaseClient#compareAndSet(org.hbase.async.PutRequest, byte[])
119 | */
120 | public Deferred compareAndSet(PutRequest edit, byte[] expected);
121 |
122 | /**
123 | * Atomically compares and sets (CAS) a single cell.
124 | *
125 | * @param edit the cell to set.
126 | * @param expected the expected current value.
127 | *
128 | * @return true if the expectation was met and the cell was set, otherwise, false.
129 | *
130 | * @see org.hbase.async.HBaseClient#compareAndSet(org.hbase.async.PutRequest, String)
131 | */
132 | public Deferred compareAndSet(PutRequest edit, String expected);
133 |
134 | /**
135 | * Deletes the specified cells
136 | *
137 | * @param request the cell(s) to delete.
138 | *
139 | * @return a {@link Deferred} indicating when the deletion completes.
140 | *
141 | * @see org.hbase.async.HBaseClient#delete(org.hbase.async.DeleteRequest)
142 | */
143 | public Deferred