All Downloads are FREE. Search and download functionalities are using the official Maven repository.

systems.composable.dropwizard.cassandra.CassandraFactory Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2016 Composable Systems Limited
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package systems.composable.dropwizard.cassandra;

import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.health.HealthCheckRegistry;
import com.datastax.driver.core.*;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Strings;
import io.dropwizard.setup.Environment;
import io.dropwizard.util.Duration;
import org.hibernate.validator.constraints.NotEmpty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import systems.composable.dropwizard.cassandra.auth.AuthProviderFactory;
import systems.composable.dropwizard.cassandra.network.AddressTranslatorFactory;
import systems.composable.dropwizard.cassandra.loadbalancing.LoadBalancingPolicyFactory;
import systems.composable.dropwizard.cassandra.pooling.PoolingOptionsFactory;
import systems.composable.dropwizard.cassandra.reconnection.ReconnectionPolicyFactory;
import systems.composable.dropwizard.cassandra.retry.RetryPolicyFactory;
import systems.composable.dropwizard.cassandra.speculativeexecution.SpeculativeExecutionPolicyFactory;
import systems.composable.dropwizard.cassandra.ssl.SSLOptionsFactory;

import javax.validation.Valid;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.util.Optional;

import static com.codahale.metrics.MetricRegistry.name;

