/*
* Copyright 2014, Stratio.
*
* 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 com.stratio.deep.cassandra.cql;
import static com.stratio.deep.commons.utils.Utils.quote;
import java.net.InetAddress;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.datastax.driver.core.Cluster;
import com.datastax.driver.core.ProtocolVersion;
import com.datastax.driver.core.Session;
import com.datastax.driver.core.policies.LoadBalancingPolicy;
import com.datastax.driver.core.policies.Policies;
import com.stratio.deep.cassandra.config.CassandraDeepJobConfig;
import com.stratio.deep.commons.exception.DeepIOException;
import com.stratio.deep.commons.utils.Pair;
/**
* Created by luca on 09/04/14.
*/
class CassandraClientProvider {
private static final transient Map<String, Session> CLIENTS_CACHE = Collections.synchronizedMap(new
HashMap<String, Session>());
private static final Logger LOG = LoggerFactory.getLogger(CassandraClientProvider.class);
static {
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
synchronized (CLIENTS_CACHE) {
if (CLIENTS_CACHE != null && !CLIENTS_CACHE.isEmpty()) {
LOG.info("Closing clients ");
for (Session entry : CLIENTS_CACHE.values()) {
if (entry != null) {
entry.close();
}
}
}
}
}
});
}
CassandraClientProvider() {
}
static Pair<Session, String> trySessionForLocation(String location, CassandraDeepJobConfig conf,
Boolean balanced) {
try {
return getSession(location, conf, balanced);
} catch (Exception e) {
LOG.warn("Could not connect to {}, possible loss of data-locality. Delegating connection to java driver",
location, conf.getHost());
return getSession(conf.getHost(), conf, true);
}
}
static Pair<Session, String> getSession(String location, CassandraDeepJobConfig conf, Boolean balanced) {
assert balanced != null;
synchronized (CLIENTS_CACHE) {
final int port = conf.getCqlPort();
final String key = location + ":" + port + ":" + conf.getKeyspace() + ":" + balanced;
if (CLIENTS_CACHE.containsKey(key)) {
LOG.trace("Found cached session at level 1 for key {{}}", key);
return Pair.create(CLIENTS_CACHE.get(key), location);
}
if (balanced && location.equals(conf.getHost())) {
CLIENTS_CACHE.put(key, conf.getSession());
LOG.trace("Found cached session at level 2 for key {{}}", key);
return Pair.create(CLIENTS_CACHE.get(key), location);
}
try {
LOG.debug("No cached session found for key {{}}", key);
InetAddress locationInet = InetAddress.getByName(location);
LoadBalancingPolicy loadBalancingPolicy = balanced ? Policies.defaultLoadBalancingPolicy() : new
LocalMachineLoadBalancingPolicy(locationInet);
Cluster cluster = Cluster.builder()
.withPort(port)
.addContactPoint(location)
.withLoadBalancingPolicy(loadBalancingPolicy)
.withProtocolVersion(ProtocolVersion.V2)
.withCredentials(conf.getUsername(), conf.getPassword())
.build();
Session session = cluster.connect(quote(conf.getKeyspace()));
CLIENTS_CACHE.put(key, session);
return Pair.create(CLIENTS_CACHE.get(key), location);
} catch (Exception e) {
throw new DeepIOException("Failed to create authenticated client to {" + location + "}:{" + port +
"}", e);
}
}
}
}