Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2013-2018 Cinchapi Inc.
*
* 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.cinchapi.concourse;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.Callable;
import javax.annotation.Nullable;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
import com.cinchapi.common.base.CheckedExceptions;
import com.cinchapi.concourse.config.ConcourseClientPreferences;
import com.cinchapi.concourse.lang.BuildableState;
import com.cinchapi.concourse.lang.Criteria;
import com.cinchapi.concourse.lang.Language;
import com.cinchapi.concourse.security.ClientSecurity;
import com.cinchapi.concourse.thrift.AccessToken;
import com.cinchapi.concourse.thrift.ComplexTObject;
import com.cinchapi.concourse.thrift.ConcourseService;
import com.cinchapi.concourse.thrift.Diff;
import com.cinchapi.concourse.thrift.Operator;
import com.cinchapi.concourse.thrift.SecurityException;
import com.cinchapi.concourse.thrift.TObject;
import com.cinchapi.concourse.thrift.TransactionToken;
import com.cinchapi.concourse.util.ByteBuffers;
import com.cinchapi.concourse.util.Collections;
import com.cinchapi.concourse.util.Conversions;
import com.cinchapi.concourse.util.Convert;
import com.cinchapi.concourse.util.LinkNavigation;
import com.cinchapi.concourse.util.PrettyLinkedHashMap;
import com.cinchapi.concourse.util.PrettyLinkedTableMap;
import com.cinchapi.concourse.util.Transformers;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
/**
* An implementation of the {@link Concourse} interface that interacts with the
* server via Thrift's RPC protocols.
*
* @author Jeff Nelson
*/
class ConcourseThriftDriver extends Concourse {
private static String ENVIRONMENT;
private static String PASSWORD;
private static String SERVER_HOST;
private static int SERVER_PORT;
private static String USERNAME;
static {
// If there is a concourse_client.prefs file located in the working
// directory, parse it and use its values as defaults.
ConcourseClientPreferences config = ConcourseClientPreferences
.fromCurrentWorkingDirectory();
SERVER_HOST = config.getHost();
SERVER_PORT = config.getPort();
USERNAME = config.getUsername();
PASSWORD = new String(config.getPassword());
ENVIRONMENT = config.getEnvironment();
}
/**
* The Thrift client that actually handles all RPC communication.
*/
private final ConcourseService.Client client;
/**
* The client keeps a copy of its {@link AccessToken} and passes it to
* the server for each remote procedure call. The client will
* re-authenticate when necessary using the username/password read from
* the prefs file.
*/
private AccessToken creds = null;
/**
* The environment to which the client is connected.
*/
private final String environment;
/**
* The host of the connection.
*/
private final String host;
/**
* An encrypted copy of the password passed to the constructor.
*/
private final ByteBuffer password;
/**
* The port of the connection.
*/
private final int port;
/**
* Whenever the client starts a Transaction, it keeps a
* {@link TransactionToken} so that the server can stage the changes in
* the appropriate place.
*/
private TransactionToken transaction = null;
/**
* An encrypted copy of the username passed to the constructor.
*/
private final ByteBuffer username;
/**
* Create a new Client connection to the environment of the Concourse
* Server described in {@code concourse_client.prefs} (or the default
* environment and server if the prefs file does not exist) and return a
* handler to facilitate database interaction.
*/
public ConcourseThriftDriver() {
this(ENVIRONMENT);
}
/**
* Create a new Client connection to the specified {@code environment}
* of the Concourse Server described in {@code concourse_client.prefs}
* (or the default server if the prefs file does not exist) and return a
* handler to facilitate database interaction.
*
* @param environment
*/
public ConcourseThriftDriver(String environment) {
this(SERVER_HOST, SERVER_PORT, USERNAME, PASSWORD, environment);
}
/**
* Create a new Client connection to the default environment of the
* specified Concourse Server and return a handler to facilitate
* database interaction.
*
* @param host
* @param port
* @param username
* @param password
*/
public ConcourseThriftDriver(String host, int port, String username,
String password) {
this(host, port, username, password, "");
}
/**
* Create a new Client connection to the specified {@code environment}
* of the specified Concourse Server and return a handler to facilitate
* database interaction.
*
* @param host
* @param port
* @param username
* @param password
* @param environment
*/
public ConcourseThriftDriver(String host, int port, String username,
String password, String environment) {
this.host = host;
this.port = port;
this.username = ClientSecurity.encrypt(username);
this.password = ClientSecurity.encrypt(password);
this.environment = environment;
final TTransport transport = new TSocket(host, port);
try {
transport.open();
TProtocol protocol = new TBinaryProtocol(transport);
client = new ConcourseService.Client(protocol);
authenticate();
Runtime.getRuntime().addShutdownHook(new Thread("shutdown") {
@Override
public void run() {
if(transaction != null && transport.isOpen()) {
abort();
transport.close();
}
}
});
}
catch (TTransportException e) {
throw new RuntimeException(
"Could not connect to the Concourse Server at " + host + ":"
+ port);
}
}
@Override
public void abort() {
execute(() -> {
if(transaction != null) {
final TransactionToken token = transaction;
transaction = null;
client.abort(creds, token, environment);
}
return null;
});
}
@Override
public long add(String key, T value) {
return execute(() -> {
return client.addKeyValue(key, Convert.javaToThrift(value), creds,
transaction, environment);
});
}
@Override
public Map add(String key, T value,
Collection records) {
return execute(() -> {
Map raw = client.addKeyValueRecords(key,
Convert.javaToThrift(value),
Collections.toLongList(records), creds, transaction,
environment);
Map pretty = PrettyLinkedHashMap
.newPrettyLinkedHashMap("Record", "Successful");
for (long record : records) {
pretty.put(record, raw.get(record));
}
return pretty;
});
}
@Override
public boolean add(String key, T value, long record) {
return execute(() -> {
return client.addKeyValueRecord(key, Convert.javaToThrift(value),
record, creds, transaction, environment);
});
}
@Override
public Map audit(long record) {
return execute(() -> {
Map audit = client.auditRecord(record, creds,
transaction, environment);
return ((PrettyLinkedHashMap) Transformers
.transformMap(audit, Conversions.timestampToMicros()))
.setKeyName("DateTime").setValueName("Revision");
});
}
@Override
public Map audit(long record, Timestamp start) {
return execute(() -> {
Map audit;
if(start.isString()) {
audit = client.auditRecordStartstr(record, start.toString(),
creds, transaction, environment);
}
else {
audit = client.auditRecordStart(record, start.getMicros(),
creds, transaction, environment);
}
return ((PrettyLinkedHashMap) Transformers
.transformMap(audit, Conversions.timestampToMicros()))
.setKeyName("DateTime").setValueName("Revision");
});
}
@Override
public Map audit(long record, Timestamp start,
Timestamp end) {
return execute(() -> {
Map audit;
if(start.isString()) {
audit = client.auditRecordStartstrEndstr(record,
start.toString(), end.toString(), creds, transaction,
environment);
}
else {
audit = client.auditRecordStartEnd(record, start.getMicros(),
end.getMicros(), creds, transaction, environment);
}
return ((PrettyLinkedHashMap) Transformers
.transformMap(audit, Conversions.timestampToMicros()))
.setKeyName("DateTime").setValueName("Revision");
});
}
@Override
public Map audit(String key, long record) {
return execute(() -> {
Map audit = client.auditKeyRecord(key, record, creds,
transaction, environment);
return ((PrettyLinkedHashMap) Transformers
.transformMap(audit, Conversions.timestampToMicros()))
.setKeyName("DateTime").setValueName("Revision");
});
}
@Override
public Map audit(String key, long record,
Timestamp start) {
return execute(() -> {
Map audit;
if(start.isString()) {
audit = client.auditKeyRecordStartstr(key, record,
start.toString(), creds, transaction, environment);
}
else {
audit = client.auditKeyRecordStart(key, record,
start.getMicros(), creds, transaction, environment);
}
return ((PrettyLinkedHashMap) Transformers
.transformMap(audit, Conversions.timestampToMicros()))
.setKeyName("DateTime").setValueName("Revision");
});
}
@Override
public Map audit(String key, long record,
Timestamp start, Timestamp end) {
return execute(() -> {
Map audit;
if(start.isString()) {
audit = client.auditKeyRecordStartstrEndstr(key, record,
start.toString(), end.toString(), creds, transaction,
environment);
}
else {
audit = client.auditKeyRecordStartEnd(key, record,
start.getMicros(), end.getMicros(), creds, transaction,
environment);
}
return ((PrettyLinkedHashMap) Transformers
.transformMap(audit, Conversions.timestampToMicros()))
.setKeyName("DateTime").setValueName("Revision");
});
}
@Override
public Map>> browse(Collection keys) {
return execute(() -> {
Map>> raw = client.browseKeys(
Collections.toList(keys), creds, transaction, environment);
Map>> pretty = PrettyLinkedTableMap
.newPrettyLinkedTableMap("Key");
for (Entry>> entry : raw
.entrySet()) {
pretty.put(entry.getKey(),
Transformers.transformMapSet(entry.getValue(),
Conversions.thriftToJava(),
Conversions. none()));
}
return pretty;
});
}
@Override
public Map>> browse(Collection keys,
Timestamp timestamp) {
return execute(() -> {
Map>> raw;
if(timestamp.isString()) {
raw = client.browseKeysTimestr(Collections.toList(keys),
timestamp.toString(), creds, transaction, environment);
}
else {
raw = client.browseKeysTime(Collections.toList(keys),
timestamp.getMicros(), creds, transaction, environment);
}
Map>> pretty = PrettyLinkedTableMap
.newPrettyLinkedTableMap("Key");
for (Entry>> entry : raw
.entrySet()) {
pretty.put(entry.getKey(),
Transformers.transformMapSet(entry.getValue(),
Conversions.thriftToJava(),
Conversions. none()));
}
return pretty;
});
}
@Override
public Map