/**
 * A factory for configuring the Cassandra bundle.
 * 

* Configuration Parameters: *

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
NameDefaultDescription
clusterNameDefaults to the cluster name provided by the Cassandra driver.The name of the cluster, as defined by the Cassandra driver; also used in metrics and health checks.
keyspaceNo default. If provided, this will be included in the health check.The name of the keyspace to connect to.
validationQuerySELECT key FROM system.localThe query to execute against the cluster to determine whether it is healthy.
healthCheckTimeout2 seconds.Sets the maximum time to wait for the validation query to respond.
contactPointsNo default. You must provide a list of contact points for the Cassandra driver.Each contact point can be a DNS record resolving to multiple hosts. In this case all of them will be added to the {@link Cluster}.
port9042The port to use to connect to the Cassandra host.
protocolVersion-1The native protocol version to use.
compressionNONESets the compression to use for the transport. Must a value in the {@link ProtocolOptions.Compression compression enum}.
maxSchemaAgreementWaitNo default.Sets the maximum time to wait for schema agreement before returning from a DDL query.
reconnectionPolicyNo default.The {@link ReconnectionPolicyFactory reconnection policy} to use.
authProviderNo default.The {@link AuthProviderFactory auth provider} to use.
retryPolicyNo default.The {@link RetryPolicyFactory retry policy} to use.
loadBalancingPolicyNo default.The {@link LoadBalancingPolicyFactory load balancing policy} to use.
speculativeExecutionPolicyNo default.The {@link SpeculativeExecutionPolicyFactory speculative execution policy} to use.
queryOptionsNo default.The {@link QueryOptions} to use.
socketOptionsNo default.The {@link SocketOptions} to use
poolingOptionsNo default.The {@link PoolingOptionsFactory pooling options} to use.
metricsEnabledtrueWhether or not to enable metrics reporting.
jmxEnabledfalseWhether or not to enable JMX metrics reporting. This should ideally remain disabled in a Dropwizard app, * as metrics reporters should be configured via the {@code metrics} configuration option.
shutdownGracePeriod30 secondsThe time to wait while the cluster closes gracefully; after which, the cluster will be forcefully terminated.
addressTranslatorNo default.The {@link com.datastax.driver.core.policies.AddressTranslator} to use.
*/ public class CassandraFactory { private static final Logger LOG = LoggerFactory.getLogger(CassandraFactory.class); private String clusterName; private String keyspace; @NotEmpty private String validationQuery = "SELECT key FROM system.local"; @NotEmpty private String[] contactPoints; @Min(1) private int port = ProtocolOptions.DEFAULT_PORT; private Optional protocolVersion = Optional.empty(); @Valid private Optional ssl = Optional.empty(); @NotNull private ProtocolOptions.Compression compression = ProtocolOptions.Compression.NONE; private Optional maxSchemaAgreementWait = Optional.empty(); @Valid private Optional reconnectionPolicy = Optional.empty(); @Valid private Optional authProvider = Optional.empty(); @Valid private Optional retryPolicy = Optional.empty(); @Valid private Optional loadBalancingPolicy = Optional.empty(); @Valid private Optional speculativeExecutionPolicy = Optional.empty(); private Optional queryOptions = Optional.empty(); private Optional socketOptions = Optional.empty(); @Valid private Optional poolingOptions = Optional.empty(); @Valid private Optional addressTranslator = Optional.empty(); private boolean metricsEnabled = true; private boolean jmxEnabled = false; @NotNull private Duration shutdownGracePeriod = Duration.seconds(30); @NotNull private Duration healthCheckTimeout = Duration.seconds(2); @JsonProperty public String getClusterName() { return clusterName; } @JsonProperty public void setClusterName(String clusterName) { this.clusterName = clusterName; } @JsonProperty public String getKeyspace() { return keyspace; } @JsonProperty public void setKeyspace(String keyspace) { this.keyspace = keyspace; } @JsonProperty public String getValidationQuery() { return validationQuery; } @JsonProperty public void setValidationQuery(String validationQuery) { this.validationQuery = validationQuery; } @JsonProperty public String[] getContactPoints() { return contactPoints; } @JsonProperty public void setContactPoints(String[] contactPoints) { this.contactPoints = contactPoints; } @JsonProperty public int getPort() { return port; } @JsonProperty public void setPort(int port) { this.port = port; } @JsonProperty public Optional getProtocolVersion() { return protocolVersion; } @JsonProperty public void setProtocolVersion(Optional protocolVersion) { this.protocolVersion = protocolVersion; } @JsonProperty public Optional getSsl() { return ssl; } @JsonProperty public void setSsl(Optional ssl) { this.ssl = ssl; } @JsonProperty public ProtocolOptions.Compression getCompression() { return compression; } @JsonProperty public void setCompression(ProtocolOptions.Compression compression) { this.compression = compression; } @JsonProperty public void setMaxSchemaAgreementWait(Optional maxSchemaAgreementWait) { this.maxSchemaAgreementWait = maxSchemaAgreementWait; } @JsonProperty public Optional getReconnectionPolicy() { return reconnectionPolicy; } @JsonProperty public void setReconnectionPolicy(Optional reconnectionPolicy) { this.reconnectionPolicy = reconnectionPolicy; } @JsonProperty public Optional getAuthProvider() { return authProvider; } @JsonProperty public void setAuthProvider(Optional authProvider) { this.authProvider = authProvider; } @JsonProperty public Optional getRetryPolicy() { return retryPolicy; } @JsonProperty public void setRetryPolicy(Optional retryPolicy) { this.retryPolicy = retryPolicy; } @JsonProperty public Optional getLoadBalancingPolicy() { return loadBalancingPolicy; } @JsonProperty public void setLoadBalancingPolicy(Optional loadBalancingPolicy) { this.loadBalancingPolicy = loadBalancingPolicy; } @JsonProperty public Optional getSpeculativeExecutionPolicy() { return speculativeExecutionPolicy; } @JsonProperty public void setSpeculativeExecutionPolicy(Optional speculativeExecutionPolicy) { this.speculativeExecutionPolicy = speculativeExecutionPolicy; } @JsonProperty public Optional getQueryOptions() { return queryOptions; } @JsonProperty public void setQueryOptions(Optional queryOptions) { this.queryOptions = queryOptions; } @JsonProperty public Optional getSocketOptions() { return socketOptions; } @JsonProperty public void setSocketOptions(Optional socketOptions) { this.socketOptions = socketOptions; } @JsonProperty public Optional getPoolingOptions() { return poolingOptions; } @JsonProperty public void setPoolingOptions(Optional poolingOptions) { this.poolingOptions = poolingOptions; } @JsonProperty public boolean isMetricsEnabled() { return metricsEnabled; } @JsonProperty public void setMetricsEnabled(boolean metricsEnabled) { this.metricsEnabled = metricsEnabled; } @JsonProperty public boolean isJmxEnabled() { return jmxEnabled; } @JsonProperty public void setJmxEnabled(boolean jmxEnabled) { this.jmxEnabled = jmxEnabled; } @JsonProperty public Duration getShutdownGracePeriod() { return shutdownGracePeriod; } @JsonProperty public void setShutdownGracePeriod(Duration shutdownGracePeriod) { this.shutdownGracePeriod = shutdownGracePeriod; } @JsonProperty public Duration getHealthCheckTimeout() { return healthCheckTimeout; } @JsonProperty public void setHealthCheckTimeout(Duration healthCheckTimeout) { this.healthCheckTimeout = healthCheckTimeout; } @JsonProperty public Optional getAddressTranslator() { return addressTranslator; } @JsonProperty public void setAddressTranslator(Optional addressTranslator) { this.addressTranslator = addressTranslator; } /** * Builds a {@link Cluster} instance for the given {@link Environment}. *

* The {@code environment} will be used for lifecycle management, as well as metrics and * health-checks. * * @param environment the environment to manage the lifecycle, metrics and health-checks. * @return a fully configured and managed {@link Cluster}. */ public Cluster build(Environment environment) { final Cluster cluster = build(environment.metrics(), environment.healthChecks()); LOG.debug("Registering {} Cassandra cluster for lifecycle management", cluster.getClusterName()); environment.lifecycle().manage(new CassandraManager(cluster, getShutdownGracePeriod())); return cluster; } /** * Builds a {@link Cluster} instance. *

* The {@link MetricRegistry} will be used to register client metrics, and the {@link * HealthCheckRegistry} to register client health-checks. * * @param metrics the registry to register client metrics. * @param healthChecks the registry to register client health-checks. * @return a fully configured {@link Cluster}. */ public Cluster build(MetricRegistry metrics, HealthCheckRegistry healthChecks) { final Cluster.Builder builder = Cluster.builder(); for (String contactPoint : contactPoints) { builder.addContactPoints(contactPoint); } builder.withPort(port); builder.withCompression(compression); protocolVersion.ifPresent(builder::withProtocolVersion); ssl.map(SSLOptionsFactory::build).ifPresent(builder::withSSL); maxSchemaAgreementWait.map(Duration::toSeconds).map(Long::intValue).ifPresent(builder::withMaxSchemaAgreementWaitSeconds); authProvider.map(AuthProviderFactory::build).ifPresent(builder::withAuthProvider); reconnectionPolicy.map(ReconnectionPolicyFactory::build).ifPresent(builder::withReconnectionPolicy); retryPolicy.map(RetryPolicyFactory::build).ifPresent(builder::withRetryPolicy); loadBalancingPolicy.map(LoadBalancingPolicyFactory::build).ifPresent(builder::withLoadBalancingPolicy); speculativeExecutionPolicy.map(SpeculativeExecutionPolicyFactory::build).ifPresent(builder::withSpeculativeExecutionPolicy); queryOptions.ifPresent(builder::withQueryOptions); socketOptions.ifPresent(builder::withSocketOptions); poolingOptions.map(PoolingOptionsFactory::build).ifPresent(builder::withPoolingOptions); addressTranslator.map(AddressTranslatorFactory::build).ifPresent(builder::withAddressTranslator); if (!metricsEnabled) { builder.withoutMetrics(); } if (!jmxEnabled) { builder.withoutJMXReporting(); } if (!Strings.isNullOrEmpty(clusterName)) { builder.withClusterName(clusterName); } Cluster cluster = builder.build(); LOG.debug("Registering {} Cassandra health check", cluster.getClusterName()); CassandraHealthCheck healthCheck = new CassandraHealthCheck(cluster, validationQuery, healthCheckTimeout); healthChecks.register(name("cassandra", cluster.getClusterName()), healthCheck); if (isMetricsEnabled()) { LOG.debug("Registering {} Cassandra metrics", cluster.getClusterName()); metrics.registerAll(new CassandraMetricSet(cluster)); } return cluster; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy