-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Documentation and code updates (#17)
* Moved namespace code from the Accumulo website to namespace_client.py * Renamed existing python client to basic_client.py * Moved Java client code/docs from website to docs/java_client.md * Updated README.md
- Loading branch information
Showing
4 changed files
with
261 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
<!-- | ||
Licensed to the Apache Software Foundation (ASF) under one or more | ||
contributor license agreements. See the NOTICE file distributed with | ||
this work for additional information regarding copyright ownership. | ||
The ASF licenses this file to You 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. | ||
--> | ||
|
||
# Java client | ||
|
||
After initiating a connection to the Proxy (see Apache Thrift's documentation for examples | ||
of connecting to a Thrift service), the methods on the proxy client will be available. The | ||
first thing to do is log in: | ||
|
||
```java | ||
Map password = new HashMap<String,String>(); | ||
password.put("password", "secret"); | ||
ByteBuffer token = client.login("root", password); | ||
``` | ||
|
||
Once logged in, the token returned will be used for most subsequent calls to the client. | ||
Let's create a table, add some data, scan the table, and delete it. | ||
|
||
First, create a table. | ||
|
||
```java | ||
client.createTable(token, "myTable", true, TimeType.MILLIS); | ||
``` | ||
|
||
Next, add some data: | ||
|
||
```java | ||
// first, create a writer on the server | ||
String writer = client.createWriter(token, "myTable", new WriterOptions()); | ||
|
||
//rowid | ||
ByteBuffer rowid = ByteBuffer.wrap("UUID".getBytes()); | ||
|
||
//mutation like class | ||
ColumnUpdate cu = new ColumnUpdate(); | ||
cu.setColFamily("MyFamily".getBytes()); | ||
cu.setColQualifier("MyQualifier".getBytes()); | ||
cu.setColVisibility("VisLabel".getBytes()); | ||
cu.setValue("Some Value.".getBytes()); | ||
|
||
List<ColumnUpdate> updates = new ArrayList<ColumnUpdate>(); | ||
updates.add(cu); | ||
|
||
// build column updates | ||
Map<ByteBuffer, List<ColumnUpdate>> cellsToUpdate = new HashMap<ByteBuffer, List<ColumnUpdate>>(); | ||
cellsToUpdate.put(rowid, updates); | ||
|
||
// send updates to the server | ||
client.updateAndFlush(writer, "myTable", cellsToUpdate); | ||
|
||
client.closeWriter(writer); | ||
``` | ||
|
||
Scan for the data and batch the return of the results on the server: | ||
|
||
```java | ||
String scanner = client.createScanner(token, "myTable", new ScanOptions()); | ||
ScanResult results = client.nextK(scanner, 100); | ||
|
||
for(KeyValue keyValue : results.getResultsIterator()) { | ||
// do something with results | ||
} | ||
|
||
client.closeScanner(scanner); | ||
``` | ||
|
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
# Licensed to the Apache Software Foundation (ASF) under one or more | ||
# contributor license agreements. See the NOTICE file distributed with | ||
# this work for additional information regarding copyright ownership. | ||
# The ASF licenses this file to You 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. | ||
|
||
#! /usr/bin/env python | ||
|
||
from thrift.protocol import TCompactProtocol | ||
from thrift.transport import TSocket, TTransport | ||
|
||
from accumulo import AccumuloProxy | ||
from accumulo.ttypes import NamespacePermission, IteratorSetting, IteratorScope, AccumuloException | ||
|
||
def main(): | ||
transport = TSocket.TSocket('localhost', 42424) | ||
transport = TTransport.TFramedTransport(transport) | ||
protocol = TCompactProtocol.TCompactProtocol(transport) | ||
client = AccumuloProxy.Client(protocol) | ||
transport.open() | ||
login = client.login('root', {'password': 'secret'}) | ||
|
||
client.createLocalUser(login, 'user1', 'password1') | ||
|
||
print client.listNamespaces(login) | ||
|
||
# create a namespace and give the user1 all permissions | ||
print 'creating namespace testing' | ||
client.createNamespace(login, 'testing') | ||
assert client.namespaceExists(login, 'testing') | ||
print client.listNamespaces(login) | ||
|
||
print 'testing namespace renaming' | ||
client.renameNamespace(login, 'testing', 'testing2') | ||
assert not client.namespaceExists(login, 'testing') | ||
assert client.namespaceExists(login, 'testing2') | ||
client.renameNamespace(login, 'testing2', 'testing') | ||
assert not client.namespaceExists(login, 'testing2') | ||
assert client.namespaceExists(login, 'testing') | ||
|
||
print 'granting all namespace permissions to user1' | ||
for k, v in NamespacePermission._VALUES_TO_NAMES.iteritems(): | ||
client.grantNamespacePermission(login, 'user1', 'testing', k) | ||
|
||
# make sure the last operation worked | ||
for k, v in NamespacePermission._VALUES_TO_NAMES.iteritems(): | ||
assert client.hasNamespacePermission(login, 'user1', 'testing', k), \ | ||
'user1 does\'nt have namespace permission %s' % v | ||
|
||
print 'default namespace: ' + client.defaultNamespace() | ||
print 'system namespace: ' + client.systemNamespace() | ||
|
||
# grab the namespace properties | ||
print 'retrieving namespace properties' | ||
props = client.getNamespaceProperties(login, 'testing') | ||
assert props and props['table.compaction.major.ratio'] == '3' | ||
|
||
# update a property and verify it is good | ||
print 'setting namespace property table.compaction.major.ratio = 4' | ||
client.setNamespaceProperty(login, 'testing', 'table.compaction.major.ratio', '4') | ||
props = client.getNamespaceProperties(login, 'testing') | ||
assert props and props['table.compaction.major.ratio'] == '4' | ||
|
||
print 'retrieving namespace ID map' | ||
nsids = client.namespaceIdMap(login) | ||
assert nsids and 'accumulo' in nsids | ||
|
||
print 'attaching debug iterator to namespace testing' | ||
setting = IteratorSetting(priority=40, name='DebugTheThings', | ||
iteratorClass='org.apache.accumulo.core.iterators.DebugIterator', properties={}) | ||
client.attachNamespaceIterator(login, 'testing', setting, [IteratorScope.SCAN]) | ||
setting = client.getNamespaceIteratorSetting(login, 'testing', 'DebugTheThings', IteratorScope.SCAN) | ||
assert setting and setting.name == 'DebugTheThings' | ||
|
||
# make sure the iterator is in the list | ||
iters = client.listNamespaceIterators(login, 'testing') | ||
found = False | ||
for name, scopes in iters.iteritems(): | ||
if name == 'DebugTheThings': | ||
found = True | ||
break | ||
assert found | ||
|
||
print 'checking for iterator conflicts' | ||
|
||
# this next statment should be fine since we are on a different scope | ||
client.checkNamespaceIteratorConflicts(login, 'testing', setting, [IteratorScope.MINC]) | ||
|
||
# this time it should throw an exception since we have already added the iterator with this scope | ||
try: | ||
client.checkNamespaceIteratorConflicts(login, 'testing', setting, [IteratorScope.SCAN, IteratorScope.MINC]) | ||
except AccumuloException: | ||
pass | ||
else: | ||
assert False, 'There should have been a namespace iterator conflict!' | ||
|
||
print 'removing debug iterator from namespace testing' | ||
client.removeNamespaceIterator(login, 'testing', 'DebugTheThings', [IteratorScope.SCAN]) | ||
|
||
# make sure the iterator is NOT in the list anymore | ||
iters = client.listNamespaceIterators(login, 'testing') | ||
found = False | ||
for name, scopes in iters.iteritems(): | ||
if name == 'DebugTheThings': | ||
found = True | ||
break | ||
assert not found | ||
|
||
print 'adding max mutation size namespace constraint' | ||
constraintid = client.addNamespaceConstraint(login, 'testing', | ||
'org.apache.accumulo.test.constraints.MaxMutationSize') | ||
|
||
print 'make sure constraint was added' | ||
constraints = client.listNamespaceConstraints(login, 'testing') | ||
found = False | ||
for name, cid in constraints.iteritems(): | ||
if cid == constraintid and name == 'org.apache.accumulo.test.constraints.MaxMutationSize': | ||
found = True | ||
break | ||
assert found | ||
|
||
print 'remove max mutation size namespace constraint' | ||
client.removeNamespaceConstraint(login, 'testing', constraintid) | ||
|
||
print 'make sure constraint was removed' | ||
constraints = client.listNamespaceConstraints(login, 'testing') | ||
found = False | ||
for name, cid in constraints.iteritems(): | ||
if cid == constraintid and name == 'org.apache.accumulo.test.constraints.MaxMutationSize': | ||
found = True | ||
break | ||
assert not found | ||
|
||
print 'test a namespace class load of the VersioningIterator' | ||
res = client.testNamespaceClassLoad(login, 'testing', 'org.apache.accumulo.core.iterators.user.VersioningIterator', | ||
'org.apache.accumulo.core.iterators.SortedKeyValueIterator') | ||
assert res | ||
|
||
print 'test a bad namespace class load of the VersioningIterator' | ||
res = client.testNamespaceClassLoad(login, 'testing', 'org.apache.accumulo.core.iterators.user.VersioningIterator', | ||
'dummy') | ||
assert not res | ||
|
||
# revoke the permissions | ||
print 'revoking namespace permissions for user1' | ||
for k, v in NamespacePermission._VALUES_TO_NAMES.iteritems(): | ||
client.revokeNamespacePermission(login, 'user1', 'testing', k) | ||
|
||
# make sure the last operation worked | ||
for k, v in NamespacePermission._VALUES_TO_NAMES.iteritems(): | ||
assert not client.hasNamespacePermission(login, 'user1', 'testing', k), \ | ||
'user1 does\'nt have namespace permission %s' % v | ||
|
||
print 'deleting namespace testing' | ||
client.deleteNamespace(login, 'testing') | ||
assert not client.namespaceExists(login, 'testing') | ||
|
||
print 'deleting user1' | ||
client.dropLocalUser(login, 'user1') | ||
|
||
if __name__ == "__main__": | ||
main() |