mirror of
https://github.com/apple/foundationdb.git
synced 2025-05-14 01:42:37 +08:00
add python bindings and revise test code
This commit is contained in:
parent
718119af83
commit
c683795f6b
91
TenantTest.java
Normal file
91
TenantTest.java
Normal file
@ -0,0 +1,91 @@
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import com.apple.foundationdb.Database;
|
||||
import com.apple.foundationdb.FDB;
|
||||
import com.apple.foundationdb.KeyValue;
|
||||
import com.apple.foundationdb.Tenant;
|
||||
import com.apple.foundationdb.Transaction;
|
||||
import com.apple.foundationdb.tuple.Tuple;
|
||||
import com.apple.foundationdb.KeyArrayResult;
|
||||
import com.apple.foundationdb.TenantManagement;
|
||||
import com.apple.foundationdb.async.AsyncUtil;
|
||||
import static com.apple.foundationdb.async.AsyncUtil.collectRemaining;
|
||||
import com.apple.foundationdb.async.CloseableAsyncIterator;
|
||||
|
||||
public class TenantTest {
|
||||
private FDB fdb;
|
||||
private Database db;
|
||||
CloseableAsyncIterator<KeyValue> tenants;
|
||||
|
||||
public TenantTest() {
|
||||
try {
|
||||
fdb = FDB.selectAPIVersion(710);
|
||||
fdb.options().setTraceEnable(null);
|
||||
db = fdb.open();
|
||||
///*
|
||||
Tuple t1 = Tuple.from("tenant");
|
||||
Tuple t2 = Tuple.from("tenant2");
|
||||
Tuple t3 = Tuple.from("tenant3");
|
||||
//*/
|
||||
/*
|
||||
byte[] t1 = Tuple.from("tenant").pack();
|
||||
byte[] t2 = Tuple.from("tenant2").pack();
|
||||
byte[] t3 = Tuple.from("tenant3").pack();
|
||||
*/
|
||||
System.out.println(t1);
|
||||
System.out.println(t2);
|
||||
System.out.println(t3);
|
||||
|
||||
TenantManagement.createTenant(db, t1).join();
|
||||
TenantManagement.createTenant(db, t2).join();
|
||||
TenantManagement.createTenant(db, t3).join();
|
||||
|
||||
tenants = TenantManagement.listTenants(db, Tuple.from("a").pack(), Tuple.from("z").pack(), 100);
|
||||
|
||||
try {
|
||||
/*
|
||||
List<KeyValue> result = AsyncUtil.collectRemaining(tenants).join();
|
||||
System.out.println("Size: " + result.size());
|
||||
for(int i = 0; i < result.size(); i++) {
|
||||
System.out.println(i);
|
||||
KeyValue res = result.get(i);
|
||||
System.out.println(new String(res.getKey()));
|
||||
System.out.println(new String(res.getValue()));
|
||||
}
|
||||
*/
|
||||
// /*
|
||||
while (tenants.hasNext()) {
|
||||
KeyValue res = tenants.next();
|
||||
System.out.println(new String(res.getKey()));
|
||||
System.out.println(new String(res.getValue()));
|
||||
}
|
||||
// */
|
||||
}
|
||||
finally {
|
||||
tenants.close();
|
||||
}
|
||||
TenantManagement.deleteTenant(db, t1).join();
|
||||
TenantManagement.deleteTenant(db, t2).join();
|
||||
TenantManagement.deleteTenant(db, t3).join();
|
||||
}
|
||||
catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
db.close();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new TenantTest().close();
|
||||
}
|
||||
}
|
||||
|
@ -219,23 +219,35 @@ public class TenantManagement {
|
||||
* @param begin The beginning of the range of tenants to list.
|
||||
* @param end The end of the range of the tenants to list.
|
||||
* @param limit The maximum number of tenants to return from this request.
|
||||
* @return an iterator where each item is a byte array with the tenant name and value.
|
||||
* @return an iterator where each item is a KeyValue object where the key is the tenant name
|
||||
* and the value is the unprocessed JSON string containing the tenant's metadata
|
||||
*/
|
||||
public static CloseableAsyncIterator<byte[]> listTenants(Database db, byte[] begin, byte[] end, int limit) {
|
||||
public static CloseableAsyncIterator<KeyValue> listTenants(Database db, byte[] begin, byte[] end, int limit) {
|
||||
return listTenants_internal(db.createTransaction(), begin, end, limit);
|
||||
}
|
||||
|
||||
public static CloseableAsyncIterator<byte[]> listTenants(Database db, Tuple begin, Tuple end, int limit) {
|
||||
/**
|
||||
* Lists all tenants in between the range specified. The number of tenants listed can be restricted.
|
||||
* This is a convenience method that generates the begin and end ranges by packing two {@code Tuple}s.
|
||||
*
|
||||
* @param db The database used to create a transaction for listing the tenants.
|
||||
* @param begin The beginning of the range of tenants to list.
|
||||
* @param end The end of the range of the tenants to list.
|
||||
* @param limit The maximum number of tenants to return from this request.
|
||||
* @return an iterator where each item is a KeyValue object where the key is the tenant name
|
||||
* and the value is the unprocessed JSON string containing the tenant's metadata
|
||||
*/
|
||||
public static CloseableAsyncIterator<KeyValue> listTenants(Database db, Tuple begin, Tuple end, int limit) {
|
||||
return listTenants_internal(db.createTransaction(), begin.pack(), end.pack(), limit);
|
||||
}
|
||||
|
||||
private static CloseableAsyncIterator<byte[]> listTenants_internal(Transaction tr, byte[] begin, byte[] end,
|
||||
private static CloseableAsyncIterator<KeyValue> listTenants_internal(Transaction tr, byte[] begin, byte[] end,
|
||||
int limit) {
|
||||
return new TenantAsyncIterator(tr, begin, end, limit);
|
||||
}
|
||||
|
||||
// Templates taken from BoundaryIterator LocalityUtil.java
|
||||
static class TenantAsyncIterator implements CloseableAsyncIterator<byte[]> {
|
||||
static class TenantAsyncIterator implements CloseableAsyncIterator<KeyValue> {
|
||||
Transaction tr;
|
||||
final byte[] begin;
|
||||
final byte[] end;
|
||||
@ -268,15 +280,12 @@ public class TenantManagement {
|
||||
return iter.hasNext();
|
||||
}
|
||||
@Override
|
||||
public byte[] next() {
|
||||
public KeyValue next() {
|
||||
KeyValue kv = iter.next();
|
||||
byte[] tenant = ByteArrayUtil.replace(kv.getKey(), 0, kv.getKey().length, TENANT_MAP_PREFIX, null);
|
||||
byte[] value = kv.getValue();
|
||||
|
||||
List<byte[]> parts = Arrays.asList(tenant, value);
|
||||
byte[] separator = ": ".getBytes();
|
||||
|
||||
byte[] result = ByteArrayUtil.join(separator, parts);
|
||||
KeyValue result = new KeyValue(tenant, value);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -71,6 +71,11 @@ import types
|
||||
import struct
|
||||
|
||||
|
||||
def remove_prefix(text, prefix):
|
||||
if text.startswith(prefix):
|
||||
return text[len(prefix):]
|
||||
return text
|
||||
|
||||
def option_wrap(code):
|
||||
def setfunc(self):
|
||||
self._parent._set_option(code, None, 0)
|
||||
|
@ -78,6 +78,41 @@ def _delete_tenant_impl(tr, tenant_name, existence_check_marker, force_existence
|
||||
|
||||
del tr[key]
|
||||
|
||||
class FDBTenantList(object):
|
||||
"""Iterates over the results of list_tenants query. Returns
|
||||
KeyValue objects.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, rangeresult):
|
||||
self._range = rangeresult
|
||||
self._iter = iter(self._range)
|
||||
|
||||
def to_list(self):
|
||||
return list(self.__iter__())
|
||||
|
||||
def __iter__(self, mode=None):
|
||||
while True:
|
||||
result = self._iter.__next__()
|
||||
|
||||
tenant_name = _impl.remove_prefix(result.key, _tenant_map_prefix)
|
||||
yield _impl.KeyValue(tenant_name, result.value)
|
||||
|
||||
# Lists the tenants created in the cluster, specified by the begin and end range.
|
||||
# Also limited in number of results by the limit parameter.
|
||||
# Returns an iterable object that yields KeyValue objects
|
||||
# where the keys are the tenant names and the values are the unprocessed
|
||||
# JSON strings of the tenant metadata
|
||||
@_impl.transactional
|
||||
def _list_tenants_impl(tr, begin, end, limit):
|
||||
tr.options.set_read_system_keys()
|
||||
begin_key = b'%s%s' % (_tenant_map_prefix, begin)
|
||||
end_key = b'%s%s' % (_tenant_map_prefix, end)
|
||||
|
||||
rangeresult = tr.get_range(begin_key, end_key, limit)
|
||||
|
||||
return FDBTenantList(rangeresult)
|
||||
|
||||
def create_tenant(db_or_tr, tenant_name):
|
||||
tenant_name = _impl.process_tenant_name(tenant_name)
|
||||
|
||||
@ -93,3 +128,9 @@ def delete_tenant(db_or_tr, tenant_name):
|
||||
# Callers using a transaction are expected to check existence themselves if required
|
||||
existence_check_marker = [] if not isinstance(db_or_tr, _impl.TransactionRead) else [None]
|
||||
_delete_tenant_impl(db_or_tr, tenant_name, existence_check_marker)
|
||||
|
||||
def list_tenants(db_or_tr, begin, end, limit):
|
||||
begin = _impl.process_tenant_name(begin)
|
||||
end = _impl.process_tenant_name(end)
|
||||
|
||||
return _list_tenants_impl(db_or_tr, begin, end, limit)
|
@ -980,7 +980,7 @@ ThreadFuture<MappedRangeResult> MultiVersionTransaction::getMappedRange(const Ke
|
||||
auto tr = getTransaction();
|
||||
auto f = tr.transaction ? tr.transaction->getMappedRange(begin, end, mapper, limits, snapshot, reverse)
|
||||
: makeTimeout<MappedRangeResult>();
|
||||
return abortableFuture(f, tr.onChange, cluster_version_changed());
|
||||
return abortableFuture(f, tr.onChange);
|
||||
}
|
||||
|
||||
ThreadFuture<Standalone<StringRef>> MultiVersionTransaction::getVersionstamp() {
|
||||
|
33
test_tenant.py
Executable file
33
test_tenant.py
Executable file
@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import fdb
|
||||
import sys
|
||||
|
||||
fdb.api_version(710)
|
||||
db=fdb.open()
|
||||
|
||||
db.options.set_transaction_timeout(2000)
|
||||
|
||||
#tenant = b'tenant'
|
||||
#tenant2 = b'tenant2'
|
||||
#tenant3 = b'tenant3'
|
||||
|
||||
tenant = (u"tenant",)
|
||||
tenant2 = (u"tenant2",)
|
||||
tenant3 = (u"tenant3",)
|
||||
|
||||
fdb.tenant_management.create_tenant(db, tenant)
|
||||
fdb.tenant_management.create_tenant(db, tenant2)
|
||||
fdb.tenant_management.create_tenant(db, tenant3)
|
||||
|
||||
res = fdb.tenant_management.list_tenants(db, (u"a",), (u"z",), 10)
|
||||
#res = fdb.tenant_management.list_tenants(db, b'a', b'z', 10)
|
||||
for t in res:
|
||||
print(t.key.decode())
|
||||
print(t.value.decode())
|
||||
|
||||
fdb.tenant_management.delete_tenant(db, tenant)
|
||||
fdb.tenant_management.delete_tenant(db, tenant2)
|
||||
fdb.tenant_management.delete_tenant(db, tenant3)
|
||||
|
||||
sys.exit(0)
|
Loading…
x
Reference in New Issue
Block a user