├── src ├── main │ ├── python │ │ ├── accumulo │ │ │ ├── .gitignore │ │ │ ├── __init__.py │ │ │ └── constants.py │ │ ├── .gitignore │ │ ├── setup.py │ │ ├── basic_client.py │ │ └── namespace_client.py │ ├── ruby │ │ ├── Gemfile │ │ ├── accumulo │ │ │ ├── lib │ │ │ │ └── proxy_constants.rb │ │ │ └── accumulo.gemspec │ │ └── client.rb │ ├── assemble │ │ ├── conf │ │ │ ├── proxy-env.sh │ │ │ └── proxy.properties │ │ ├── bin │ │ │ └── accumulo-proxy │ │ ├── binary-release.xml │ │ └── component.xml │ ├── spotbugs │ │ └── exclude-filter.xml │ ├── thrift-gen-java │ │ └── org │ │ │ └── apache │ │ │ └── accumulo │ │ │ └── proxy │ │ │ └── thrift │ │ │ ├── ScanType.java │ │ │ ├── TimeType.java │ │ │ ├── ScanState.java │ │ │ ├── IteratorScope.java │ │ │ ├── CompactionType.java │ │ │ ├── Durability.java │ │ │ ├── CompactionReason.java │ │ │ ├── ConditionalStatus.java │ │ │ ├── TablePermission.java │ │ │ ├── PartialKey.java │ │ │ ├── NamespacePermission.java │ │ │ ├── SystemPermission.java │ │ │ ├── UnknownWriter.java │ │ │ ├── UnknownScanner.java │ │ │ ├── AccumuloException.java │ │ │ └── TableExistsException.java │ ├── java │ │ └── org │ │ │ └── apache │ │ │ └── accumulo │ │ │ └── proxy │ │ │ ├── Util.java │ │ │ └── Proxy.java │ └── scripts │ │ └── generate-thrift.sh └── test │ ├── thrift │ └── test.thrift │ ├── java │ └── org │ │ └── apache │ │ └── accumulo │ │ └── proxy │ │ ├── its │ │ ├── TBinaryProxyIT.java │ │ ├── TTupleProxyIT.java │ │ ├── TCompactProxyIT.java │ │ ├── TJsonProtocolProxyIT.java │ │ ├── ProxyDurabilityIT.java │ │ └── TestProxyClient.java │ │ └── ProxyServerTest.java │ └── resources │ └── log4j2-test.properties ├── NOTICE ├── contrib ├── license-header.txt └── create-release-candidate.sh ├── .gitattributes ├── .gitignore ├── .asf.yaml ├── docs └── java_client.md ├── .github └── workflows │ └── maven.yaml ├── Dockerfile ├── README.md ├── DOCKER.md └── LICENSE /src/main/python/accumulo/.gitignore: -------------------------------------------------------------------------------- 1 | AccumuloProxy.egg-info/ 2 | -------------------------------------------------------------------------------- /src/main/python/.gitignore: -------------------------------------------------------------------------------- 1 | AccumuloProxy.egg-info/ 2 | pyproject.toml 3 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Apache Accumulo Proxy 2 | Copyright 2013-2025 The Apache Software Foundation 3 | 4 | This product includes software developed at 5 | The Apache Software Foundation (https://www.apache.org/). 6 | -------------------------------------------------------------------------------- /contrib/license-header.txt: -------------------------------------------------------------------------------- 1 | Licensed to the Apache Software Foundation (ASF) under one 2 | or more contributor license agreements. See the NOTICE file 3 | distributed with this work for additional information 4 | regarding copyright ownership. The ASF licenses this file 5 | to you under the Apache License, Version 2.0 (the 6 | "License"); you may not use this file except in compliance 7 | with the License. You may obtain a copy of the License at 8 | 9 | https://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, 12 | software distributed under the License is distributed on an 13 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | KIND, either express or implied. See the License for the 15 | specific language governing permissions and limitations 16 | under the License. 17 | -------------------------------------------------------------------------------- /src/main/python/accumulo/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, 13 | # software distributed under the License is distributed on an 14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | # KIND, either express or implied. See the License for the 16 | # specific language governing permissions and limitations 17 | # under the License. 18 | # 19 | 20 | __all__ = ['ttypes', 'constants', 'AccumuloProxy'] 21 | -------------------------------------------------------------------------------- /src/main/ruby/Gemfile: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, 13 | # software distributed under the License is distributed on an 14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | # KIND, either express or implied. See the License for the 16 | # specific language governing permissions and limitations 17 | # under the License. 18 | # 19 | 20 | ruby '>2.5' 21 | source "https://rubygems.org" 22 | gem 'thrift', '0.17.0' 23 | gem 'accumulo', :path => "/path/to/accumulo-proxy/src/main/ruby/accumulo" 24 | -------------------------------------------------------------------------------- /src/main/assemble/conf/proxy-env.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | # 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # 20 | 21 | CONF_DIR=$(readlink -f ./conf) 22 | LIB_DIR=./lib 23 | 24 | CLASSPATH="$CONF_DIR:$LIB_DIR/*:$(accumulo classpath)" 25 | export CLASSPATH 26 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, 13 | # software distributed under the License is distributed on an 14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | # KIND, either express or implied. See the License for the 16 | # specific language governing permissions and limitations 17 | # under the License. 18 | # 19 | 20 | src/main/thrift-gen-java/** linguist-generated=true 21 | src/main/cpp/** linguist-generated=true 22 | src/main/python/accumulo/** linguist-generated=true 23 | src/main/ruby/accumulo/lib/** linguist-generated=true 24 | -------------------------------------------------------------------------------- /src/main/assemble/bin/accumulo-proxy: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | # 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # 20 | 21 | BIN_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) 22 | 23 | cd $BIN_DIR/.. 24 | 25 | . conf/proxy-env.sh 26 | 27 | java org.apache.accumulo.proxy.Proxy "${@}" 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, 13 | # software distributed under the License is distributed on an 14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | # KIND, either express or implied. See the License for the 16 | # specific language governing permissions and limitations 17 | # under the License. 18 | # 19 | 20 | # Maven ignores 21 | /target/ 22 | 23 | # IDE ignores 24 | /.settings/ 25 | /.project 26 | /.classpath 27 | /.pydevproject 28 | /.idea 29 | /*.iml 30 | /nbproject/ 31 | /nbactions.xml 32 | /nb-configuration.xml 33 | 34 | # python ignores 35 | *.pyc 36 | -------------------------------------------------------------------------------- /src/main/ruby/accumulo/lib/proxy_constants.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, 13 | # software distributed under the License is distributed on an 14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | # KIND, either express or implied. See the License for the 16 | # specific language governing permissions and limitations 17 | # under the License. 18 | # 19 | 20 | # 21 | # Autogenerated by Thrift Compiler (0.17.0) 22 | # 23 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 24 | # 25 | 26 | require 'thrift' 27 | require 'proxy_types' 28 | 29 | module Accumulo 30 | end 31 | -------------------------------------------------------------------------------- /src/main/python/setup.py: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, 13 | # software distributed under the License is distributed on an 14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | # KIND, either express or implied. See the License for the 16 | # specific language governing permissions and limitations 17 | # under the License. 18 | # 19 | 20 | from distutils.core import setup 21 | 22 | setup( 23 | name='AccumuloProxy', 24 | version='2.0.0', 25 | packages=['accumulo',], 26 | license='Apache License, Version 2.0', 27 | long_description=open('../../../README.md').read(), 28 | ) 29 | -------------------------------------------------------------------------------- /.asf.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, 13 | # software distributed under the License is distributed on an 14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | # KIND, either express or implied. See the License for the 16 | # specific language governing permissions and limitations 17 | # under the License. 18 | # 19 | 20 | # https://cwiki.apache.org/confluence/display/INFRA/git+-+.asf.yaml+features 21 | 22 | github: 23 | description: "Apache Accumulo Proxy" 24 | homepage: https://accumulo.apache.org 25 | labels: 26 | - accumulo 27 | - big-data 28 | - hacktoberfest 29 | - thrift 30 | features: 31 | wiki: false 32 | issues: true 33 | projects: true 34 | 35 | -------------------------------------------------------------------------------- /src/test/thrift/test.thrift: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | namespace java org.apache.accumulo.test.rpc.thrift 20 | 21 | service SimpleThriftService { 22 | 23 | string echoPass(1:string value) 24 | oneway void onewayPass(1:string value) 25 | 26 | string echoFail(1:string value) 27 | oneway void onewayFail(1:string value) 28 | 29 | string echoRuntimeFail(1:string value) 30 | oneway void onewayRuntimeFail(1:string value) 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/python/accumulo/constants.py: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, 13 | # software distributed under the License is distributed on an 14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | # KIND, either express or implied. See the License for the 16 | # specific language governing permissions and limitations 17 | # under the License. 18 | # 19 | 20 | # 21 | # Autogenerated by Thrift Compiler (0.17.0) 22 | # 23 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 24 | # 25 | # options string: py 26 | # 27 | 28 | from thrift.Thrift import TType, TMessageType, TFrozenDict, TException, TApplicationException 29 | from thrift.protocol.TProtocol import TProtocolException 30 | from thrift.TRecursive import fix_spec 31 | 32 | import sys 33 | from .ttypes import * 34 | -------------------------------------------------------------------------------- /src/test/java/org/apache/accumulo/proxy/its/TBinaryProxyIT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package org.apache.accumulo.proxy.its; 20 | 21 | import org.apache.accumulo.harness.SharedMiniClusterBase; 22 | import org.apache.thrift.protocol.TBinaryProtocol; 23 | import org.junit.jupiter.api.BeforeAll; 24 | 25 | public class TBinaryProxyIT extends SimpleProxyBase { 26 | 27 | @BeforeAll 28 | public static void setProtocol() throws Exception { 29 | SharedMiniClusterBase.startMiniClusterWithConfig(new TestConfig()); 30 | SimpleProxyBase.factory = new TBinaryProtocol.Factory(); 31 | setUpProxy(); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/org/apache/accumulo/proxy/its/TTupleProxyIT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package org.apache.accumulo.proxy.its; 20 | 21 | import org.apache.accumulo.harness.SharedMiniClusterBase; 22 | import org.apache.thrift.protocol.TTupleProtocol; 23 | import org.junit.jupiter.api.BeforeAll; 24 | 25 | public class TTupleProxyIT extends SimpleProxyBase { 26 | 27 | @BeforeAll 28 | public static void setProtocol() throws Exception { 29 | SharedMiniClusterBase.startMiniClusterWithConfig(new TestConfig()); 30 | SimpleProxyBase.factory = new TTupleProtocol.Factory(); 31 | setUpProxy(); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/org/apache/accumulo/proxy/its/TCompactProxyIT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package org.apache.accumulo.proxy.its; 20 | 21 | import org.apache.accumulo.harness.SharedMiniClusterBase; 22 | import org.apache.thrift.protocol.TCompactProtocol; 23 | import org.junit.jupiter.api.BeforeAll; 24 | 25 | public class TCompactProxyIT extends SimpleProxyBase { 26 | 27 | @BeforeAll 28 | public static void setProtocol() throws Exception { 29 | SharedMiniClusterBase.startMiniClusterWithConfig(new TestConfig()); 30 | SimpleProxyBase.factory = new TCompactProtocol.Factory(); 31 | setUpProxy(); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/ruby/accumulo/accumulo.gemspec: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, 13 | # software distributed under the License is distributed on an 14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | # KIND, either express or implied. See the License for the 16 | # specific language governing permissions and limitations 17 | # under the License. 18 | # 19 | 20 | Gem::Specification.new do |s| 21 | s.name = 'accumulo' 22 | s.version = '1.0.0' 23 | s.date = '2019-12-18' 24 | s.summary = "Accumulo Client library using Proxy" 25 | s.description = "Code that lets you communicate with Accumulo using the Proxy" 26 | s.authors = ["Apache Accumulo committers"] 27 | s.email = 'user@accumulo.apache.org' 28 | s.files = ["lib/accumulo_proxy.rb", "lib/proxy_types.rb", "lib/proxy_constants.rb"] 29 | s.homepage = 'https://github.com/apache/accumulo-proxy' 30 | s.license = 'Apache-2.0' 31 | end 32 | -------------------------------------------------------------------------------- /src/test/java/org/apache/accumulo/proxy/its/TJsonProtocolProxyIT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package org.apache.accumulo.proxy.its; 20 | 21 | import org.apache.accumulo.harness.SharedMiniClusterBase; 22 | import org.apache.thrift.protocol.TJSONProtocol; 23 | import org.junit.jupiter.api.BeforeAll; 24 | 25 | public class TJsonProtocolProxyIT extends SimpleProxyBase { 26 | 27 | @BeforeAll 28 | public static void setProtocol() throws Exception { 29 | SharedMiniClusterBase.startMiniClusterWithConfig(new TestConfig()); 30 | SimpleProxyBase.factory = new TJSONProtocol.Factory(); 31 | setUpProxy(); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/assemble/binary-release.xml: -------------------------------------------------------------------------------- 1 | 2 | 22 | 24 | bin 25 | 26 | tar.gz 27 | 28 | 29 | src/main/assemble/component.xml 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/main/spotbugs/exclude-filter.xml: -------------------------------------------------------------------------------- 1 | 21 | 22 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/main/python/basic_client.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # 20 | 21 | import sys 22 | 23 | from thrift import Thrift 24 | from thrift.transport import TSocket 25 | from thrift.transport import TTransport 26 | from thrift.protocol import TCompactProtocol 27 | 28 | from accumulo import AccumuloProxy 29 | from accumulo.ttypes import * 30 | 31 | transport = TSocket.TSocket('localhost', 42424) 32 | transport = TTransport.TFramedTransport(transport) 33 | protocol = TCompactProtocol.TCompactProtocol(transport) 34 | client = AccumuloProxy.Client(protocol) 35 | transport.open() 36 | 37 | login = "sharedSecret" 38 | 39 | print client.listTables(login) 40 | 41 | testtable = "pythontest" 42 | if not client.tableExists(login, testtable): 43 | client.createTable(login, testtable, True, TimeType.MILLIS) 44 | 45 | row1 = {'a':[ColumnUpdate('a','a',value='value1'), ColumnUpdate('b','b',value='value2')]} 46 | client.updateAndFlush(login, testtable, row1) 47 | 48 | cookie = client.createScanner(login, testtable, None) 49 | for entry in client.nextK(cookie, 10).results: 50 | print entry 51 | -------------------------------------------------------------------------------- /src/main/thrift-gen-java/org/apache/accumulo/proxy/thrift/ScanType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | /** 20 | * Autogenerated by Thrift Compiler (0.17.0) 21 | * 22 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 23 | * @generated 24 | */ 25 | package org.apache.accumulo.proxy.thrift; 26 | 27 | 28 | public enum ScanType implements org.apache.thrift.TEnum { 29 | SINGLE(0), 30 | BATCH(1); 31 | 32 | private final int value; 33 | 34 | private ScanType(int value) { 35 | this.value = value; 36 | } 37 | 38 | /** 39 | * Get the integer value of this enum value, as defined in the Thrift IDL. 40 | */ 41 | @Override 42 | public int getValue() { 43 | return value; 44 | } 45 | 46 | /** 47 | * Find a the enum type by its integer value, as defined in the Thrift IDL. 48 | * @return null if the value is not found. 49 | */ 50 | @org.apache.thrift.annotation.Nullable 51 | public static ScanType findByValue(int value) { 52 | switch (value) { 53 | case 0: 54 | return SINGLE; 55 | case 1: 56 | return BATCH; 57 | default: 58 | return null; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/thrift-gen-java/org/apache/accumulo/proxy/thrift/TimeType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | /** 20 | * Autogenerated by Thrift Compiler (0.17.0) 21 | * 22 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 23 | * @generated 24 | */ 25 | package org.apache.accumulo.proxy.thrift; 26 | 27 | 28 | public enum TimeType implements org.apache.thrift.TEnum { 29 | LOGICAL(0), 30 | MILLIS(1); 31 | 32 | private final int value; 33 | 34 | private TimeType(int value) { 35 | this.value = value; 36 | } 37 | 38 | /** 39 | * Get the integer value of this enum value, as defined in the Thrift IDL. 40 | */ 41 | @Override 42 | public int getValue() { 43 | return value; 44 | } 45 | 46 | /** 47 | * Find a the enum type by its integer value, as defined in the Thrift IDL. 48 | * @return null if the value is not found. 49 | */ 50 | @org.apache.thrift.annotation.Nullable 51 | public static TimeType findByValue(int value) { 52 | switch (value) { 53 | case 0: 54 | return LOGICAL; 55 | case 1: 56 | return MILLIS; 57 | default: 58 | return null; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/ruby/client.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # 20 | 21 | require 'rubygems' 22 | require 'thrift' 23 | require 'accumulo_proxy' 24 | 25 | server = ARGV[0] || 'localhost' 26 | 27 | socket = Thrift::Socket.new(server, 42424, 9001) 28 | transport = Thrift::FramedTransport.new(socket) 29 | proto = Thrift::CompactProtocol.new(transport) 30 | proxy = Accumulo::AccumuloProxy::Client.new(proto) 31 | 32 | # open up the connect 33 | transport.open() 34 | 35 | login = "sharedSecret" 36 | 37 | # print out a table list 38 | puts "List of tables: #{proxy.listTables(login).inspect}" 39 | 40 | testtable = "rubytest" 41 | proxy.createTable(login, testtable, true, Accumulo::TimeType::MILLIS) unless proxy.tableExists(login,testtable) 42 | 43 | update1 = Accumulo::ColumnUpdate.new({'colFamily' => "cf1", 'colQualifier' => "cq1", 'value'=> "a"}) 44 | update2 = Accumulo::ColumnUpdate.new({'colFamily' => "cf2", 'colQualifier' => "cq2", 'value'=> "b"}) 45 | proxy.updateAndFlush(login,testtable,{'row1' => [update1,update2]}) 46 | 47 | cookie = proxy.createScanner(login,testtable,nil) 48 | result = proxy.nextK(cookie,10) 49 | result.results.each{ |keyvalue| puts "Key: #{keyvalue.key.inspect} Value: #{keyvalue.value}" } 50 | -------------------------------------------------------------------------------- /src/main/thrift-gen-java/org/apache/accumulo/proxy/thrift/ScanState.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | /** 20 | * Autogenerated by Thrift Compiler (0.17.0) 21 | * 22 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 23 | * @generated 24 | */ 25 | package org.apache.accumulo.proxy.thrift; 26 | 27 | 28 | public enum ScanState implements org.apache.thrift.TEnum { 29 | IDLE(0), 30 | RUNNING(1), 31 | QUEUED(2); 32 | 33 | private final int value; 34 | 35 | private ScanState(int value) { 36 | this.value = value; 37 | } 38 | 39 | /** 40 | * Get the integer value of this enum value, as defined in the Thrift IDL. 41 | */ 42 | @Override 43 | public int getValue() { 44 | return value; 45 | } 46 | 47 | /** 48 | * Find a the enum type by its integer value, as defined in the Thrift IDL. 49 | * @return null if the value is not found. 50 | */ 51 | @org.apache.thrift.annotation.Nullable 52 | public static ScanState findByValue(int value) { 53 | switch (value) { 54 | case 0: 55 | return IDLE; 56 | case 1: 57 | return RUNNING; 58 | case 2: 59 | return QUEUED; 60 | default: 61 | return null; 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/thrift-gen-java/org/apache/accumulo/proxy/thrift/IteratorScope.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | /** 20 | * Autogenerated by Thrift Compiler (0.17.0) 21 | * 22 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 23 | * @generated 24 | */ 25 | package org.apache.accumulo.proxy.thrift; 26 | 27 | 28 | public enum IteratorScope implements org.apache.thrift.TEnum { 29 | MINC(0), 30 | MAJC(1), 31 | SCAN(2); 32 | 33 | private final int value; 34 | 35 | private IteratorScope(int value) { 36 | this.value = value; 37 | } 38 | 39 | /** 40 | * Get the integer value of this enum value, as defined in the Thrift IDL. 41 | */ 42 | @Override 43 | public int getValue() { 44 | return value; 45 | } 46 | 47 | /** 48 | * Find a the enum type by its integer value, as defined in the Thrift IDL. 49 | * @return null if the value is not found. 50 | */ 51 | @org.apache.thrift.annotation.Nullable 52 | public static IteratorScope findByValue(int value) { 53 | switch (value) { 54 | case 0: 55 | return MINC; 56 | case 1: 57 | return MAJC; 58 | case 2: 59 | return SCAN; 60 | default: 61 | return null; 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/thrift-gen-java/org/apache/accumulo/proxy/thrift/CompactionType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | /** 20 | * Autogenerated by Thrift Compiler (0.17.0) 21 | * 22 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 23 | * @generated 24 | */ 25 | package org.apache.accumulo.proxy.thrift; 26 | 27 | 28 | public enum CompactionType implements org.apache.thrift.TEnum { 29 | MINOR(0), 30 | MERGE(1), 31 | MAJOR(2), 32 | FULL(3); 33 | 34 | private final int value; 35 | 36 | private CompactionType(int value) { 37 | this.value = value; 38 | } 39 | 40 | /** 41 | * Get the integer value of this enum value, as defined in the Thrift IDL. 42 | */ 43 | @Override 44 | public int getValue() { 45 | return value; 46 | } 47 | 48 | /** 49 | * Find a the enum type by its integer value, as defined in the Thrift IDL. 50 | * @return null if the value is not found. 51 | */ 52 | @org.apache.thrift.annotation.Nullable 53 | public static CompactionType findByValue(int value) { 54 | switch (value) { 55 | case 0: 56 | return MINOR; 57 | case 1: 58 | return MERGE; 59 | case 2: 60 | return MAJOR; 61 | case 3: 62 | return FULL; 63 | default: 64 | return null; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/thrift-gen-java/org/apache/accumulo/proxy/thrift/Durability.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | /** 20 | * Autogenerated by Thrift Compiler (0.17.0) 21 | * 22 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 23 | * @generated 24 | */ 25 | package org.apache.accumulo.proxy.thrift; 26 | 27 | 28 | public enum Durability implements org.apache.thrift.TEnum { 29 | DEFAULT(0), 30 | NONE(1), 31 | LOG(2), 32 | FLUSH(3), 33 | SYNC(4); 34 | 35 | private final int value; 36 | 37 | private Durability(int value) { 38 | this.value = value; 39 | } 40 | 41 | /** 42 | * Get the integer value of this enum value, as defined in the Thrift IDL. 43 | */ 44 | @Override 45 | public int getValue() { 46 | return value; 47 | } 48 | 49 | /** 50 | * Find a the enum type by its integer value, as defined in the Thrift IDL. 51 | * @return null if the value is not found. 52 | */ 53 | @org.apache.thrift.annotation.Nullable 54 | public static Durability findByValue(int value) { 55 | switch (value) { 56 | case 0: 57 | return DEFAULT; 58 | case 1: 59 | return NONE; 60 | case 2: 61 | return LOG; 62 | case 3: 63 | return FLUSH; 64 | case 4: 65 | return SYNC; 66 | default: 67 | return null; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/thrift-gen-java/org/apache/accumulo/proxy/thrift/CompactionReason.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | /** 20 | * Autogenerated by Thrift Compiler (0.17.0) 21 | * 22 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 23 | * @generated 24 | */ 25 | package org.apache.accumulo.proxy.thrift; 26 | 27 | 28 | public enum CompactionReason implements org.apache.thrift.TEnum { 29 | USER(0), 30 | SYSTEM(1), 31 | CHOP(2), 32 | IDLE(3), 33 | CLOSE(4); 34 | 35 | private final int value; 36 | 37 | private CompactionReason(int value) { 38 | this.value = value; 39 | } 40 | 41 | /** 42 | * Get the integer value of this enum value, as defined in the Thrift IDL. 43 | */ 44 | @Override 45 | public int getValue() { 46 | return value; 47 | } 48 | 49 | /** 50 | * Find a the enum type by its integer value, as defined in the Thrift IDL. 51 | * @return null if the value is not found. 52 | */ 53 | @org.apache.thrift.annotation.Nullable 54 | public static CompactionReason findByValue(int value) { 55 | switch (value) { 56 | case 0: 57 | return USER; 58 | case 1: 59 | return SYSTEM; 60 | case 2: 61 | return CHOP; 62 | case 3: 63 | return IDLE; 64 | case 4: 65 | return CLOSE; 66 | default: 67 | return null; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/thrift-gen-java/org/apache/accumulo/proxy/thrift/ConditionalStatus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | /** 20 | * Autogenerated by Thrift Compiler (0.17.0) 21 | * 22 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 23 | * @generated 24 | */ 25 | package org.apache.accumulo.proxy.thrift; 26 | 27 | 28 | public enum ConditionalStatus implements org.apache.thrift.TEnum { 29 | ACCEPTED(0), 30 | REJECTED(1), 31 | VIOLATED(2), 32 | UNKNOWN(3), 33 | INVISIBLE_VISIBILITY(4); 34 | 35 | private final int value; 36 | 37 | private ConditionalStatus(int value) { 38 | this.value = value; 39 | } 40 | 41 | /** 42 | * Get the integer value of this enum value, as defined in the Thrift IDL. 43 | */ 44 | @Override 45 | public int getValue() { 46 | return value; 47 | } 48 | 49 | /** 50 | * Find a the enum type by its integer value, as defined in the Thrift IDL. 51 | * @return null if the value is not found. 52 | */ 53 | @org.apache.thrift.annotation.Nullable 54 | public static ConditionalStatus findByValue(int value) { 55 | switch (value) { 56 | case 0: 57 | return ACCEPTED; 58 | case 1: 59 | return REJECTED; 60 | case 2: 61 | return VIOLATED; 62 | case 3: 63 | return UNKNOWN; 64 | case 4: 65 | return INVISIBLE_VISIBILITY; 66 | default: 67 | return null; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/thrift-gen-java/org/apache/accumulo/proxy/thrift/TablePermission.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | /** 20 | * Autogenerated by Thrift Compiler (0.17.0) 21 | * 22 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 23 | * @generated 24 | */ 25 | package org.apache.accumulo.proxy.thrift; 26 | 27 | 28 | public enum TablePermission implements org.apache.thrift.TEnum { 29 | READ(2), 30 | WRITE(3), 31 | BULK_IMPORT(4), 32 | ALTER_TABLE(5), 33 | GRANT(6), 34 | DROP_TABLE(7); 35 | 36 | private final int value; 37 | 38 | private TablePermission(int value) { 39 | this.value = value; 40 | } 41 | 42 | /** 43 | * Get the integer value of this enum value, as defined in the Thrift IDL. 44 | */ 45 | @Override 46 | public int getValue() { 47 | return value; 48 | } 49 | 50 | /** 51 | * Find a the enum type by its integer value, as defined in the Thrift IDL. 52 | * @return null if the value is not found. 53 | */ 54 | @org.apache.thrift.annotation.Nullable 55 | public static TablePermission findByValue(int value) { 56 | switch (value) { 57 | case 2: 58 | return READ; 59 | case 3: 60 | return WRITE; 61 | case 4: 62 | return BULK_IMPORT; 63 | case 5: 64 | return ALTER_TABLE; 65 | case 6: 66 | return GRANT; 67 | case 7: 68 | return DROP_TABLE; 69 | default: 70 | return null; 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/thrift-gen-java/org/apache/accumulo/proxy/thrift/PartialKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | /** 20 | * Autogenerated by Thrift Compiler (0.17.0) 21 | * 22 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 23 | * @generated 24 | */ 25 | package org.apache.accumulo.proxy.thrift; 26 | 27 | 28 | public enum PartialKey implements org.apache.thrift.TEnum { 29 | ROW(0), 30 | ROW_COLFAM(1), 31 | ROW_COLFAM_COLQUAL(2), 32 | ROW_COLFAM_COLQUAL_COLVIS(3), 33 | ROW_COLFAM_COLQUAL_COLVIS_TIME(4), 34 | ROW_COLFAM_COLQUAL_COLVIS_TIME_DEL(5); 35 | 36 | private final int value; 37 | 38 | private PartialKey(int value) { 39 | this.value = value; 40 | } 41 | 42 | /** 43 | * Get the integer value of this enum value, as defined in the Thrift IDL. 44 | */ 45 | @Override 46 | public int getValue() { 47 | return value; 48 | } 49 | 50 | /** 51 | * Find a the enum type by its integer value, as defined in the Thrift IDL. 52 | * @return null if the value is not found. 53 | */ 54 | @org.apache.thrift.annotation.Nullable 55 | public static PartialKey findByValue(int value) { 56 | switch (value) { 57 | case 0: 58 | return ROW; 59 | case 1: 60 | return ROW_COLFAM; 61 | case 2: 62 | return ROW_COLFAM_COLQUAL; 63 | case 3: 64 | return ROW_COLFAM_COLQUAL_COLVIS; 65 | case 4: 66 | return ROW_COLFAM_COLQUAL_COLVIS_TIME; 67 | case 5: 68 | return ROW_COLFAM_COLQUAL_COLVIS_TIME_DEL; 69 | default: 70 | return null; 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/thrift-gen-java/org/apache/accumulo/proxy/thrift/NamespacePermission.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | /** 20 | * Autogenerated by Thrift Compiler (0.17.0) 21 | * 22 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 23 | * @generated 24 | */ 25 | package org.apache.accumulo.proxy.thrift; 26 | 27 | 28 | public enum NamespacePermission implements org.apache.thrift.TEnum { 29 | READ(0), 30 | WRITE(1), 31 | ALTER_NAMESPACE(2), 32 | GRANT(3), 33 | ALTER_TABLE(4), 34 | CREATE_TABLE(5), 35 | DROP_TABLE(6), 36 | BULK_IMPORT(7), 37 | DROP_NAMESPACE(8); 38 | 39 | private final int value; 40 | 41 | private NamespacePermission(int value) { 42 | this.value = value; 43 | } 44 | 45 | /** 46 | * Get the integer value of this enum value, as defined in the Thrift IDL. 47 | */ 48 | @Override 49 | public int getValue() { 50 | return value; 51 | } 52 | 53 | /** 54 | * Find a the enum type by its integer value, as defined in the Thrift IDL. 55 | * @return null if the value is not found. 56 | */ 57 | @org.apache.thrift.annotation.Nullable 58 | public static NamespacePermission findByValue(int value) { 59 | switch (value) { 60 | case 0: 61 | return READ; 62 | case 1: 63 | return WRITE; 64 | case 2: 65 | return ALTER_NAMESPACE; 66 | case 3: 67 | return GRANT; 68 | case 4: 69 | return ALTER_TABLE; 70 | case 5: 71 | return CREATE_TABLE; 72 | case 6: 73 | return DROP_TABLE; 74 | case 7: 75 | return BULK_IMPORT; 76 | case 8: 77 | return DROP_NAMESPACE; 78 | default: 79 | return null; 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /docs/java_client.md: -------------------------------------------------------------------------------- 1 | 21 | 22 | # Java client 23 | 24 | After initiating a connection to the Proxy (see Apache Thrift's documentation for examples 25 | of connecting to a Thrift service), the methods on the proxy client will be available. A shared 26 | secret will be used to authenticate to the proxy server: 27 | 28 | ```java 29 | String sharedSecret = "sharedSecret"; 30 | ``` 31 | 32 | The shared secret will be used for most subsequent calls to the client. 33 | Let's create a table, add some data, scan the table, and delete it. 34 | 35 | First, create a table. 36 | 37 | ```java 38 | client.createTable(sharedSecret, "myTable", true, TimeType.MILLIS); 39 | ``` 40 | 41 | Next, add some data: 42 | 43 | ```java 44 | // first, create a writer on the server 45 | String writer = client.createWriter(sharedSecret, "myTable", new WriterOptions()); 46 | 47 | // rowid 48 | ByteBuffer rowid = ByteBuffer.wrap("UUID".getBytes()); 49 | 50 | // mutation-like class 51 | ColumnUpdate cu = new ColumnUpdate(); 52 | cu.setColFamily("MyFamily".getBytes()); 53 | cu.setColQualifier("MyQualifier".getBytes()); 54 | cu.setColVisibility("VisLabel".getBytes()); 55 | cu.setValue("Some Value.".getBytes()); 56 | 57 | List updates = List.of(cu); 58 | 59 | // build column updates 60 | Map> cellsToUpdate = Map.of(rowid, updates); 61 | 62 | // send updates to the server 63 | client.updateAndFlush(writer, "myTable", cellsToUpdate); 64 | 65 | client.closeWriter(writer); 66 | ``` 67 | 68 | Scan for the data and batch the return of the results on the server: 69 | 70 | ```java 71 | String scanner = client.createScanner(sharedSecret, "myTable", new ScanOptions()); 72 | ScanResult results = client.nextK(scanner, 100); 73 | 74 | for(KeyValue keyValue : results.getResultsIterator()) { 75 | // do something with results 76 | } 77 | 78 | client.closeScanner(scanner); 79 | ``` 80 | 81 | -------------------------------------------------------------------------------- /src/main/thrift-gen-java/org/apache/accumulo/proxy/thrift/SystemPermission.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | /** 20 | * Autogenerated by Thrift Compiler (0.17.0) 21 | * 22 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 23 | * @generated 24 | */ 25 | package org.apache.accumulo.proxy.thrift; 26 | 27 | 28 | public enum SystemPermission implements org.apache.thrift.TEnum { 29 | GRANT(0), 30 | CREATE_TABLE(1), 31 | DROP_TABLE(2), 32 | ALTER_TABLE(3), 33 | CREATE_USER(4), 34 | DROP_USER(5), 35 | ALTER_USER(6), 36 | SYSTEM(7), 37 | CREATE_NAMESPACE(8), 38 | DROP_NAMESPACE(9), 39 | ALTER_NAMESPACE(10), 40 | OBTAIN_DELEGATION_TOKEN(11); 41 | 42 | private final int value; 43 | 44 | private SystemPermission(int value) { 45 | this.value = value; 46 | } 47 | 48 | /** 49 | * Get the integer value of this enum value, as defined in the Thrift IDL. 50 | */ 51 | @Override 52 | public int getValue() { 53 | return value; 54 | } 55 | 56 | /** 57 | * Find a the enum type by its integer value, as defined in the Thrift IDL. 58 | * @return null if the value is not found. 59 | */ 60 | @org.apache.thrift.annotation.Nullable 61 | public static SystemPermission findByValue(int value) { 62 | switch (value) { 63 | case 0: 64 | return GRANT; 65 | case 1: 66 | return CREATE_TABLE; 67 | case 2: 68 | return DROP_TABLE; 69 | case 3: 70 | return ALTER_TABLE; 71 | case 4: 72 | return CREATE_USER; 73 | case 5: 74 | return DROP_USER; 75 | case 6: 76 | return ALTER_USER; 77 | case 7: 78 | return SYSTEM; 79 | case 8: 80 | return CREATE_NAMESPACE; 81 | case 9: 82 | return DROP_NAMESPACE; 83 | case 10: 84 | return ALTER_NAMESPACE; 85 | case 11: 86 | return OBTAIN_DELEGATION_TOKEN; 87 | default: 88 | return null; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /.github/workflows/maven.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, 13 | # software distributed under the License is distributed on an 14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | # KIND, either express or implied. See the License for the 16 | # specific language governing permissions and limitations 17 | # under the License. 18 | # 19 | 20 | # This workflow will build a Java project with Maven 21 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven 22 | 23 | name: QA 24 | 25 | on: 26 | push: 27 | branches: [ '*' ] 28 | pull_request: 29 | branches: [ '*' ] 30 | 31 | jobs: 32 | mvn: 33 | strategy: 34 | matrix: 35 | profile: 36 | - {name: 'unitTests', args: 'verify javadoc:jar -DskipITs'} 37 | - {name: 'integrationTests', args: 'verify -Dspotbugs.skip -Dcheckstyle.skip -Drat.skip'} 38 | fail-fast: false 39 | timeout-minutes: 60 40 | runs-on: ubuntu-latest 41 | steps: 42 | - uses: actions/checkout@v4 43 | - name: Set up JDK 17 44 | uses: actions/setup-java@v4 45 | with: 46 | distribution: adopt 47 | java-version: 17 48 | cache: 'maven' 49 | - name: Build with Maven (${{ matrix.profile.name }}) 50 | run: mvn -B -V -e -ntp "-Dstyle.color=always" ${{ matrix.profile.args }} 51 | env: 52 | MAVEN_OPTS: -Djansi.force=true 53 | - name: Upload unit test results 54 | if: ${{ failure() }} 55 | uses: actions/upload-artifact@v4 56 | with: 57 | name: surefire-reports-${{ matrix.profile.name }} 58 | path: ./**/target/surefire-reports/ 59 | if-no-files-found: ignore 60 | - name: Upload integration test results 61 | if: ${{ failure() }} 62 | uses: actions/upload-artifact@v4 63 | with: 64 | name: failsafe-reports-${{ matrix.profile.name }} 65 | path: ./**/target/failsafe-reports/ 66 | if-no-files-found: ignore 67 | - name: Upload mini test logs 68 | if: ${{ failure() }} 69 | uses: actions/upload-artifact@v4 70 | with: 71 | name: mini-tests-logs-${{ matrix.profile.name }} 72 | path: ./**/target/**/mini-tests/**/logs/ 73 | if-no-files-found: ignore 74 | 75 | -------------------------------------------------------------------------------- /src/main/java/org/apache/accumulo/proxy/Util.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package org.apache.accumulo.proxy; 20 | 21 | import static java.nio.charset.StandardCharsets.UTF_8; 22 | 23 | import java.math.BigInteger; 24 | import java.nio.ByteBuffer; 25 | import java.security.SecureRandom; 26 | import java.util.Random; 27 | 28 | import org.apache.accumulo.proxy.thrift.IteratorSetting; 29 | import org.apache.accumulo.proxy.thrift.Key; 30 | 31 | public class Util { 32 | 33 | private static final Random random = new SecureRandom(); 34 | 35 | public static String randString(int numbytes) { 36 | return new BigInteger(numbytes * 5, random).toString(32); 37 | } 38 | 39 | public static ByteBuffer randStringBuffer(int numbytes) { 40 | return ByteBuffer.wrap(new BigInteger(numbytes * 5, random).toString(32).getBytes(UTF_8)); 41 | } 42 | 43 | public static IteratorSetting 44 | iteratorSetting2ProxyIteratorSetting(org.apache.accumulo.core.client.IteratorSetting is) { 45 | return new IteratorSetting(is.getPriority(), is.getName(), is.getIteratorClass(), 46 | is.getOptions()); 47 | } 48 | 49 | public static Key toThrift(org.apache.accumulo.core.data.Key key) { 50 | Key pkey = new Key(ByteBuffer.wrap(key.getRow().getBytes()), 51 | ByteBuffer.wrap(key.getColumnFamily().getBytes()), 52 | ByteBuffer.wrap(key.getColumnQualifier().getBytes()), 53 | ByteBuffer.wrap(key.getColumnVisibility().getBytes())); 54 | pkey.setTimestamp(key.getTimestamp()); 55 | return pkey; 56 | } 57 | 58 | public static org.apache.accumulo.core.data.Key fromThrift(Key pkey) { 59 | if (pkey == null) { 60 | return null; 61 | } 62 | return new org.apache.accumulo.core.data.Key(deNullify(pkey.getRow()), 63 | deNullify(pkey.getColFamily()), deNullify(pkey.getColQualifier()), 64 | deNullify(pkey.getColVisibility()), pkey.getTimestamp()); 65 | } 66 | 67 | protected static byte[] deNullify(byte[] in) { 68 | if (in == null) { 69 | return new byte[0]; 70 | } else { 71 | return in; 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/assemble/component.xml: -------------------------------------------------------------------------------- 1 | 2 | 22 | 24 | 25 | 26 | lib 27 | 0755 28 | 0644 29 | true 30 | false 31 | 32 | 35 | ${groupId}:${artifactId} 36 | com.google.guava:guava 37 | org.apache.thrift:libthrift 38 | org.slf4j:slf4j-api 39 | 40 | 41 | 42 | 43 | 44 | bin 45 | src/main/assemble/bin 46 | 0755 47 | 0755 48 | 49 | 50 | conf 51 | src/main/assemble/conf 52 | 0755 53 | 0644 54 | 55 | 56 | ./ 57 | 0644 58 | 59 | README.md 60 | LICENSE 61 | NOTICE 62 | 63 | 64 | 65 | thrift 66 | src/main/thrift 67 | 0755 68 | 0755 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, 13 | # software distributed under the License is distributed on an 14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | # KIND, either express or implied. See the License for the 16 | # specific language governing permissions and limitations 17 | # under the License. 18 | # 19 | 20 | FROM openjdk:11 21 | 22 | EXPOSE 42424 23 | 24 | WORKDIR /opt/accumulo-proxy 25 | 26 | ARG HADOOP_VERSION=3.3.6 27 | ARG ZOOKEEPER_VERSION=3.9.2 28 | ARG ACCUMULO_VERSION=2.1.3 29 | ARG ACCUMULO_PROXY_VERSION=2.0.0-SNAPSHOT 30 | 31 | ARG HADOOP_HASH=de3eaca2e0517e4b569a88b63c89fae19cb8ac6c01ff990f1ff8f0cc0f3128c8e8a23db01577ca562a0e0bb1b4a3889f8c74384e609cd55e537aada3dcaa9f8a 32 | ARG ZOOKEEPER_HASH=2b5ae02d618a27ca8cd54924855d5344263b7d9dee760181f9d66bafa9230324d2ad31786895f0654c969dc38d4a3d0077f74cc376b58b5fa2fb94beb1ab445f 33 | ARG ACCUMULO_HASH=1a27a144dc31f55ccc8e081b6c1bc6cc0362a8391838c53c166cb45291ff8f35867fd8e4729aa7b2c540f8b721f8c6953281bf589fc7fe320e4dc4d20b87abc4 34 | 35 | # Download from Apache mirrors instead of archive #9 36 | ENV APACHE_DIST_URLS="\ 37 | https://www.apache.org/dyn/closer.cgi?action=download&filename= \ 38 | # if the version is outdated (or we're grabbing the .asc file), we might have to pull from the dist/archive :/ 39 | https://www-us.apache.org/dist/ \ 40 | https://www.apache.org/dist/ \ 41 | https://archive.apache.org/dist/" 42 | 43 | RUN set -eux; \ 44 | download_bin() { \ 45 | local f="$1"; shift; \ 46 | local hash="$1"; shift; \ 47 | local distFile="$1"; shift; \ 48 | local success=; \ 49 | local distUrl=; \ 50 | for distUrl in ${APACHE_DIST_URLS}; do \ 51 | if wget -nv -O "/tmp/${f}" "${distUrl}${distFile}"; then \ 52 | success=1; \ 53 | # Checksum the download 54 | echo "${hash}" "/tmp/${f}" | sha512sum -c -; \ 55 | break; \ 56 | fi; \ 57 | done; \ 58 | [ -n "${success}" ]; \ 59 | };\ 60 | \ 61 | download_bin "apache-zookeeper.tar.gz" "${ZOOKEEPER_HASH}" "zookeeper/zookeeper-${ZOOKEEPER_VERSION}/apache-zookeeper-${ZOOKEEPER_VERSION}-bin.tar.gz"; \ 62 | download_bin "hadoop.tar.gz" "$HADOOP_HASH" "hadoop/core/hadoop-${HADOOP_VERSION}/hadoop-$HADOOP_VERSION.tar.gz"; \ 63 | download_bin "accumulo.tar.gz" "${ACCUMULO_HASH}" "accumulo/${ACCUMULO_VERSION}/accumulo-${ACCUMULO_VERSION}-bin.tar.gz"; 64 | 65 | # Install the dependencies into /opt/ 66 | RUN tar xzf /tmp/hadoop.tar.gz -C /opt/ && ln -s /opt/hadoop-${HADOOP_VERSION} /opt/hadoop 67 | RUN tar xzf /tmp/apache-zookeeper.tar.gz -C /opt/ && ln -s /opt/apache-zookeeper-${ZOOKEEPER_VERSION}-bin /opt/apache-zookeeper 68 | RUN tar xzf /tmp/accumulo.tar.gz -C /opt/ && ln -s /opt/accumulo-${ACCUMULO_VERSION} /opt/accumulo && sed -i 's/\${ZOOKEEPER_HOME}\/\*/\${ZOOKEEPER_HOME}\/\*\:\${ZOOKEEPER_HOME}\/lib\/\*/g' /opt/accumulo/conf/accumulo-env.sh 69 | 70 | ENV HADOOP_HOME=/opt/hadoop 71 | ENV ZOOKEEPER_HOME=/opt/apache-zookeeper 72 | ENV ACCUMULO_HOME=/opt/accumulo 73 | 74 | # Add the proxy binary 75 | COPY target/accumulo-proxy-${ACCUMULO_PROXY_VERSION}-bin.tar.gz /tmp/ 76 | RUN tar xzf /tmp/accumulo-proxy-${ACCUMULO_PROXY_VERSION}-bin.tar.gz -C /opt/accumulo-proxy --strip 1 77 | ENV ACCUMULO_PROXY_HOME=/opt/accumulo-proxy 78 | 79 | # Ensure Accumulo is on the path. 80 | ENV PATH="${PATH}:${ACCUMULO_HOME}/bin" 81 | 82 | CMD ["/opt/accumulo-proxy/bin/accumulo-proxy", "-p", "/opt/accumulo-proxy/conf/proxy.properties"] 83 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 21 | 22 | [Apache Accumulo][accumulo] Proxy 23 | -- 24 | [![Build Status][ti]][tl] [![Maven Central][mi]][ml] [![Javadoc][ji]][jl] [![Apache License][li]][ll] 25 | 26 | This application acts as an Apache Accumulo Java client, and exposes its API as 27 | an Apache [Thrift] service so that users can use their preferred programming 28 | language to communicate with Accumulo (provided that language has a supported 29 | Thrift language binding). 30 | 31 | # Running the Accumulo proxy 32 | 33 | 1. Build the proxy tarball and install it. 34 | 35 | ``` 36 | cd /path/to/accumulo-proxy 37 | mvn clean package -Ptarball 38 | tar xzvf ./target/accumulo-proxy-2.0.0-SNAPSHOT-bin.tar.gz -C /path/to/install 39 | ``` 40 | 41 | 2. Edit `proxy.properties` and run the proxy. 42 | 43 | ``` 44 | cd /path/to/install/accumulo-proxy-2.0.0-SNAPSHOT 45 | ./bin/accumulo-proxy -p conf/proxy.properties 46 | ``` 47 | 48 | # Docker Environment 49 | 50 | The Accumulo Proxy can also now be packaged and started in a Docker container, see the [DOCKER.md](DOCKER.md) for full details. 51 | 52 | # Build language specific bindings 53 | 54 | Bindings have been built in `src/main/` for Java, Python, and Ruby. 55 | 56 | Bindings for other languages can be built using the Thrift compiler. Follow the [Thrift tutorial] 57 | to install a Thrift compiler and use the following command to generate language bindings. 58 | 59 | ``` 60 | thrift -r --gen 61 | ``` 62 | 63 | # Create an Accumulo client using Python 64 | 65 | Run the commands below to install the Python bindings and create an example Python client: 66 | 67 | ```bash 68 | mkdir accumulo-client/ 69 | cd accumulo-client/ 70 | pipenv --python 2.7 71 | pipenv install thrift 72 | pipenv install -e /path/to/accumulo-proxy/src/main/python 73 | cp /path/to/accumulo-proxy/src/main/python/basic_client.py . 74 | # Edit credentials if needed 75 | vim basic_client.py 76 | pipenv run python2 basic_client.py 77 | ``` 78 | 79 | # Create an Accumulo client using Ruby 80 | 81 | Run the command below to create an example Ruby client: 82 | 83 | ```bash 84 | mkdir accumulo-client/ 85 | cd accumulo-client/ 86 | cp /path/to/accumulo-proxy/src/main/ruby/Gemfile . 87 | vim Gemfile # Set correct path 88 | cp /path/to/accumulo-proxy/src/main/ruby/client.rb . 89 | gem install bundler 90 | bundle install 91 | bundle exec ruby client.rb 92 | ``` 93 | 94 | # Java clients to Proxy 95 | 96 | [Java clients] to the Proxy can be written to limit access to the cluster. The proxy can be placed 97 | on a server in the cluster and clients can communicate with proxy from outside of the cluster. 98 | 99 | [Java clients]: docs/java_client.md 100 | [accumulo]: https://accumulo.apache.org 101 | [Thrift]: https://thrift.apache.org 102 | [Thrift tutorial]: https://thrift.apache.org/tutorial/ 103 | [li]: https://img.shields.io/badge/license-ASL-blue.svg 104 | [ll]: https://www.apache.org/licenses/LICENSE-2.0 105 | [mi]: https://maven-badges.herokuapp.com/maven-central/org.apache.accumulo/accumulo-proxy/badge.svg 106 | [ml]: https://maven-badges.herokuapp.com/maven-central/org.apache.accumulo/accumulo-proxy/ 107 | [ji]: https://www.javadoc.io/badge/org.apache.accumulo/accumulo-proxy.svg 108 | [jl]: https://www.javadoc.io/doc/org.apache.accumulo/accumulo-proxy 109 | [ti]: https://github.com/apache/accumulo-proxy/workflows/QA/badge.svg 110 | [tl]: https://github.com/apache/accumulo-proxy/actions 111 | -------------------------------------------------------------------------------- /src/test/java/org/apache/accumulo/proxy/ProxyServerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package org.apache.accumulo.proxy; 20 | 21 | import static org.junit.jupiter.api.Assertions.assertThrows; 22 | 23 | import java.nio.ByteBuffer; 24 | import java.util.HashMap; 25 | import java.util.List; 26 | import java.util.Map; 27 | 28 | import org.apache.accumulo.core.client.BatchWriter; 29 | import org.apache.accumulo.core.client.MutationsRejectedException; 30 | import org.apache.accumulo.proxy.ProxyServer.BatchWriterPlusProblem; 31 | import org.apache.accumulo.proxy.thrift.ColumnUpdate; 32 | import org.apache.accumulo.proxy.thrift.WriterOptions; 33 | import org.easymock.EasyMock; 34 | import org.junit.jupiter.api.Test; 35 | 36 | public class ProxyServerTest { 37 | 38 | @Test 39 | public void updateAndFlushClosesWriterOnExceptionFromAddCells() throws Exception { 40 | ProxyServer server = EasyMock.createMockBuilder(ProxyServer.class) 41 | .addMockedMethod("getWriter", String.class, String.class, WriterOptions.class) 42 | .addMockedMethod("addCellsToWriter", Map.class, BatchWriterPlusProblem.class).createMock(); 43 | BatchWriter writer = EasyMock.createMock(BatchWriter.class); 44 | BatchWriterPlusProblem bwpe = new BatchWriterPlusProblem(); 45 | bwpe.writer = writer; 46 | MutationsRejectedException mre = EasyMock.createMock(MutationsRejectedException.class); 47 | 48 | final String sharedSecret = "proxy_secret"; 49 | final String tableName = "table1"; 50 | final Map> cells = new HashMap<>(); 51 | 52 | EasyMock.expect(server.getWriter(sharedSecret, tableName, null)).andReturn(bwpe); 53 | server.addCellsToWriter(cells, bwpe); 54 | EasyMock.expectLastCall(); 55 | 56 | // Set the exception 57 | bwpe.exception = mre; 58 | 59 | writer.close(); 60 | EasyMock.expectLastCall(); 61 | 62 | EasyMock.replay(server, writer, mre); 63 | 64 | assertThrows(org.apache.accumulo.proxy.thrift.MutationsRejectedException.class, 65 | () -> server.updateAndFlush(sharedSecret, tableName, cells)); 66 | 67 | EasyMock.verify(server, writer, mre); 68 | } 69 | 70 | @Test 71 | public void updateAndFlushClosesWriterOnExceptionFromFlush() throws Exception { 72 | ProxyServer server = EasyMock.createMockBuilder(ProxyServer.class) 73 | .addMockedMethod("getWriter", String.class, String.class, WriterOptions.class) 74 | .addMockedMethod("addCellsToWriter", Map.class, BatchWriterPlusProblem.class).createMock(); 75 | BatchWriter writer = EasyMock.createMock(BatchWriter.class); 76 | BatchWriterPlusProblem bwpe = new BatchWriterPlusProblem(); 77 | bwpe.writer = writer; 78 | MutationsRejectedException mre = EasyMock.createMock(MutationsRejectedException.class); 79 | 80 | final String sharedSecret = "proxy_secret"; 81 | final String tableName = "table1"; 82 | final Map> cells = new HashMap<>(); 83 | 84 | EasyMock.expect(server.getWriter(sharedSecret, tableName, null)).andReturn(bwpe); 85 | server.addCellsToWriter(cells, bwpe); 86 | EasyMock.expectLastCall(); 87 | 88 | // No exception throw adding the cells 89 | bwpe.exception = null; 90 | 91 | writer.flush(); 92 | EasyMock.expectLastCall().andThrow(mre); 93 | 94 | writer.close(); 95 | EasyMock.expectLastCall(); 96 | 97 | EasyMock.replay(server, writer, mre); 98 | 99 | assertThrows(org.apache.accumulo.proxy.thrift.MutationsRejectedException.class, 100 | () -> server.updateAndFlush(sharedSecret, tableName, cells)); 101 | 102 | EasyMock.verify(server, writer, mre); 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /src/main/assemble/conf/proxy.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, 13 | # software distributed under the License is distributed on an 14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | # KIND, either express or implied. See the License for the 16 | # specific language governing permissions and limitations 17 | # under the License. 18 | # 19 | 20 | ############################### 21 | ## Accumulo Proxy configuration 22 | ############################### 23 | 24 | # Port to run proxy on 25 | port=42424 26 | sharedSecret=sharedSecret 27 | # Set to true if you wish to use an Mini Accumulo Cluster 28 | useMiniAccumulo=false 29 | protocolFactory=org.apache.thrift.protocol.TCompactProtocol$Factory 30 | tokenClass=org.apache.accumulo.core.client.security.tokens.PasswordToken 31 | maxFrameSize=16M 32 | 33 | ######################################################################## 34 | 35 | ################################ 36 | ## Accumulo client configuration 37 | ################################ 38 | 39 | ## NOTE - All properties that have a default are set with it. Properties that 40 | ## are uncommented must be set by the user. 41 | 42 | ## Instance properties 43 | ## -------------- 44 | ## Name of Accumulo instance to connect to 45 | instance.name=myinstance 46 | 47 | ## Zookeeper connection information for Accumulo instance 48 | instance.zookeepers=localhost:2181 49 | 50 | ## Zookeeper session timeout 51 | #instance.zookeepers.timeout=30s 52 | 53 | 54 | ## Authentication properties 55 | ## -------------- 56 | ## Authentication method (i.e password, kerberos, PasswordToken, KerberosToken, etc) 57 | auth.type=password 58 | 59 | ## Accumulo principal/username for chosen authentication method 60 | auth.principal=root 61 | 62 | ## Authentication token (ex. mypassword, /path/to/keytab) 63 | auth.token=secret 64 | 65 | 66 | ## Batch Writer properties 67 | ## -------------- 68 | ## The durability used to write to the write-ahead log. Legal values are: none, which skips the write-ahead log; log, which sends the data to the write-ahead log, but does nothing to make it durable; flush, which pushes data to the file system; and sync, which ensures the data is written to disk. Setting this property will change the durability for the BatchWriter session. A value of "default" will use the table's durability setting. 69 | #batch.writer.durability=default 70 | 71 | ## Max amount of time (in seconds) to hold data in memory before flushing it 72 | #batch.writer.latency.max=120s 73 | 74 | ## Max memory (in bytes) to batch before writing 75 | #batch.writer.memory.max=50M 76 | 77 | ## Maximum number of threads to use for writing data to tablet servers. 78 | #batch.writer.threads.max=3 79 | 80 | ## Max amount of time (in seconds) an unresponsive server will be re-tried. An exception is thrown when this timeout is exceeded. Set to zero for no timeout. 81 | #batch.writer.timeout.max=0 82 | 83 | 84 | ## Batch Scanner properties 85 | ## -------------- 86 | ## Number of concurrent query threads to spawn for querying 87 | #batch.scanner.num.query.threads=3 88 | 89 | 90 | ## Scanner properties 91 | ## -------------- 92 | ## Number of key/value pairs that will be fetched at time from tablet server 93 | #scanner.batch.size=1000 94 | 95 | 96 | ## SSL properties 97 | ## -------------- 98 | ## Enable SSL for client RPC 99 | #ssl.enabled=false 100 | 101 | ## Password used to encrypt keystore 102 | #ssl.keystore.password= 103 | 104 | ## Path to SSL keystore file 105 | #ssl.keystore.path= 106 | 107 | ## Type of SSL keystore 108 | #ssl.keystore.type=jks 109 | 110 | ## Password used to encrypt truststore 111 | #ssl.truststore.password= 112 | 113 | ## Path to SSL truststore file 114 | #ssl.truststore.path= 115 | 116 | ## Type of SSL truststore 117 | #ssl.truststore.type=jks 118 | 119 | ## Use JSSE system properties to configure SSL 120 | #ssl.use.jsse=false 121 | 122 | 123 | ## SASL properties 124 | ## -------------- 125 | ## Enable SASL for client RPC 126 | #sasl.enabled=false 127 | 128 | ## Kerberos principal/primary that Accumulo servers use to login 129 | #sasl.kerberos.server.primary=accumulo 130 | 131 | ## SASL quality of protection. Valid values are 'auth', 'auth-int', and 'auth-conf' 132 | #sasl.qop=auth 133 | 134 | 135 | ## Tracing properties 136 | ## -------------- 137 | ## A list of span receiver classes to send trace spans 138 | #trace.span.receivers=org.apache.accumulo.tracer.ZooTraceClient 139 | 140 | ## The zookeeper node where tracers are registered 141 | #trace.zookeeper.path=/tracers 142 | 143 | -------------------------------------------------------------------------------- /src/test/resources/log4j2-test.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, 13 | # software distributed under the License is distributed on an 14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | # KIND, either express or implied. See the License for the 16 | # specific language governing permissions and limitations 17 | # under the License. 18 | # 19 | 20 | status = info 21 | dest = err 22 | name = AccumuloProxyITLoggingProperties 23 | monitorInterval = 10 24 | 25 | appender.console.type = Console 26 | appender.console.name = STDOUT 27 | appender.console.target = SYSTEM_OUT 28 | appender.console.layout.type = PatternLayout 29 | appender.console.layout.pattern = %d{ISO8601} [%c{2}] %-5p: %m%n 30 | 31 | logger.01.name = org.apache.accumulo.core 32 | logger.01.level = debug 33 | 34 | logger.02.name = org.apache.accumulo.core.clientImpl.ManagerClient 35 | logger.02.level = info 36 | 37 | logger.03.name = org.apache.accumulo.core.clientImpl.ServerClient 38 | logger.03.level = error 39 | 40 | logger.04.name = org.apache.accumulo.core.util.shell.Shell.audit 41 | logger.04.level = off 42 | 43 | logger.05.name = org.apache.accumulo.core.util.shell.Shell 44 | logger.05.level = fatal 45 | 46 | logger.06.name = org.apache.commons.vfs2.impl.DefaultFileSystemManager 47 | logger.06.level = warn 48 | 49 | logger.07.name = org.apache.hadoop.io.compress.CodecPool 50 | logger.07.level = warn 51 | 52 | logger.08.name = org.apache.hadoop.mapred 53 | logger.08.level = error 54 | 55 | logger.09.name = org.apache.hadoop.tools.DistCp 56 | logger.09.level = warn 57 | 58 | logger.10.name = org.apache.hadoop.util.NativeCodeLoader 59 | logger.10.level = error 60 | 61 | logger.11.name = org.apache.hadoop.util.ProcessTree 62 | logger.11.level = warn 63 | 64 | logger.12.name = org.apache.zookeeper 65 | logger.12.level = info 66 | 67 | logger.13.name = org.apache.zookeeper.ClientCnxn 68 | logger.13.level = fatal 69 | 70 | logger.14.name = org.apache.zookeeper.ClientCnxnSocket 71 | logger.14.level = warn 72 | 73 | logger.15.name = org.apache.zookeeper.ZooKeeper 74 | logger.15.level = warn 75 | 76 | logger.16.name = org.apache.accumulo.core.file.rfile.bcfile 77 | logger.16.level = info 78 | 79 | logger.17.name = org.apache.accumulo.core.clientImpl.ThriftScanner 80 | logger.17.level = info 81 | 82 | logger.18.name = org.apache.accumulo.core.fate.zookeeper.DistributedReadWriteLock 83 | logger.18.level = warn 84 | 85 | logger.19.name = org.apache.hadoop 86 | logger.19.level = warn 87 | 88 | logger.20.name = org.apache.jasper 89 | logger.20.level = info 90 | 91 | logger.21.name = org.apache.hadoop.hdfs.server.namenode.FSNamesystem.audit 92 | logger.21.level = warn 93 | 94 | logger.22.name = org.apache.hadoop.hdfs.server.datanode.DataNode.clienttrace 95 | logger.22.level = warn 96 | 97 | logger.23.name = BlockStateChange 98 | logger.23.level = warn 99 | 100 | logger.24.name = org.apache.accumulo.core.clientImpl.TabletServerBatchReaderIterator 101 | logger.24.level = info 102 | 103 | logger.25.name = org.apache.hadoop.security 104 | logger.25.level = info 105 | 106 | logger.26.name = org.apache.hadoop.minikdc 107 | logger.26.level = debug 108 | 109 | logger.27.name = org.apache.directory 110 | logger.27.level = info 111 | 112 | logger.28.name = org.apache.directory.api.ldap 113 | logger.28.level = warn 114 | 115 | # This is really spammy at debug 116 | logger.29.name = org.apache.thrift.transport.TSaslTransport 117 | logger.29.level = info 118 | 119 | # From apache-ds/minikdc 120 | logger.31.name = org.apache.mina 121 | logger.31.level = info 122 | 123 | logger.32.name = org.apache.accumulo.server.thrift.UGIAssumingProcessor 124 | logger.32.level = trace 125 | 126 | logger.33.name = org.apache.hadoop.security.UserGroupInformation 127 | logger.33.level = info 128 | 129 | # This is spammy 130 | logger.35.name = org.apache.accumulo.miniclusterImpl.MiniAccumuloClusterImpl 131 | logger.35.level = info 132 | 133 | # This is pointless, as it only ever logs errors closing connections that are 134 | # already closed, such as when we release a cached thrift transport after the 135 | # network socket has already disconnected; These can't really be avoided, 136 | # because TIOStreamTransport does not implement a good isOpen() 137 | logger.36.name = org.apache.thrift.transport.TIOStreamTransport 138 | logger.36.level = error 139 | 140 | logger.37.name = org.eclipse.jetty 141 | logger.37.level = warn 142 | 143 | logger.38.name = org.apache.accumulo.core.clientImpl.ThriftTransportPool 144 | logger.38.level = info 145 | 146 | logger.39.name = org.apache.accumulo.core.util.threads.ThreadPools 147 | logger.39.level = info 148 | 149 | rootLogger.level = debug 150 | rootLogger.appenderRef.console.ref = STDOUT 151 | 152 | -------------------------------------------------------------------------------- /src/main/scripts/generate-thrift.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | # 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # 20 | 21 | # This script will regenerate the thrift code for accumulo-proxy. 22 | 23 | # NOTES: 24 | # To support this script being called by other modules, only edit the right side. 25 | # In other scripts, set the variables that diverge from the defaults below, then call this script. 26 | # PACKAGES_TO_GENERATE should be an array, and each element should be the portion of the dot-separated Java package 27 | # name following the BASE_OUTPUT_PACKAGE 28 | # Leave the BUILD_DIR and FINAL_DIR alone for Maven builds. 29 | # INCLUDED_MODULES should be an array that includes other Maven modules with src/main/thrift directories 30 | # Use INCLUDED_MODULES=(-) in calling scripts that require no other modules 31 | # ======================================================================================================================== 32 | [[ -z $REQUIRED_THRIFT_VERSION ]] && REQUIRED_THRIFT_VERSION='0.17.0' 33 | [[ -z $INCLUDED_MODULES ]] && INCLUDED_MODULES=(-) 34 | [[ -z $BASE_OUTPUT_PACKAGE ]] && BASE_OUTPUT_PACKAGE='org.apache.accumulo' 35 | [[ -z $PACKAGES_TO_GENERATE ]] && PACKAGES_TO_GENERATE=(proxy) 36 | [[ -z $BUILD_DIR ]] && BUILD_DIR='target' 37 | [[ -z $LANGUAGES_TO_GENERATE ]] && LANGUAGES_TO_GENERATE=(cpp java rb py) 38 | [[ -z $FINAL_DIR ]] && FINAL_DIR='src/main' 39 | # ======================================================================================================================== 40 | 41 | fail() { 42 | echo "$@" 43 | exit 1 44 | } 45 | 46 | # Test to see if we have thrift installed 47 | if ! thrift -version 2>/dev/null | grep -qF "${REQUIRED_THRIFT_VERSION}"; then 48 | # Nope: bail 49 | echo "****************************************************" 50 | echo "*** thrift is not available" 51 | echo "*** expecting 'thrift -version' to return ${REQUIRED_THRIFT_VERSION}" 52 | echo "*** generated code will not be updated" 53 | fail "****************************************************" 54 | fi 55 | 56 | # Include thrift sources from additional modules 57 | THRIFT_ARGS=() 58 | for i in "${INCLUDED_MODULES[@]}"; do 59 | if [[ $i != '-' ]]; then 60 | test -d "$i" || fail missing required included module "$i" 61 | THRIFT_ARGS=("${THRIFT_ARGS[@]}" -I "$i/src/main/thrift") 62 | fi 63 | done 64 | 65 | # Ensure output directories are created 66 | THRIFT_ARGS=("${THRIFT_ARGS[@]}" -o "$BUILD_DIR") 67 | mkdir -p "$BUILD_DIR" 68 | rm -rf "$BUILD_DIR"/gen-java 69 | for f in src/main/thrift/*.thrift; do 70 | thrift "${THRIFT_ARGS[@]}" --gen java:generated_annotations=suppress "$f" || fail unable to generate java thrift classes 71 | thrift "${THRIFT_ARGS[@]}" --gen py "$f" || fail unable to generate python thrift classes 72 | thrift "${THRIFT_ARGS[@]}" --gen rb "$f" || fail unable to generate ruby thrift classes 73 | thrift "${THRIFT_ARGS[@]}" --gen cpp "$f" || fail unable to generate cpp thrift classes 74 | done 75 | 76 | # For all generated thrift code, get rid of all warnings and add the LICENSE header 77 | 78 | # add dummy method to suppress "unnecessary suppress warnings" for classes which don't have any unused variables 79 | # this only affects classes, enums aren't affected 80 | #shellcheck disable=SC1004 81 | find $BUILD_DIR/gen-java -name '*.java' -exec grep -Zl '^public class ' {} + | xargs -0 sed -i -e 's/^[}]$/ private static void unusedMethod() {}\ 82 | }/' 83 | 84 | # For every generated java file, compare it with the version-controlled one, and copy the ones that have changed into place 85 | for d in "${PACKAGES_TO_GENERATE[@]}"; do 86 | for lang in "${LANGUAGES_TO_GENERATE[@]}"; do 87 | case "$lang" in 88 | cpp) 89 | SDIR="${BUILD_DIR}/gen-$lang/" 90 | DDIR="${FINAL_DIR}/cpp" 91 | FILE_SUFFIX=(.h .cpp) 92 | ;; 93 | java) 94 | SDIR="${BUILD_DIR}/gen-$lang/${BASE_OUTPUT_PACKAGE//.//}/${d//.//}/thrift" 95 | DDIR="${FINAL_DIR}/thrift-gen-$lang/${BASE_OUTPUT_PACKAGE//.//}/${d//.//}/thrift" 96 | FILE_SUFFIX=(.java) 97 | ;; 98 | rb) 99 | SDIR="${BUILD_DIR}/gen-$lang/" 100 | DDIR="${FINAL_DIR}/ruby/accumulo/lib" 101 | FILE_SUFFIX=(.rb) 102 | ;; 103 | py) 104 | SDIR="${BUILD_DIR}/gen-$lang/accumulo" 105 | DDIR="${FINAL_DIR}/python/accumulo" 106 | FILE_SUFFIX=(.py -remote) 107 | ;; 108 | *) 109 | continue 110 | ;; 111 | esac 112 | mkdir -p "$DDIR" 113 | for file in "${FILE_SUFFIX[@]}"; do 114 | mapfile -t ALL_EXISTING_FILES < <(find "$DDIR" -name "*$file") 115 | for f in "${ALL_EXISTING_FILES[@]}"; do 116 | if [[ ! -f "$SDIR/$(basename "$f")" ]]; then 117 | set -x 118 | rm -f "$f" 119 | { set +x; } 2>/dev/null 120 | fi 121 | done 122 | mapfile -t ALL_FILES_TO_COPY < <(find "$SDIR" -name "*$file") 123 | for f in "${ALL_FILES_TO_COPY[@]}"; do 124 | DEST="$DDIR/$(basename "$f")" 125 | if ! cmp -s "${f}" "${DEST}"; then 126 | set -x 127 | cp -f "${f}" "${DEST}" || fail unable to copy files to java workspace 128 | { set +x; } 2>/dev/null 129 | fi 130 | done 131 | done 132 | done 133 | done 134 | -------------------------------------------------------------------------------- /DOCKER.md: -------------------------------------------------------------------------------- 1 | 21 | 22 | # accumulo-proxy-docker 23 | This documentation covers how to stand up [accumulo-proxy](https://github.com/apache/accumulo-proxy/) within a Docker container. 24 | 25 | The guide covers: 26 | * Building the image 27 | * Configuring the `proxy.properties` file 28 | * Selecting an appropriate networking choice 29 | * Starting and stopping the container 30 | * Basic troubleshooting tips 31 | 32 | It is not recommended using this guide for a production instance of accumulo-proxy at this time. 33 | 34 | ## Build the image 35 | Firstly you will need the tarball of accumulo-proxy, this is documented in the [README.md](README.md) but for simplicity run: 36 | ```commandline 37 | mvn clean package -Ptarball 38 | ``` 39 | 40 | Once you have the tarball (should be in ./target/ folder) then invoke the Docker build command to create a container image. 41 | ```commandline 42 | docker build -t accumulo-proxy:latest . 43 | ``` 44 | 45 | ## Default Configuration and Quickstart 46 | By default, the container image expects the following to be true: 47 | 1. Your Accumulo instance name is "myinstance" 48 | 2. Your ZooKeeper is available (and reachable from the container) at localhost:2181 49 | 50 | You can start the proxy using: 51 | ```commandline 52 | docker run --rm -d -p 42424:42424 --network="host" --name accumulo-proxy accumulo-proxy:latest; 53 | ``` 54 | 55 | ## Custom proxy.properties 56 | If you wish to create advanced proxy.properties configuration changes, you should look to volume mount these in when you invoke the `docker run` command, an example is: 57 | ```commandline 58 | docker run --rm -d -p 42424:42424 -v /path/to/proxy.properties:/opt/accumulo-proxy/conf/proxy.properties --network="host" --name accumulo-proxy accumulo-proxy:latest 59 | ``` 60 | 61 | ## Networking configuration 62 | Container networking can be a very specialised subject therefore we document two common practices that should cover the majority of use cases for development. 63 | 64 | The proxy container must be able to access both Accumulo and ZooKeeper. 65 | 66 | The ZooKeeper location can be configured in the `conf/proxy.properties` file, so you can override this to an acceptable value (see "Custom proxy.properties" section) 67 | 68 | In order to communicate with Accumulo the container will need to be able to resolve the FQDN that the servers have registered in ZooKeeper. If using [fluo-uno](https://github.com/apache/fluo-uno) this is very likely the hostname of your development environment. We'll call this my.host.com and IP 192.168.0.1 for the rest of this document. 69 | 70 | ### Host networking 71 | 72 | Host networking is the simplest mechanism but generally only works for linux hosts where Docker has been installed on 'bare metal' e.g. through an RPM. 73 | 74 | You can test if this will work for you by executing the following steps 75 | 76 | Start the accumulo-proxy container and enter it 77 | ```commandline 78 | docker run -it --rm -p 42424:42424 --network="host" --name accumulo-proxy accumulo-proxy:latest bash; 79 | ``` 80 | 81 | Once inside the container, execute the curl command to attempt to connect to the monitor webserver: 82 | ```commandline 83 | curl my.host.com:9995 84 | ``` 85 | 86 | If the terminal returns an error such as: 87 | ``` 88 | curl: (7) Failed to connect to my.host.com 9995: Connection refused 89 | ``` 90 | then your container cannot see the host, and you will need to look at the next section (Non-Host networking). 91 | 92 | If you receive the HTML for the monitor web page then host networking will work for you and you can add `--network="host"` to each Docker command going forward. 93 | 94 | An example of using host networking: 95 | ```commandline 96 | docker run --rm -d -p 42424:42424 --network="host" --name accumulo-proxy accumulo-proxy:latest 97 | ``` 98 | 99 | Note: You do not need to map your ports (-p) if using host networking, but we include it for clarity. 100 | 101 | For more details see the official Docker documentation: [Use host Networking](https://docs.docker.com/network/host) 102 | 103 | ### Non-Host networking 104 | If you run outside of a single node linux installation, e.g. Docker for Mac, Docker for Windows or use a VM to isolate your Docker engine then you will likely need to take this path. 105 | 106 | Docker allows you to supply additional addresses to be resolved by the container, and these are automatically added by Docker to the /etc/hosts 107 | 108 | For each host add a `--add-host FQDN:IP` entry to your Docker run command, you can add multiple entries if need to, see the official docs covering [network settings](https://docs.docker.com/engine/reference/run/#network-settings). 109 | 110 | An example of using this approach: 111 | 112 | ```commandline 113 | docker run --rm -d -p 42424:42424 --add-host "my.host.com:192.168.0.1" --name accumulo-proxy accumulo-proxy:latest 114 | ``` 115 | 116 | ## Cleanup 117 | Once completed you should stop and remove the container. 118 | ```commandline 119 | docker stop accumulo-proxy; 120 | docker rm accumulo-proxy; 121 | ``` 122 | 123 | ## Troubleshooting 124 | It can often be difficult to know where to start with troubleshooting inside containers, if you need to enter the container without starting the proxy we support this: 125 | ```commandline 126 | docker run -it --rm -p 42424:42424 --network="host" --name accumulo-proxy accumulo-proxy:latest bash 127 | ``` 128 | 129 | The container is very slim so if need be you can add additional tools using `apt`. 130 | 131 | If you wish to manually execute the accumulo-proxy in the container you can: 132 | ```commandline 133 | /opt/accumulo-proxy/bin/accumulo-proxy -p /opt/accumulo-proxy/conf/proxy.properties 134 | ``` 135 | 136 | Some resources for additional help: 137 | * [Main Accumulo Website](https://accumulo.apache.org/) 138 | * [Contact Us page](https://accumulo.apache.org/contact-us/) 139 | -------------------------------------------------------------------------------- /src/test/java/org/apache/accumulo/proxy/its/ProxyDurabilityIT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package org.apache.accumulo.proxy.its; 20 | 21 | import static org.apache.accumulo.core.util.UtilWaitThread.sleepUninterruptibly; 22 | import static org.junit.jupiter.api.Assertions.assertEquals; 23 | import static org.junit.jupiter.api.Assertions.assertTrue; 24 | 25 | import java.io.File; 26 | import java.nio.ByteBuffer; 27 | import java.nio.file.Files; 28 | import java.time.Duration; 29 | import java.util.Collections; 30 | import java.util.List; 31 | import java.util.Map; 32 | import java.util.Properties; 33 | import java.util.TreeMap; 34 | import java.util.concurrent.TimeUnit; 35 | 36 | import org.apache.accumulo.core.client.Accumulo; 37 | import org.apache.accumulo.core.client.AccumuloClient; 38 | import org.apache.accumulo.core.client.security.tokens.PasswordToken; 39 | import org.apache.accumulo.core.conf.ClientProperty; 40 | import org.apache.accumulo.core.conf.Property; 41 | import org.apache.accumulo.core.security.Authorizations; 42 | import org.apache.accumulo.core.util.HostAndPort; 43 | import org.apache.accumulo.minicluster.ServerType; 44 | import org.apache.accumulo.miniclusterImpl.MiniAccumuloConfigImpl; 45 | import org.apache.accumulo.miniclusterImpl.ProcessReference; 46 | import org.apache.accumulo.proxy.Proxy; 47 | import org.apache.accumulo.proxy.thrift.AccumuloProxy.Client; 48 | import org.apache.accumulo.proxy.thrift.Column; 49 | import org.apache.accumulo.proxy.thrift.ColumnUpdate; 50 | import org.apache.accumulo.proxy.thrift.Condition; 51 | import org.apache.accumulo.proxy.thrift.ConditionalStatus; 52 | import org.apache.accumulo.proxy.thrift.ConditionalUpdates; 53 | import org.apache.accumulo.proxy.thrift.ConditionalWriterOptions; 54 | import org.apache.accumulo.proxy.thrift.Durability; 55 | import org.apache.accumulo.proxy.thrift.TimeType; 56 | import org.apache.accumulo.proxy.thrift.WriterOptions; 57 | import org.apache.accumulo.server.util.PortUtils; 58 | import org.apache.accumulo.test.functional.ConfigurableMacBase; 59 | import org.apache.hadoop.conf.Configuration; 60 | import org.apache.hadoop.fs.RawLocalFileSystem; 61 | import org.apache.thrift.protocol.TJSONProtocol; 62 | import org.apache.thrift.server.TServer; 63 | import org.junit.jupiter.api.Test; 64 | 65 | import com.google.common.collect.Iterators; 66 | 67 | import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 68 | 69 | public class ProxyDurabilityIT extends ConfigurableMacBase { 70 | 71 | @Override 72 | protected Duration defaultTimeout() { 73 | return Duration.ofMinutes(2); 74 | } 75 | 76 | @Override 77 | public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) { 78 | hadoopCoreSite.set("fs.file.impl", RawLocalFileSystem.class.getName()); 79 | cfg.setProperty(Property.TSERV_NATIVEMAP_ENABLED, "false"); 80 | cfg.setClientProperty(ClientProperty.INSTANCE_ZOOKEEPERS_TIMEOUT, "15s"); 81 | cfg.setProperty(Property.INSTANCE_ZK_TIMEOUT, "15s"); 82 | cfg.setNumTservers(1); 83 | } 84 | 85 | @SuppressFBWarnings(value = {"DM_DEFAULT_ENCODING"}, 86 | justification = "no check needed on encoding") 87 | private static ByteBuffer bytes(String value) { 88 | return ByteBuffer.wrap(value.getBytes()); 89 | } 90 | 91 | @SuppressFBWarnings(value = {"HARD_CODE_PASSWORD", "DM_DEFAULT_ENCODING"}, 92 | justification = "test password is okay and no check needed on encoding") 93 | @Test 94 | public void testDurability() throws Exception { 95 | try (AccumuloClient c = Accumulo.newClient().from(getClientProperties()).build()) { 96 | Properties proxyProps = new Properties(); 97 | // Avoid issues with locally installed client configuration files with custom properties 98 | File emptyFile = Files.createTempFile(null, null).toFile(); 99 | emptyFile.deleteOnExit(); 100 | proxyProps.put("tokenClass", PasswordToken.class.getName()); 101 | proxyProps.putAll(getClientProperties()); 102 | 103 | String sharedSecret = "superSecret"; 104 | 105 | proxyProps.put("sharedSecret", sharedSecret); 106 | 107 | TJSONProtocol.Factory protocol = new TJSONProtocol.Factory(); 108 | 109 | int proxyPort = PortUtils.getRandomFreePort(); 110 | final TServer proxyServer = 111 | Proxy.createProxyServer(HostAndPort.fromParts("localhost", proxyPort), protocol, 112 | proxyProps).server; 113 | while (!proxyServer.isServing()) { 114 | sleepUninterruptibly(100, TimeUnit.MILLISECONDS); 115 | } 116 | try (var proxyClient = new TestProxyClient("localhost", proxyPort, protocol)) { 117 | Client client = proxyClient.proxy(); 118 | String tableName = getUniqueNames(1)[0]; 119 | client.createTable(sharedSecret, tableName, true, TimeType.MILLIS); 120 | assertTrue(c.tableOperations().exists(tableName)); 121 | 122 | WriterOptions options = new WriterOptions(); 123 | options.setDurability(Durability.NONE); 124 | String writer = client.createWriter(sharedSecret, tableName, options); 125 | Map> cells = new TreeMap<>(); 126 | ColumnUpdate column = new ColumnUpdate(bytes("cf"), bytes("cq")); 127 | column.setValue("value".getBytes()); 128 | cells.put(bytes("row"), Collections.singletonList(column)); 129 | client.update(writer, cells); 130 | client.closeWriter(writer); 131 | assertEquals(1, count(c, tableName)); 132 | restartTServer(); 133 | assertEquals(0, count(c, tableName)); 134 | 135 | ConditionalWriterOptions cfg = new ConditionalWriterOptions(); 136 | cfg.setDurability(Durability.SYNC); 137 | String cwriter = client.createConditionalWriter(sharedSecret, tableName, cfg); 138 | ConditionalUpdates updates = new ConditionalUpdates(); 139 | updates.addToConditions(new Condition(new Column(bytes("cf"), bytes("cq"), bytes("")))); 140 | updates.addToUpdates(column); 141 | Map status = client.updateRowsConditionally(cwriter, 142 | Collections.singletonMap(bytes("row"), updates)); 143 | assertEquals(ConditionalStatus.ACCEPTED, status.get(bytes("row"))); 144 | assertEquals(1, count(c, tableName)); 145 | restartTServer(); 146 | assertEquals(1, count(c, tableName)); 147 | 148 | } finally { 149 | proxyServer.stop(); 150 | } 151 | } 152 | } 153 | 154 | private void restartTServer() throws Exception { 155 | for (ProcessReference proc : cluster.getProcesses().get(ServerType.TABLET_SERVER)) { 156 | cluster.killProcess(ServerType.TABLET_SERVER, proc); 157 | } 158 | cluster.start(); 159 | } 160 | 161 | private int count(AccumuloClient client, String tableName) throws Exception { 162 | return Iterators.size((client.createScanner(tableName, Authorizations.EMPTY)).iterator()); 163 | } 164 | 165 | } 166 | -------------------------------------------------------------------------------- /src/main/python/namespace_client.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # 20 | 21 | from thrift.protocol import TCompactProtocol 22 | from thrift.transport import TSocket, TTransport 23 | 24 | from accumulo import AccumuloProxy 25 | from accumulo.ttypes import NamespacePermission, IteratorSetting, IteratorScope, AccumuloException 26 | 27 | def main(): 28 | transport = TSocket.TSocket('localhost', 42424) 29 | transport = TTransport.TFramedTransport(transport) 30 | protocol = TCompactProtocol.TCompactProtocol(transport) 31 | client = AccumuloProxy.Client(protocol) 32 | transport.open() 33 | login = client.login('root', {'password': 'secret'}) 34 | 35 | client.createLocalUser(login, 'user1', 'password1') 36 | 37 | print client.listNamespaces(login) 38 | 39 | # create a namespace and give the user1 all permissions 40 | print 'creating namespace testing' 41 | client.createNamespace(login, 'testing') 42 | assert client.namespaceExists(login, 'testing') 43 | print client.listNamespaces(login) 44 | 45 | print 'testing namespace renaming' 46 | client.renameNamespace(login, 'testing', 'testing2') 47 | assert not client.namespaceExists(login, 'testing') 48 | assert client.namespaceExists(login, 'testing2') 49 | client.renameNamespace(login, 'testing2', 'testing') 50 | assert not client.namespaceExists(login, 'testing2') 51 | assert client.namespaceExists(login, 'testing') 52 | 53 | print 'granting all namespace permissions to user1' 54 | for k, v in NamespacePermission._VALUES_TO_NAMES.iteritems(): 55 | client.grantNamespacePermission(login, 'user1', 'testing', k) 56 | 57 | # make sure the last operation worked 58 | for k, v in NamespacePermission._VALUES_TO_NAMES.iteritems(): 59 | assert client.hasNamespacePermission(login, 'user1', 'testing', k), \ 60 | 'user1 does\'nt have namespace permission %s' % v 61 | 62 | print 'default namespace: ' + client.defaultNamespace() 63 | print 'system namespace: ' + client.systemNamespace() 64 | 65 | # grab the namespace properties 66 | print 'retrieving namespace properties' 67 | props = client.getNamespaceProperties(login, 'testing') 68 | assert props and props['table.compaction.major.ratio'] == '3' 69 | 70 | # update a property and verify it is good 71 | print 'setting namespace property table.compaction.major.ratio = 4' 72 | client.setNamespaceProperty(login, 'testing', 'table.compaction.major.ratio', '4') 73 | props = client.getNamespaceProperties(login, 'testing') 74 | assert props and props['table.compaction.major.ratio'] == '4' 75 | 76 | print 'retrieving namespace ID map' 77 | nsids = client.namespaceIdMap(login) 78 | assert nsids and 'accumulo' in nsids 79 | 80 | print 'attaching debug iterator to namespace testing' 81 | setting = IteratorSetting(priority=40, name='DebugTheThings', 82 | iteratorClass='org.apache.accumulo.core.iterators.DebugIterator', properties={}) 83 | client.attachNamespaceIterator(login, 'testing', setting, [IteratorScope.SCAN]) 84 | setting = client.getNamespaceIteratorSetting(login, 'testing', 'DebugTheThings', IteratorScope.SCAN) 85 | assert setting and setting.name == 'DebugTheThings' 86 | 87 | # make sure the iterator is in the list 88 | iters = client.listNamespaceIterators(login, 'testing') 89 | found = False 90 | for name, scopes in iters.iteritems(): 91 | if name == 'DebugTheThings': 92 | found = True 93 | break 94 | assert found 95 | 96 | print 'checking for iterator conflicts' 97 | 98 | # this next statment should be fine since we are on a different scope 99 | client.checkNamespaceIteratorConflicts(login, 'testing', setting, [IteratorScope.MINC]) 100 | 101 | # this time it should throw an exception since we have already added the iterator with this scope 102 | try: 103 | client.checkNamespaceIteratorConflicts(login, 'testing', setting, [IteratorScope.SCAN, IteratorScope.MINC]) 104 | except AccumuloException: 105 | pass 106 | else: 107 | assert False, 'There should have been a namespace iterator conflict!' 108 | 109 | print 'removing debug iterator from namespace testing' 110 | client.removeNamespaceIterator(login, 'testing', 'DebugTheThings', [IteratorScope.SCAN]) 111 | 112 | # make sure the iterator is NOT in the list anymore 113 | iters = client.listNamespaceIterators(login, 'testing') 114 | found = False 115 | for name, scopes in iters.iteritems(): 116 | if name == 'DebugTheThings': 117 | found = True 118 | break 119 | assert not found 120 | 121 | print 'adding max mutation size namespace constraint' 122 | constraintid = client.addNamespaceConstraint(login, 'testing', 123 | 'org.apache.accumulo.test.constraints.MaxMutationSize') 124 | 125 | print 'make sure constraint was added' 126 | constraints = client.listNamespaceConstraints(login, 'testing') 127 | found = False 128 | for name, cid in constraints.iteritems(): 129 | if cid == constraintid and name == 'org.apache.accumulo.test.constraints.MaxMutationSize': 130 | found = True 131 | break 132 | assert found 133 | 134 | print 'remove max mutation size namespace constraint' 135 | client.removeNamespaceConstraint(login, 'testing', constraintid) 136 | 137 | print 'make sure constraint was removed' 138 | constraints = client.listNamespaceConstraints(login, 'testing') 139 | found = False 140 | for name, cid in constraints.iteritems(): 141 | if cid == constraintid and name == 'org.apache.accumulo.test.constraints.MaxMutationSize': 142 | found = True 143 | break 144 | assert not found 145 | 146 | print 'test a namespace class load of the VersioningIterator' 147 | res = client.testNamespaceClassLoad(login, 'testing', 'org.apache.accumulo.core.iterators.user.VersioningIterator', 148 | 'org.apache.accumulo.core.iterators.SortedKeyValueIterator') 149 | assert res 150 | 151 | print 'test a bad namespace class load of the VersioningIterator' 152 | res = client.testNamespaceClassLoad(login, 'testing', 'org.apache.accumulo.core.iterators.user.VersioningIterator', 153 | 'dummy') 154 | assert not res 155 | 156 | # revoke the permissions 157 | print 'revoking namespace permissions for user1' 158 | for k, v in NamespacePermission._VALUES_TO_NAMES.iteritems(): 159 | client.revokeNamespacePermission(login, 'user1', 'testing', k) 160 | 161 | # make sure the last operation worked 162 | for k, v in NamespacePermission._VALUES_TO_NAMES.iteritems(): 163 | assert not client.hasNamespacePermission(login, 'user1', 'testing', k), \ 164 | 'user1 does\'nt have namespace permission %s' % v 165 | 166 | print 'deleting namespace testing' 167 | client.deleteNamespace(login, 'testing') 168 | assert not client.namespaceExists(login, 'testing') 169 | 170 | print 'deleting user1' 171 | client.dropLocalUser(login, 'user1') 172 | 173 | if __name__ == "__main__": 174 | main() 175 | -------------------------------------------------------------------------------- /src/test/java/org/apache/accumulo/proxy/its/TestProxyClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package org.apache.accumulo.proxy.its; 20 | 21 | import static java.nio.charset.StandardCharsets.UTF_8; 22 | 23 | import java.nio.ByteBuffer; 24 | import java.util.Collections; 25 | import java.util.Date; 26 | import java.util.HashMap; 27 | import java.util.List; 28 | import java.util.Map; 29 | 30 | import javax.security.sasl.SaslException; 31 | 32 | import org.apache.accumulo.core.client.IteratorSetting; 33 | import org.apache.accumulo.core.iterators.user.RegExFilter; 34 | import org.apache.accumulo.core.rpc.UGIAssumingTransport; 35 | import org.apache.accumulo.proxy.Util; 36 | import org.apache.accumulo.proxy.thrift.AccumuloProxy; 37 | import org.apache.accumulo.proxy.thrift.ColumnUpdate; 38 | import org.apache.accumulo.proxy.thrift.Key; 39 | import org.apache.accumulo.proxy.thrift.ScanResult; 40 | import org.apache.accumulo.proxy.thrift.TimeType; 41 | import org.apache.hadoop.security.UserGroupInformation; 42 | import org.apache.thrift.protocol.TCompactProtocol; 43 | import org.apache.thrift.protocol.TProtocol; 44 | import org.apache.thrift.protocol.TProtocolFactory; 45 | import org.apache.thrift.transport.TSaslClientTransport; 46 | import org.apache.thrift.transport.TSocket; 47 | import org.apache.thrift.transport.TTransport; 48 | import org.apache.thrift.transport.TTransportException; 49 | import org.apache.thrift.transport.layered.TFramedTransport; 50 | 51 | import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 52 | 53 | public class TestProxyClient implements AutoCloseable { 54 | 55 | protected TProtocolFactory tProtocolFactory; 56 | protected TTransport transport; 57 | 58 | public TestProxyClient(String host, int port) throws TTransportException { 59 | this(host, port, new TCompactProtocol.Factory()); 60 | } 61 | 62 | public TestProxyClient(String host, int port, TProtocolFactory protoFactory) 63 | throws TTransportException { 64 | final TSocket socket = new TSocket(host, port); 65 | socket.setTimeout(600000); 66 | transport = new TFramedTransport(socket); 67 | tProtocolFactory = protoFactory; 68 | transport.open(); 69 | } 70 | 71 | public TestProxyClient(String host, int port, TProtocolFactory protoFactory, String proxyPrimary, 72 | UserGroupInformation ugi) throws SaslException, TTransportException { 73 | TSocket socket = new TSocket(host, port); 74 | TSaslClientTransport saslTransport = new TSaslClientTransport("GSSAPI", null, proxyPrimary, 75 | host, Collections.singletonMap("javax.security.sasl.qop", "auth"), null, socket); 76 | 77 | transport = new UGIAssumingTransport(saslTransport, ugi); 78 | 79 | // UGI transport will perform the doAs for us 80 | transport.open(); 81 | 82 | tProtocolFactory = protoFactory; 83 | } 84 | 85 | public synchronized void close() { 86 | if (transport != null) { 87 | transport.close(); 88 | transport = null; 89 | } 90 | } 91 | 92 | public AccumuloProxy.Client proxy() { 93 | AccumuloProxy.Client.Factory proxyClientFactory = new AccumuloProxy.Client.Factory(); 94 | final TProtocol protocol = tProtocolFactory.getProtocol(transport); 95 | return proxyClientFactory.getClient(protocol); 96 | } 97 | 98 | @SuppressFBWarnings(value = "HARD_CODE_PASSWORD", justification = "test password is okay") 99 | public static void main(String[] args) throws Exception { 100 | 101 | TestProxyClient tpc = new TestProxyClient("localhost", 42424); 102 | String sharedSecret = "secret"; 103 | 104 | System.out.println("Creating user: "); 105 | if (!tpc.proxy().listLocalUsers(sharedSecret).contains("testuser")) { 106 | tpc.proxy().createLocalUser(sharedSecret, "testuser", 107 | ByteBuffer.wrap("testpass".getBytes(UTF_8))); 108 | } 109 | System.out.println("UserList: " + tpc.proxy().listLocalUsers(sharedSecret)); 110 | 111 | System.out.println("Listing: " + tpc.proxy().listTables(sharedSecret)); 112 | 113 | System.out.println("Deleting: "); 114 | String testTable = "testtableOMGOMGOMG"; 115 | 116 | System.out.println("Creating: "); 117 | 118 | if (tpc.proxy().tableExists(sharedSecret, testTable)) { 119 | tpc.proxy().deleteTable(sharedSecret, testTable); 120 | } 121 | 122 | tpc.proxy().createTable(sharedSecret, testTable, true, TimeType.MILLIS); 123 | 124 | System.out.println("Listing: " + tpc.proxy().listTables(sharedSecret)); 125 | 126 | System.out.println("Writing: "); 127 | Date start = new Date(); 128 | Date then = new Date(); 129 | int maxInserts = 1000000; 130 | String format = "%1$05d"; 131 | Map> mutations = new HashMap<>(); 132 | for (int i = 0; i < maxInserts; i++) { 133 | String result = String.format(format, i); 134 | ColumnUpdate update = new ColumnUpdate(ByteBuffer.wrap(("cf" + i).getBytes(UTF_8)), 135 | ByteBuffer.wrap(("cq" + i).getBytes(UTF_8))); 136 | update.setValue(Util.randStringBuffer(10)); 137 | mutations.put(ByteBuffer.wrap(result.getBytes(UTF_8)), Collections.singletonList(update)); 138 | 139 | if (i % 1000 == 0) { 140 | tpc.proxy().updateAndFlush(sharedSecret, testTable, mutations); 141 | mutations.clear(); 142 | } 143 | } 144 | tpc.proxy().updateAndFlush(sharedSecret, testTable, mutations); 145 | Date end = new Date(); 146 | System.out.println(" End of writing: " + (end.getTime() - start.getTime())); 147 | 148 | tpc.proxy().deleteTable(sharedSecret, testTable); 149 | tpc.proxy().createTable(sharedSecret, testTable, true, TimeType.MILLIS); 150 | 151 | // Thread.sleep(1000); 152 | 153 | System.out.println("Writing async: "); 154 | start = new Date(); 155 | then = new Date(); 156 | mutations.clear(); 157 | String writer = tpc.proxy().createWriter(sharedSecret, testTable, null); 158 | for (int i = 0; i < maxInserts; i++) { 159 | String result = String.format(format, i); 160 | Key pkey = new Key(); 161 | pkey.setRow(result.getBytes(UTF_8)); 162 | ColumnUpdate update = new ColumnUpdate(ByteBuffer.wrap(("cf" + i).getBytes(UTF_8)), 163 | ByteBuffer.wrap(("cq" + i).getBytes(UTF_8))); 164 | update.setValue(Util.randStringBuffer(10)); 165 | mutations.put(ByteBuffer.wrap(result.getBytes(UTF_8)), Collections.singletonList(update)); 166 | tpc.proxy().update(writer, mutations); 167 | mutations.clear(); 168 | } 169 | 170 | end = new Date(); 171 | System.out.println(" End of writing: " + (end.getTime() - start.getTime())); 172 | start = end; 173 | System.out.println("Closing..."); 174 | tpc.proxy().closeWriter(writer); 175 | end = new Date(); 176 | System.out.println(" End of closing: " + (end.getTime() - start.getTime())); 177 | 178 | System.out.println("Reading: "); 179 | 180 | String regex = "cf1.*"; 181 | 182 | IteratorSetting is = new IteratorSetting(50, regex, RegExFilter.class); 183 | RegExFilter.setRegexs(is, null, regex, null, null, false); 184 | 185 | String cookie = tpc.proxy().createScanner(sharedSecret, testTable, null); 186 | 187 | int i = 0; 188 | start = new Date(); 189 | then = new Date(); 190 | boolean hasNext = true; 191 | 192 | int k = 1000; 193 | while (hasNext) { 194 | ScanResult kvList = tpc.proxy().nextK(cookie, k); 195 | 196 | Date now = new Date(); 197 | System.out.println(i + " " + (now.getTime() - then.getTime())); 198 | then = now; 199 | 200 | i += kvList.getResultsSize(); 201 | // for (TKeyValue kv:kvList.getResults()) System.out.println(new Key(kv.getKey())); 202 | hasNext = kvList.isMore(); 203 | } 204 | end = new Date(); 205 | System.out.println("Total entries: " + i + " total time " + (end.getTime() - start.getTime())); 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | 204 | -------------------------------------------------------------------------------- /src/main/java/org/apache/accumulo/proxy/Proxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package org.apache.accumulo.proxy; 20 | 21 | import java.io.File; 22 | import java.io.FileInputStream; 23 | import java.io.IOException; 24 | import java.io.InputStream; 25 | import java.io.UncheckedIOException; 26 | import java.nio.file.Files; 27 | import java.util.Collection; 28 | import java.util.Properties; 29 | 30 | import org.apache.accumulo.core.cli.Help; 31 | import org.apache.accumulo.core.client.security.tokens.AuthenticationToken; 32 | import org.apache.accumulo.core.client.security.tokens.KerberosToken; 33 | import org.apache.accumulo.core.clientImpl.ClientConfConverter; 34 | import org.apache.accumulo.core.conf.ClientProperty; 35 | import org.apache.accumulo.core.conf.ConfigurationTypeHelper; 36 | import org.apache.accumulo.core.metrics.MetricsInfo; 37 | import org.apache.accumulo.core.metrics.MetricsProducer; 38 | import org.apache.accumulo.core.rpc.SslConnectionParams; 39 | import org.apache.accumulo.core.trace.TraceUtil; 40 | import org.apache.accumulo.core.util.HostAndPort; 41 | import org.apache.accumulo.core.util.threads.ThreadPools; 42 | import org.apache.accumulo.minicluster.MiniAccumuloCluster; 43 | import org.apache.accumulo.proxy.thrift.AccumuloProxy; 44 | import org.apache.accumulo.server.rpc.SaslServerConnectionParams; 45 | import org.apache.accumulo.server.rpc.ServerAddress; 46 | import org.apache.accumulo.server.rpc.ThriftServerType; 47 | import org.apache.accumulo.server.rpc.TimedProcessor; 48 | import org.apache.accumulo.server.rpc.UGIAssumingProcessor; 49 | import org.apache.accumulo.start.spi.KeywordExecutable; 50 | import org.apache.hadoop.security.UserGroupInformation; 51 | import org.apache.thrift.TProcessor; 52 | import org.apache.thrift.protocol.TCompactProtocol; 53 | import org.apache.thrift.protocol.TProtocolFactory; 54 | import org.slf4j.Logger; 55 | import org.slf4j.LoggerFactory; 56 | 57 | import com.beust.jcommander.IStringConverter; 58 | import com.beust.jcommander.Parameter; 59 | import com.google.auto.service.AutoService; 60 | 61 | import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 62 | import io.micrometer.core.instrument.Tag; 63 | 64 | @AutoService(KeywordExecutable.class) 65 | public class Proxy implements KeywordExecutable { 66 | 67 | private static final Logger log = LoggerFactory.getLogger(Proxy.class); 68 | 69 | public static final String USE_MINI_ACCUMULO_KEY = "useMiniAccumulo"; 70 | public static final String USE_MINI_ACCUMULO_DEFAULT = "false"; 71 | public static final String THRIFT_THREAD_POOL_SIZE_KEY = "numThreads"; 72 | // Default number of threads from THsHaServer.Args 73 | public static final String THRIFT_THREAD_POOL_SIZE_DEFAULT = "5"; 74 | public static final String THRIFT_MAX_FRAME_SIZE_KEY = "maxFrameSize"; 75 | public static final String THRIFT_MAX_FRAME_SIZE_DEFAULT = "16M"; 76 | 77 | // Type of thrift server to create 78 | public static final String THRIFT_SERVER_TYPE = "thriftServerType"; 79 | public static final String THRIFT_SERVER_TYPE_DEFAULT = ""; 80 | public static final ThriftServerType DEFAULT_SERVER_TYPE = ThriftServerType.getDefault(); 81 | 82 | public static final String THRIFT_SERVER_HOSTNAME = "thriftServerHostname"; 83 | public static final String THRIFT_SERVER_HOSTNAME_DEFAULT = "0.0.0.0"; 84 | 85 | public static class PropertiesConverter implements IStringConverter { 86 | 87 | @SuppressFBWarnings(value = "PATH_TRAVERSAL_IN", 88 | justification = "app is run in same security context as user providing the filename") 89 | @Override 90 | public Properties convert(String fileName) { 91 | Properties prop = new Properties(); 92 | try (InputStream is = new FileInputStream(fileName)) { 93 | prop.load(is); 94 | } catch (IOException e) { 95 | throw new RuntimeException(e); 96 | } 97 | return prop; 98 | } 99 | } 100 | 101 | public static class Opts extends Help { 102 | @Parameter(names = "-p", description = "proxy.properties path", required = true, 103 | converter = PropertiesConverter.class) 104 | Properties proxyProps; 105 | } 106 | 107 | @Override 108 | public String keyword() { 109 | return "proxy"; 110 | } 111 | 112 | @Override 113 | public UsageGroup usageGroup() { 114 | return UsageGroup.PROCESS; 115 | } 116 | 117 | @Override 118 | public String description() { 119 | return "Starts Accumulo proxy"; 120 | } 121 | 122 | @SuppressFBWarnings(value = "DM_EXIT", justification = "System.exit() from a main class is okay") 123 | @Override 124 | public void execute(final String[] args) throws Exception { 125 | Opts opts = new Opts(); 126 | opts.parseArgs(Proxy.class.getName(), args); 127 | 128 | Properties proxyProps = opts.proxyProps; 129 | 130 | boolean useMini = Boolean 131 | .parseBoolean(proxyProps.getProperty(USE_MINI_ACCUMULO_KEY, USE_MINI_ACCUMULO_DEFAULT)); 132 | 133 | if (!proxyProps.containsKey("port")) { 134 | System.err.println("No port property"); 135 | System.exit(1); 136 | } 137 | 138 | if (useMini) { 139 | log.info("Creating mini cluster"); 140 | final File folder = Files.createTempDirectory(System.currentTimeMillis() + "").toFile(); 141 | final MiniAccumuloCluster accumulo = new MiniAccumuloCluster(folder, "secret"); 142 | accumulo.start(); 143 | proxyProps.putAll(accumulo.getClientProperties()); 144 | Runtime.getRuntime().addShutdownHook(new Thread(() -> { 145 | try { 146 | accumulo.close(); 147 | } catch (IOException e) { 148 | throw new UncheckedIOException(e); 149 | } finally { 150 | if (!folder.delete()) { 151 | log.warn("Unexpected error removing {}", folder); 152 | } 153 | } 154 | })); 155 | } 156 | 157 | Class protoFactoryClass = Class 158 | .forName( 159 | proxyProps.getProperty("protocolFactory", TCompactProtocol.Factory.class.getName())) 160 | .asSubclass(TProtocolFactory.class); 161 | TProtocolFactory protoFactory = protoFactoryClass.getDeclaredConstructor().newInstance(); 162 | int port = Integer.parseInt(proxyProps.getProperty("port")); 163 | String hostname = 164 | proxyProps.getProperty(THRIFT_SERVER_HOSTNAME, THRIFT_SERVER_HOSTNAME_DEFAULT); 165 | HostAndPort address = HostAndPort.fromParts(hostname, port); 166 | ServerAddress server = createProxyServer(address, protoFactory, proxyProps); 167 | // Wait for the server to come up 168 | while (!server.server.isServing()) { 169 | Thread.sleep(100); 170 | } 171 | log.info("Proxy server started on {}", server.getAddress()); 172 | while (server.server.isServing()) { 173 | Thread.sleep(1000); 174 | } 175 | } 176 | 177 | public static void main(String[] args) throws Exception { 178 | new Proxy().execute(args); 179 | } 180 | 181 | public static ServerAddress createProxyServer(HostAndPort address, 182 | TProtocolFactory protocolFactory, Properties props) throws Exception { 183 | final int numThreads = Integer 184 | .parseInt(props.getProperty(THRIFT_THREAD_POOL_SIZE_KEY, THRIFT_THREAD_POOL_SIZE_DEFAULT)); 185 | final long maxFrameSize = ConfigurationTypeHelper.getFixedMemoryAsBytes( 186 | props.getProperty(THRIFT_MAX_FRAME_SIZE_KEY, THRIFT_MAX_FRAME_SIZE_DEFAULT)); 187 | // No timeout 188 | final long serverSocketTimeout = 0L; 189 | // Use the new hadoop metrics2 support 190 | final String serverName = "Proxy", threadName = "Accumulo Thrift Proxy"; 191 | 192 | // create the implementation of the proxy interface 193 | ProxyServer impl = new ProxyServer(props); 194 | 195 | // Wrap the implementation -- translate some exceptions 196 | AccumuloProxy.Iface wrappedImpl = TraceUtil.wrapService(impl); 197 | 198 | // Create the processor from the implementation 199 | TProcessor processor = new AccumuloProxy.Processor<>(wrappedImpl); 200 | 201 | // Get the type of thrift server to instantiate 202 | final String serverTypeStr = props.getProperty(THRIFT_SERVER_TYPE, THRIFT_SERVER_TYPE_DEFAULT); 203 | ThriftServerType serverType = DEFAULT_SERVER_TYPE; 204 | if (!THRIFT_SERVER_TYPE_DEFAULT.equals(serverTypeStr)) { 205 | serverType = ThriftServerType.get(serverTypeStr); 206 | } 207 | 208 | SslConnectionParams sslParams = null; 209 | SaslServerConnectionParams saslParams = null; 210 | switch (serverType) { 211 | case SSL: 212 | sslParams = SslConnectionParams.forClient(ClientConfConverter.toAccumuloConf(props)); 213 | break; 214 | case SASL: 215 | if (!ClientProperty.SASL_ENABLED.getBoolean(props)) { 216 | throw new IllegalStateException("SASL thrift server was requested but 'sasl.enabled' is" 217 | + " not set to true in configuration"); 218 | } 219 | 220 | // Kerberos needs to be enabled to use it 221 | if (!UserGroupInformation.isSecurityEnabled()) { 222 | throw new IllegalStateException("Hadoop security is not enabled"); 223 | } 224 | 225 | // Login via principal and keytab 226 | final String kerberosPrincipal = ClientProperty.AUTH_PRINCIPAL.getValue(props); 227 | final AuthenticationToken authToken = ClientProperty.getAuthenticationToken(props); 228 | if (!(authToken instanceof KerberosToken)) { 229 | throw new IllegalStateException("Kerberos authentication must be used with SASL"); 230 | } 231 | final KerberosToken kerberosToken = (KerberosToken) authToken; 232 | final String kerberosKeytab = kerberosToken.getKeytab().getAbsolutePath(); 233 | 234 | if (kerberosPrincipal.isBlank() || kerberosKeytab.isBlank()) { 235 | throw new IllegalStateException( 236 | String.format("Kerberos principal '%s' and keytab '%s' must be provided", 237 | kerberosPrincipal, kerberosKeytab)); 238 | } 239 | UserGroupInformation.loginUserFromKeytab(kerberosPrincipal, kerberosKeytab); 240 | UserGroupInformation ugi = UserGroupInformation.getCurrentUser(); 241 | log.info("Logged in as {}", ugi.getUserName()); 242 | 243 | // The kerberosPrimary set in the SASL server needs to match the principal we're logged in 244 | // as. 245 | final String shortName = ugi.getShortUserName(); 246 | log.info("Setting server primary to {}", shortName); 247 | props.setProperty(ClientProperty.SASL_KERBEROS_SERVER_PRIMARY.getKey(), shortName); 248 | 249 | KerberosToken token = new KerberosToken(); 250 | saslParams = new SaslServerConnectionParams(props, token, null); 251 | processor = new UGIAssumingProcessor(processor); 252 | 253 | break; 254 | default: 255 | // nothing to do -- no extra configuration necessary 256 | break; 257 | } 258 | 259 | TimedProcessor timedProcessor = new TimedProcessor(processor, new ProxyMetricsInfo()); 260 | 261 | // Create the thrift server with our processor and properties 262 | return TServerUtils.startTServer(serverType, timedProcessor, protocolFactory, serverName, 263 | threadName, numThreads, ThreadPools.DEFAULT_TIMEOUT_MILLISECS, 264 | ClientConfConverter.toAccumuloConf(props), 1000L, maxFrameSize, sslParams, saslParams, 265 | serverSocketTimeout, address); 266 | } 267 | 268 | // This MetricsInfo is a stub MetricsInfo to allow the timed processor to build. 269 | // Issue #85 in the GitHub regards updating this with a proper implementation. 270 | static private class ProxyMetricsInfo implements MetricsInfo { 271 | 272 | @Override 273 | public boolean isMetricsEnabled() { 274 | return false; 275 | } 276 | 277 | @Override 278 | public void addMetricsProducers(MetricsProducer... producer) { 279 | return; 280 | } 281 | 282 | @Override 283 | public void close() { 284 | throw new UnsupportedOperationException("Unimplemented method 'close'"); 285 | } 286 | 287 | @Override 288 | public void init(Collection commonTags) { 289 | throw new UnsupportedOperationException("Unimplemented method 'init'"); 290 | } 291 | 292 | } 293 | } 294 | -------------------------------------------------------------------------------- /contrib/create-release-candidate.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | # 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # 20 | 21 | cd "$(dirname "$0")/.." || exit 1 22 | scriptname=$(basename "$0") 23 | export tlpName=Accumulo 24 | export projName="$tlpName-maven-plugin" 25 | export projNameLong="Apache Maven Plugin" 26 | export stagingRepoPrefix="https://repository.apache.org/content/repositories/orgapache$tlpName" 27 | export srcQualifier="source-release" 28 | export relTestingUrl="https://$tlpName.apache.org/release-process/#test-a-$tlpName-release" 29 | export tagPrefix="rel/$projName-" 30 | 31 | # check for gpg2 32 | hash gpg2 2>/dev/null && gpgCommand=gpg2 || gpgCommand=gpg 33 | 34 | # check if running in a color terminal 35 | terminalSupportsColor() { 36 | local c; c=$(tput colors 2>/dev/null) || c=-1 37 | [[ -t 1 ]] && [[ $c -ge 8 ]] 38 | } 39 | terminalSupportsColor && doColor=1 || doColor=0 40 | 41 | color() { local c; c=$1; shift; [[ $doColor -eq 1 ]] && echo -e "\\e[0;${c}m${*}\\e[0m" || echo "$@"; } 42 | red() { color 31 "$@"; } 43 | green() { color 32 "$@"; } 44 | yellow() { color 33 "$@"; } 45 | 46 | fail() { echo -e ' ' "$@"; exit 1; } 47 | runLog() { local o; o=$1 && shift && echo "$(green Running) $(yellow "$@" '>>' "$o")" && echo Running "$@" >> "$o" && eval "$@" >> "$o"; } 48 | run() { echo "$(green Running) $(yellow "$@")" && eval "$@"; } 49 | runOrFail() { run "$@" || fail "$(yellow "$@")" "$(red failed)"; } 50 | 51 | currentBranch() { local b; b=$(git symbolic-ref -q HEAD) && echo "${b##refs/heads/}"; } 52 | 53 | cacheGPG() { 54 | # make sure gpg agent has key cached 55 | # first clear cache, to reset timeouts (best attempt) 56 | { hash gpg-connect-agent && gpg-connect-agent reloadagent /bye; } &>/dev/null 57 | # TODO prompt for key instead of using default? 58 | local TESTFILE; TESTFILE=$(mktemp --tmpdir "${USER}-gpgTestFile-XXXXXXXX.txt") 59 | [[ -r $TESTFILE ]] && "$gpgCommand" --sign "${TESTFILE}" && rm -f "${TESTFILE}" "${TESTFILE}.gpg" 60 | } 61 | 62 | prompter() { 63 | # $1 description; $2 pattern to validate against 64 | local x 65 | read -r -p "Enter the $1: " x 66 | until eval "[[ \$x =~ ^$2\$ ]]"; do 67 | echo " $(red "$x") is not a proper $1" 1>&2 68 | read -r -p "Enter the $1: " x 69 | done 70 | echo "$x" 71 | } 72 | 73 | pretty() { local f; f=$1; shift; git log "--pretty=tformat:$f" "$@"; } 74 | gitCommits() { pretty %H "$@"; } 75 | gitCommit() { gitCommits -n1 "$@"; } 76 | gitSubject() { pretty %s "$@"; } 77 | 78 | createEmail() { 79 | # $1 version (optional); $2 rc sequence num (optional); $3 staging repo num (optional) 80 | local ver; [[ -n "$1" ]] && ver=$1 || ver=$(prompter 'version to be released (eg. x.y.z)' '[0-9]+[.][0-9]+[.][0-9]+') 81 | local rc; [[ -n "$2" ]] && rc=$2 || rc=$(prompter 'release candidate sequence number (eg. 1, 2, etc.)' '[0-9]+') 82 | local stagingrepo; [[ -n "$3" ]] && stagingrepo=$3 || stagingrepo=$(prompter 'staging repository number from https://repository.apache.org/#stagingRepositories' '[0-9]+') 83 | local srcSha; [[ -n "$4" ]] && srcSha=$4 || srcSha=$(prompter 'SHA512 for source tarball' '[0-9a-f]{128}') 84 | 85 | local branch; branch=$ver-rc$rc 86 | local commit; commit=$(gitCommit "$branch") || exit 1 87 | local tag; tag=$tagPrefix$ver 88 | echo 89 | yellow "IMPORTANT!! IMPORTANT!! IMPORTANT!! IMPORTANT!! IMPORTANT!! IMPORTANT!!" 90 | echo 91 | echo " Don't forget to push a branch named $(green "$branch") with" 92 | echo " its head at $(green "${commit:0:7}") so others can review using:" 93 | echo " $(green "git push origin ${commit:0:7}:refs/heads/$branch")" 94 | echo 95 | echo " Remember, $(red DO NOT PUSH) the $(red "$tag") tag until after the vote" 96 | echo " passes and the tag is re-made with a gpg signature using:" 97 | echo " $(red "git tag -f -m '$projNameLong $ver' -s $tag ${commit:0:7}")" 98 | echo 99 | yellow "IMPORTANT!! IMPORTANT!! IMPORTANT!! IMPORTANT!! IMPORTANT!! IMPORTANT!!" 100 | echo 101 | read -r -s -p 'Press Enter to generate the [VOTE] email...' 102 | echo 1>&2 103 | 104 | # compute the date with a buffer of 30 minutes 105 | local votedate; votedate=$(date -d "+3 days 30 minutes" "+%s") 106 | # round back to the previous half-hour 107 | local halfhour; halfhour=$((votedate - (votedate % 1800))) 108 | votedate=$(date -u -d"1970-01-01 $halfhour seconds UTC") 109 | export TZ="America/New_York" 110 | local edtvotedate; edtvotedate=$(date -d"1970-01-01 $halfhour seconds UTC") 111 | export TZ="America/Los_Angeles" 112 | local pdtvotedate; pdtvotedate=$(date -d"1970-01-01 $halfhour seconds UTC") 113 | 114 | local fingerprint; fingerprint=$("$gpgCommand" --list-secret-keys --with-colons --with-fingerprint 2>/dev/null | awk -F: '$1 == "fpr" {print $10}') 115 | [[ -z $fingerprint ]] && fingerprint="UNSPECIFIED" 116 | 117 | cat <, java.io.Serializable, Cloneable, Comparable { 29 | private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("UnknownWriter"); 30 | 31 | private static final org.apache.thrift.protocol.TField MSG_FIELD_DESC = new org.apache.thrift.protocol.TField("msg", org.apache.thrift.protocol.TType.STRING, (short)1); 32 | 33 | private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new UnknownWriterStandardSchemeFactory(); 34 | private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new UnknownWriterTupleSchemeFactory(); 35 | 36 | public @org.apache.thrift.annotation.Nullable java.lang.String msg; // required 37 | 38 | /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ 39 | public enum _Fields implements org.apache.thrift.TFieldIdEnum { 40 | MSG((short)1, "msg"); 41 | 42 | private static final java.util.Map byName = new java.util.HashMap(); 43 | 44 | static { 45 | for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) { 46 | byName.put(field.getFieldName(), field); 47 | } 48 | } 49 | 50 | /** 51 | * Find the _Fields constant that matches fieldId, or null if its not found. 52 | */ 53 | @org.apache.thrift.annotation.Nullable 54 | public static _Fields findByThriftId(int fieldId) { 55 | switch(fieldId) { 56 | case 1: // MSG 57 | return MSG; 58 | default: 59 | return null; 60 | } 61 | } 62 | 63 | /** 64 | * Find the _Fields constant that matches fieldId, throwing an exception 65 | * if it is not found. 66 | */ 67 | public static _Fields findByThriftIdOrThrow(int fieldId) { 68 | _Fields fields = findByThriftId(fieldId); 69 | if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!"); 70 | return fields; 71 | } 72 | 73 | /** 74 | * Find the _Fields constant that matches name, or null if its not found. 75 | */ 76 | @org.apache.thrift.annotation.Nullable 77 | public static _Fields findByName(java.lang.String name) { 78 | return byName.get(name); 79 | } 80 | 81 | private final short _thriftId; 82 | private final java.lang.String _fieldName; 83 | 84 | _Fields(short thriftId, java.lang.String fieldName) { 85 | _thriftId = thriftId; 86 | _fieldName = fieldName; 87 | } 88 | 89 | @Override 90 | public short getThriftFieldId() { 91 | return _thriftId; 92 | } 93 | 94 | @Override 95 | public java.lang.String getFieldName() { 96 | return _fieldName; 97 | } 98 | } 99 | 100 | // isset id assignments 101 | public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; 102 | static { 103 | java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); 104 | tmpMap.put(_Fields.MSG, new org.apache.thrift.meta_data.FieldMetaData("msg", org.apache.thrift.TFieldRequirementType.DEFAULT, 105 | new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); 106 | metaDataMap = java.util.Collections.unmodifiableMap(tmpMap); 107 | org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(UnknownWriter.class, metaDataMap); 108 | } 109 | 110 | public UnknownWriter() { 111 | } 112 | 113 | public UnknownWriter( 114 | java.lang.String msg) 115 | { 116 | this(); 117 | this.msg = msg; 118 | } 119 | 120 | /** 121 | * Performs a deep copy on other. 122 | */ 123 | public UnknownWriter(UnknownWriter other) { 124 | if (other.isSetMsg()) { 125 | this.msg = other.msg; 126 | } 127 | } 128 | 129 | @Override 130 | public UnknownWriter deepCopy() { 131 | return new UnknownWriter(this); 132 | } 133 | 134 | @Override 135 | public void clear() { 136 | this.msg = null; 137 | } 138 | 139 | @org.apache.thrift.annotation.Nullable 140 | public java.lang.String getMsg() { 141 | return this.msg; 142 | } 143 | 144 | public UnknownWriter setMsg(@org.apache.thrift.annotation.Nullable java.lang.String msg) { 145 | this.msg = msg; 146 | return this; 147 | } 148 | 149 | public void unsetMsg() { 150 | this.msg = null; 151 | } 152 | 153 | /** Returns true if field msg is set (has been assigned a value) and false otherwise */ 154 | public boolean isSetMsg() { 155 | return this.msg != null; 156 | } 157 | 158 | public void setMsgIsSet(boolean value) { 159 | if (!value) { 160 | this.msg = null; 161 | } 162 | } 163 | 164 | @Override 165 | public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) { 166 | switch (field) { 167 | case MSG: 168 | if (value == null) { 169 | unsetMsg(); 170 | } else { 171 | setMsg((java.lang.String)value); 172 | } 173 | break; 174 | 175 | } 176 | } 177 | 178 | @org.apache.thrift.annotation.Nullable 179 | @Override 180 | public java.lang.Object getFieldValue(_Fields field) { 181 | switch (field) { 182 | case MSG: 183 | return getMsg(); 184 | 185 | } 186 | throw new java.lang.IllegalStateException(); 187 | } 188 | 189 | /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ 190 | @Override 191 | public boolean isSet(_Fields field) { 192 | if (field == null) { 193 | throw new java.lang.IllegalArgumentException(); 194 | } 195 | 196 | switch (field) { 197 | case MSG: 198 | return isSetMsg(); 199 | } 200 | throw new java.lang.IllegalStateException(); 201 | } 202 | 203 | @Override 204 | public boolean equals(java.lang.Object that) { 205 | if (that instanceof UnknownWriter) 206 | return this.equals((UnknownWriter)that); 207 | return false; 208 | } 209 | 210 | public boolean equals(UnknownWriter that) { 211 | if (that == null) 212 | return false; 213 | if (this == that) 214 | return true; 215 | 216 | boolean this_present_msg = true && this.isSetMsg(); 217 | boolean that_present_msg = true && that.isSetMsg(); 218 | if (this_present_msg || that_present_msg) { 219 | if (!(this_present_msg && that_present_msg)) 220 | return false; 221 | if (!this.msg.equals(that.msg)) 222 | return false; 223 | } 224 | 225 | return true; 226 | } 227 | 228 | @Override 229 | public int hashCode() { 230 | int hashCode = 1; 231 | 232 | hashCode = hashCode * 8191 + ((isSetMsg()) ? 131071 : 524287); 233 | if (isSetMsg()) 234 | hashCode = hashCode * 8191 + msg.hashCode(); 235 | 236 | return hashCode; 237 | } 238 | 239 | @Override 240 | public int compareTo(UnknownWriter other) { 241 | if (!getClass().equals(other.getClass())) { 242 | return getClass().getName().compareTo(other.getClass().getName()); 243 | } 244 | 245 | int lastComparison = 0; 246 | 247 | lastComparison = java.lang.Boolean.compare(isSetMsg(), other.isSetMsg()); 248 | if (lastComparison != 0) { 249 | return lastComparison; 250 | } 251 | if (isSetMsg()) { 252 | lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.msg, other.msg); 253 | if (lastComparison != 0) { 254 | return lastComparison; 255 | } 256 | } 257 | return 0; 258 | } 259 | 260 | @org.apache.thrift.annotation.Nullable 261 | @Override 262 | public _Fields fieldForId(int fieldId) { 263 | return _Fields.findByThriftId(fieldId); 264 | } 265 | 266 | @Override 267 | public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { 268 | scheme(iprot).read(iprot, this); 269 | } 270 | 271 | @Override 272 | public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { 273 | scheme(oprot).write(oprot, this); 274 | } 275 | 276 | @Override 277 | public java.lang.String toString() { 278 | java.lang.StringBuilder sb = new java.lang.StringBuilder("UnknownWriter("); 279 | boolean first = true; 280 | 281 | sb.append("msg:"); 282 | if (this.msg == null) { 283 | sb.append("null"); 284 | } else { 285 | sb.append(this.msg); 286 | } 287 | first = false; 288 | sb.append(")"); 289 | return sb.toString(); 290 | } 291 | 292 | public void validate() throws org.apache.thrift.TException { 293 | // check for required fields 294 | // check for sub-struct validity 295 | } 296 | 297 | private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { 298 | try { 299 | write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); 300 | } catch (org.apache.thrift.TException te) { 301 | throw new java.io.IOException(te); 302 | } 303 | } 304 | 305 | private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException { 306 | try { 307 | read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); 308 | } catch (org.apache.thrift.TException te) { 309 | throw new java.io.IOException(te); 310 | } 311 | } 312 | 313 | private static class UnknownWriterStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory { 314 | @Override 315 | public UnknownWriterStandardScheme getScheme() { 316 | return new UnknownWriterStandardScheme(); 317 | } 318 | } 319 | 320 | private static class UnknownWriterStandardScheme extends org.apache.thrift.scheme.StandardScheme { 321 | 322 | @Override 323 | public void read(org.apache.thrift.protocol.TProtocol iprot, UnknownWriter struct) throws org.apache.thrift.TException { 324 | org.apache.thrift.protocol.TField schemeField; 325 | iprot.readStructBegin(); 326 | while (true) 327 | { 328 | schemeField = iprot.readFieldBegin(); 329 | if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 330 | break; 331 | } 332 | switch (schemeField.id) { 333 | case 1: // MSG 334 | if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { 335 | struct.msg = iprot.readString(); 336 | struct.setMsgIsSet(true); 337 | } else { 338 | org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); 339 | } 340 | break; 341 | default: 342 | org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); 343 | } 344 | iprot.readFieldEnd(); 345 | } 346 | iprot.readStructEnd(); 347 | 348 | // check for required fields of primitive type, which can't be checked in the validate method 349 | struct.validate(); 350 | } 351 | 352 | @Override 353 | public void write(org.apache.thrift.protocol.TProtocol oprot, UnknownWriter struct) throws org.apache.thrift.TException { 354 | struct.validate(); 355 | 356 | oprot.writeStructBegin(STRUCT_DESC); 357 | if (struct.msg != null) { 358 | oprot.writeFieldBegin(MSG_FIELD_DESC); 359 | oprot.writeString(struct.msg); 360 | oprot.writeFieldEnd(); 361 | } 362 | oprot.writeFieldStop(); 363 | oprot.writeStructEnd(); 364 | } 365 | 366 | } 367 | 368 | private static class UnknownWriterTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory { 369 | @Override 370 | public UnknownWriterTupleScheme getScheme() { 371 | return new UnknownWriterTupleScheme(); 372 | } 373 | } 374 | 375 | private static class UnknownWriterTupleScheme extends org.apache.thrift.scheme.TupleScheme { 376 | 377 | @Override 378 | public void write(org.apache.thrift.protocol.TProtocol prot, UnknownWriter struct) throws org.apache.thrift.TException { 379 | org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot; 380 | java.util.BitSet optionals = new java.util.BitSet(); 381 | if (struct.isSetMsg()) { 382 | optionals.set(0); 383 | } 384 | oprot.writeBitSet(optionals, 1); 385 | if (struct.isSetMsg()) { 386 | oprot.writeString(struct.msg); 387 | } 388 | } 389 | 390 | @Override 391 | public void read(org.apache.thrift.protocol.TProtocol prot, UnknownWriter struct) throws org.apache.thrift.TException { 392 | org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot; 393 | java.util.BitSet incoming = iprot.readBitSet(1); 394 | if (incoming.get(0)) { 395 | struct.msg = iprot.readString(); 396 | struct.setMsgIsSet(true); 397 | } 398 | } 399 | } 400 | 401 | private static S scheme(org.apache.thrift.protocol.TProtocol proto) { 402 | return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme(); 403 | } 404 | private static void unusedMethod() {} 405 | } 406 | 407 | -------------------------------------------------------------------------------- /src/main/thrift-gen-java/org/apache/accumulo/proxy/thrift/UnknownScanner.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | /** 20 | * Autogenerated by Thrift Compiler (0.17.0) 21 | * 22 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 23 | * @generated 24 | */ 25 | package org.apache.accumulo.proxy.thrift; 26 | 27 | @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"}) 28 | public class UnknownScanner extends org.apache.thrift.TException implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { 29 | private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("UnknownScanner"); 30 | 31 | private static final org.apache.thrift.protocol.TField MSG_FIELD_DESC = new org.apache.thrift.protocol.TField("msg", org.apache.thrift.protocol.TType.STRING, (short)1); 32 | 33 | private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new UnknownScannerStandardSchemeFactory(); 34 | private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new UnknownScannerTupleSchemeFactory(); 35 | 36 | public @org.apache.thrift.annotation.Nullable java.lang.String msg; // required 37 | 38 | /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ 39 | public enum _Fields implements org.apache.thrift.TFieldIdEnum { 40 | MSG((short)1, "msg"); 41 | 42 | private static final java.util.Map byName = new java.util.HashMap(); 43 | 44 | static { 45 | for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) { 46 | byName.put(field.getFieldName(), field); 47 | } 48 | } 49 | 50 | /** 51 | * Find the _Fields constant that matches fieldId, or null if its not found. 52 | */ 53 | @org.apache.thrift.annotation.Nullable 54 | public static _Fields findByThriftId(int fieldId) { 55 | switch(fieldId) { 56 | case 1: // MSG 57 | return MSG; 58 | default: 59 | return null; 60 | } 61 | } 62 | 63 | /** 64 | * Find the _Fields constant that matches fieldId, throwing an exception 65 | * if it is not found. 66 | */ 67 | public static _Fields findByThriftIdOrThrow(int fieldId) { 68 | _Fields fields = findByThriftId(fieldId); 69 | if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!"); 70 | return fields; 71 | } 72 | 73 | /** 74 | * Find the _Fields constant that matches name, or null if its not found. 75 | */ 76 | @org.apache.thrift.annotation.Nullable 77 | public static _Fields findByName(java.lang.String name) { 78 | return byName.get(name); 79 | } 80 | 81 | private final short _thriftId; 82 | private final java.lang.String _fieldName; 83 | 84 | _Fields(short thriftId, java.lang.String fieldName) { 85 | _thriftId = thriftId; 86 | _fieldName = fieldName; 87 | } 88 | 89 | @Override 90 | public short getThriftFieldId() { 91 | return _thriftId; 92 | } 93 | 94 | @Override 95 | public java.lang.String getFieldName() { 96 | return _fieldName; 97 | } 98 | } 99 | 100 | // isset id assignments 101 | public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; 102 | static { 103 | java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); 104 | tmpMap.put(_Fields.MSG, new org.apache.thrift.meta_data.FieldMetaData("msg", org.apache.thrift.TFieldRequirementType.DEFAULT, 105 | new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); 106 | metaDataMap = java.util.Collections.unmodifiableMap(tmpMap); 107 | org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(UnknownScanner.class, metaDataMap); 108 | } 109 | 110 | public UnknownScanner() { 111 | } 112 | 113 | public UnknownScanner( 114 | java.lang.String msg) 115 | { 116 | this(); 117 | this.msg = msg; 118 | } 119 | 120 | /** 121 | * Performs a deep copy on other. 122 | */ 123 | public UnknownScanner(UnknownScanner other) { 124 | if (other.isSetMsg()) { 125 | this.msg = other.msg; 126 | } 127 | } 128 | 129 | @Override 130 | public UnknownScanner deepCopy() { 131 | return new UnknownScanner(this); 132 | } 133 | 134 | @Override 135 | public void clear() { 136 | this.msg = null; 137 | } 138 | 139 | @org.apache.thrift.annotation.Nullable 140 | public java.lang.String getMsg() { 141 | return this.msg; 142 | } 143 | 144 | public UnknownScanner setMsg(@org.apache.thrift.annotation.Nullable java.lang.String msg) { 145 | this.msg = msg; 146 | return this; 147 | } 148 | 149 | public void unsetMsg() { 150 | this.msg = null; 151 | } 152 | 153 | /** Returns true if field msg is set (has been assigned a value) and false otherwise */ 154 | public boolean isSetMsg() { 155 | return this.msg != null; 156 | } 157 | 158 | public void setMsgIsSet(boolean value) { 159 | if (!value) { 160 | this.msg = null; 161 | } 162 | } 163 | 164 | @Override 165 | public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) { 166 | switch (field) { 167 | case MSG: 168 | if (value == null) { 169 | unsetMsg(); 170 | } else { 171 | setMsg((java.lang.String)value); 172 | } 173 | break; 174 | 175 | } 176 | } 177 | 178 | @org.apache.thrift.annotation.Nullable 179 | @Override 180 | public java.lang.Object getFieldValue(_Fields field) { 181 | switch (field) { 182 | case MSG: 183 | return getMsg(); 184 | 185 | } 186 | throw new java.lang.IllegalStateException(); 187 | } 188 | 189 | /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ 190 | @Override 191 | public boolean isSet(_Fields field) { 192 | if (field == null) { 193 | throw new java.lang.IllegalArgumentException(); 194 | } 195 | 196 | switch (field) { 197 | case MSG: 198 | return isSetMsg(); 199 | } 200 | throw new java.lang.IllegalStateException(); 201 | } 202 | 203 | @Override 204 | public boolean equals(java.lang.Object that) { 205 | if (that instanceof UnknownScanner) 206 | return this.equals((UnknownScanner)that); 207 | return false; 208 | } 209 | 210 | public boolean equals(UnknownScanner that) { 211 | if (that == null) 212 | return false; 213 | if (this == that) 214 | return true; 215 | 216 | boolean this_present_msg = true && this.isSetMsg(); 217 | boolean that_present_msg = true && that.isSetMsg(); 218 | if (this_present_msg || that_present_msg) { 219 | if (!(this_present_msg && that_present_msg)) 220 | return false; 221 | if (!this.msg.equals(that.msg)) 222 | return false; 223 | } 224 | 225 | return true; 226 | } 227 | 228 | @Override 229 | public int hashCode() { 230 | int hashCode = 1; 231 | 232 | hashCode = hashCode * 8191 + ((isSetMsg()) ? 131071 : 524287); 233 | if (isSetMsg()) 234 | hashCode = hashCode * 8191 + msg.hashCode(); 235 | 236 | return hashCode; 237 | } 238 | 239 | @Override 240 | public int compareTo(UnknownScanner other) { 241 | if (!getClass().equals(other.getClass())) { 242 | return getClass().getName().compareTo(other.getClass().getName()); 243 | } 244 | 245 | int lastComparison = 0; 246 | 247 | lastComparison = java.lang.Boolean.compare(isSetMsg(), other.isSetMsg()); 248 | if (lastComparison != 0) { 249 | return lastComparison; 250 | } 251 | if (isSetMsg()) { 252 | lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.msg, other.msg); 253 | if (lastComparison != 0) { 254 | return lastComparison; 255 | } 256 | } 257 | return 0; 258 | } 259 | 260 | @org.apache.thrift.annotation.Nullable 261 | @Override 262 | public _Fields fieldForId(int fieldId) { 263 | return _Fields.findByThriftId(fieldId); 264 | } 265 | 266 | @Override 267 | public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { 268 | scheme(iprot).read(iprot, this); 269 | } 270 | 271 | @Override 272 | public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { 273 | scheme(oprot).write(oprot, this); 274 | } 275 | 276 | @Override 277 | public java.lang.String toString() { 278 | java.lang.StringBuilder sb = new java.lang.StringBuilder("UnknownScanner("); 279 | boolean first = true; 280 | 281 | sb.append("msg:"); 282 | if (this.msg == null) { 283 | sb.append("null"); 284 | } else { 285 | sb.append(this.msg); 286 | } 287 | first = false; 288 | sb.append(")"); 289 | return sb.toString(); 290 | } 291 | 292 | public void validate() throws org.apache.thrift.TException { 293 | // check for required fields 294 | // check for sub-struct validity 295 | } 296 | 297 | private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { 298 | try { 299 | write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); 300 | } catch (org.apache.thrift.TException te) { 301 | throw new java.io.IOException(te); 302 | } 303 | } 304 | 305 | private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException { 306 | try { 307 | read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); 308 | } catch (org.apache.thrift.TException te) { 309 | throw new java.io.IOException(te); 310 | } 311 | } 312 | 313 | private static class UnknownScannerStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory { 314 | @Override 315 | public UnknownScannerStandardScheme getScheme() { 316 | return new UnknownScannerStandardScheme(); 317 | } 318 | } 319 | 320 | private static class UnknownScannerStandardScheme extends org.apache.thrift.scheme.StandardScheme { 321 | 322 | @Override 323 | public void read(org.apache.thrift.protocol.TProtocol iprot, UnknownScanner struct) throws org.apache.thrift.TException { 324 | org.apache.thrift.protocol.TField schemeField; 325 | iprot.readStructBegin(); 326 | while (true) 327 | { 328 | schemeField = iprot.readFieldBegin(); 329 | if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 330 | break; 331 | } 332 | switch (schemeField.id) { 333 | case 1: // MSG 334 | if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { 335 | struct.msg = iprot.readString(); 336 | struct.setMsgIsSet(true); 337 | } else { 338 | org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); 339 | } 340 | break; 341 | default: 342 | org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); 343 | } 344 | iprot.readFieldEnd(); 345 | } 346 | iprot.readStructEnd(); 347 | 348 | // check for required fields of primitive type, which can't be checked in the validate method 349 | struct.validate(); 350 | } 351 | 352 | @Override 353 | public void write(org.apache.thrift.protocol.TProtocol oprot, UnknownScanner struct) throws org.apache.thrift.TException { 354 | struct.validate(); 355 | 356 | oprot.writeStructBegin(STRUCT_DESC); 357 | if (struct.msg != null) { 358 | oprot.writeFieldBegin(MSG_FIELD_DESC); 359 | oprot.writeString(struct.msg); 360 | oprot.writeFieldEnd(); 361 | } 362 | oprot.writeFieldStop(); 363 | oprot.writeStructEnd(); 364 | } 365 | 366 | } 367 | 368 | private static class UnknownScannerTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory { 369 | @Override 370 | public UnknownScannerTupleScheme getScheme() { 371 | return new UnknownScannerTupleScheme(); 372 | } 373 | } 374 | 375 | private static class UnknownScannerTupleScheme extends org.apache.thrift.scheme.TupleScheme { 376 | 377 | @Override 378 | public void write(org.apache.thrift.protocol.TProtocol prot, UnknownScanner struct) throws org.apache.thrift.TException { 379 | org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot; 380 | java.util.BitSet optionals = new java.util.BitSet(); 381 | if (struct.isSetMsg()) { 382 | optionals.set(0); 383 | } 384 | oprot.writeBitSet(optionals, 1); 385 | if (struct.isSetMsg()) { 386 | oprot.writeString(struct.msg); 387 | } 388 | } 389 | 390 | @Override 391 | public void read(org.apache.thrift.protocol.TProtocol prot, UnknownScanner struct) throws org.apache.thrift.TException { 392 | org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot; 393 | java.util.BitSet incoming = iprot.readBitSet(1); 394 | if (incoming.get(0)) { 395 | struct.msg = iprot.readString(); 396 | struct.setMsgIsSet(true); 397 | } 398 | } 399 | } 400 | 401 | private static S scheme(org.apache.thrift.protocol.TProtocol proto) { 402 | return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme(); 403 | } 404 | private static void unusedMethod() {} 405 | } 406 | 407 | -------------------------------------------------------------------------------- /src/main/thrift-gen-java/org/apache/accumulo/proxy/thrift/AccumuloException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | /** 20 | * Autogenerated by Thrift Compiler (0.17.0) 21 | * 22 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 23 | * @generated 24 | */ 25 | package org.apache.accumulo.proxy.thrift; 26 | 27 | @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"}) 28 | public class AccumuloException extends org.apache.thrift.TException implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { 29 | private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("AccumuloException"); 30 | 31 | private static final org.apache.thrift.protocol.TField MSG_FIELD_DESC = new org.apache.thrift.protocol.TField("msg", org.apache.thrift.protocol.TType.STRING, (short)1); 32 | 33 | private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new AccumuloExceptionStandardSchemeFactory(); 34 | private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new AccumuloExceptionTupleSchemeFactory(); 35 | 36 | public @org.apache.thrift.annotation.Nullable java.lang.String msg; // required 37 | 38 | /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ 39 | public enum _Fields implements org.apache.thrift.TFieldIdEnum { 40 | MSG((short)1, "msg"); 41 | 42 | private static final java.util.Map byName = new java.util.HashMap(); 43 | 44 | static { 45 | for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) { 46 | byName.put(field.getFieldName(), field); 47 | } 48 | } 49 | 50 | /** 51 | * Find the _Fields constant that matches fieldId, or null if its not found. 52 | */ 53 | @org.apache.thrift.annotation.Nullable 54 | public static _Fields findByThriftId(int fieldId) { 55 | switch(fieldId) { 56 | case 1: // MSG 57 | return MSG; 58 | default: 59 | return null; 60 | } 61 | } 62 | 63 | /** 64 | * Find the _Fields constant that matches fieldId, throwing an exception 65 | * if it is not found. 66 | */ 67 | public static _Fields findByThriftIdOrThrow(int fieldId) { 68 | _Fields fields = findByThriftId(fieldId); 69 | if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!"); 70 | return fields; 71 | } 72 | 73 | /** 74 | * Find the _Fields constant that matches name, or null if its not found. 75 | */ 76 | @org.apache.thrift.annotation.Nullable 77 | public static _Fields findByName(java.lang.String name) { 78 | return byName.get(name); 79 | } 80 | 81 | private final short _thriftId; 82 | private final java.lang.String _fieldName; 83 | 84 | _Fields(short thriftId, java.lang.String fieldName) { 85 | _thriftId = thriftId; 86 | _fieldName = fieldName; 87 | } 88 | 89 | @Override 90 | public short getThriftFieldId() { 91 | return _thriftId; 92 | } 93 | 94 | @Override 95 | public java.lang.String getFieldName() { 96 | return _fieldName; 97 | } 98 | } 99 | 100 | // isset id assignments 101 | public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; 102 | static { 103 | java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); 104 | tmpMap.put(_Fields.MSG, new org.apache.thrift.meta_data.FieldMetaData("msg", org.apache.thrift.TFieldRequirementType.DEFAULT, 105 | new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); 106 | metaDataMap = java.util.Collections.unmodifiableMap(tmpMap); 107 | org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(AccumuloException.class, metaDataMap); 108 | } 109 | 110 | public AccumuloException() { 111 | } 112 | 113 | public AccumuloException( 114 | java.lang.String msg) 115 | { 116 | this(); 117 | this.msg = msg; 118 | } 119 | 120 | /** 121 | * Performs a deep copy on other. 122 | */ 123 | public AccumuloException(AccumuloException other) { 124 | if (other.isSetMsg()) { 125 | this.msg = other.msg; 126 | } 127 | } 128 | 129 | @Override 130 | public AccumuloException deepCopy() { 131 | return new AccumuloException(this); 132 | } 133 | 134 | @Override 135 | public void clear() { 136 | this.msg = null; 137 | } 138 | 139 | @org.apache.thrift.annotation.Nullable 140 | public java.lang.String getMsg() { 141 | return this.msg; 142 | } 143 | 144 | public AccumuloException setMsg(@org.apache.thrift.annotation.Nullable java.lang.String msg) { 145 | this.msg = msg; 146 | return this; 147 | } 148 | 149 | public void unsetMsg() { 150 | this.msg = null; 151 | } 152 | 153 | /** Returns true if field msg is set (has been assigned a value) and false otherwise */ 154 | public boolean isSetMsg() { 155 | return this.msg != null; 156 | } 157 | 158 | public void setMsgIsSet(boolean value) { 159 | if (!value) { 160 | this.msg = null; 161 | } 162 | } 163 | 164 | @Override 165 | public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) { 166 | switch (field) { 167 | case MSG: 168 | if (value == null) { 169 | unsetMsg(); 170 | } else { 171 | setMsg((java.lang.String)value); 172 | } 173 | break; 174 | 175 | } 176 | } 177 | 178 | @org.apache.thrift.annotation.Nullable 179 | @Override 180 | public java.lang.Object getFieldValue(_Fields field) { 181 | switch (field) { 182 | case MSG: 183 | return getMsg(); 184 | 185 | } 186 | throw new java.lang.IllegalStateException(); 187 | } 188 | 189 | /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ 190 | @Override 191 | public boolean isSet(_Fields field) { 192 | if (field == null) { 193 | throw new java.lang.IllegalArgumentException(); 194 | } 195 | 196 | switch (field) { 197 | case MSG: 198 | return isSetMsg(); 199 | } 200 | throw new java.lang.IllegalStateException(); 201 | } 202 | 203 | @Override 204 | public boolean equals(java.lang.Object that) { 205 | if (that instanceof AccumuloException) 206 | return this.equals((AccumuloException)that); 207 | return false; 208 | } 209 | 210 | public boolean equals(AccumuloException that) { 211 | if (that == null) 212 | return false; 213 | if (this == that) 214 | return true; 215 | 216 | boolean this_present_msg = true && this.isSetMsg(); 217 | boolean that_present_msg = true && that.isSetMsg(); 218 | if (this_present_msg || that_present_msg) { 219 | if (!(this_present_msg && that_present_msg)) 220 | return false; 221 | if (!this.msg.equals(that.msg)) 222 | return false; 223 | } 224 | 225 | return true; 226 | } 227 | 228 | @Override 229 | public int hashCode() { 230 | int hashCode = 1; 231 | 232 | hashCode = hashCode * 8191 + ((isSetMsg()) ? 131071 : 524287); 233 | if (isSetMsg()) 234 | hashCode = hashCode * 8191 + msg.hashCode(); 235 | 236 | return hashCode; 237 | } 238 | 239 | @Override 240 | public int compareTo(AccumuloException other) { 241 | if (!getClass().equals(other.getClass())) { 242 | return getClass().getName().compareTo(other.getClass().getName()); 243 | } 244 | 245 | int lastComparison = 0; 246 | 247 | lastComparison = java.lang.Boolean.compare(isSetMsg(), other.isSetMsg()); 248 | if (lastComparison != 0) { 249 | return lastComparison; 250 | } 251 | if (isSetMsg()) { 252 | lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.msg, other.msg); 253 | if (lastComparison != 0) { 254 | return lastComparison; 255 | } 256 | } 257 | return 0; 258 | } 259 | 260 | @org.apache.thrift.annotation.Nullable 261 | @Override 262 | public _Fields fieldForId(int fieldId) { 263 | return _Fields.findByThriftId(fieldId); 264 | } 265 | 266 | @Override 267 | public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { 268 | scheme(iprot).read(iprot, this); 269 | } 270 | 271 | @Override 272 | public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { 273 | scheme(oprot).write(oprot, this); 274 | } 275 | 276 | @Override 277 | public java.lang.String toString() { 278 | java.lang.StringBuilder sb = new java.lang.StringBuilder("AccumuloException("); 279 | boolean first = true; 280 | 281 | sb.append("msg:"); 282 | if (this.msg == null) { 283 | sb.append("null"); 284 | } else { 285 | sb.append(this.msg); 286 | } 287 | first = false; 288 | sb.append(")"); 289 | return sb.toString(); 290 | } 291 | 292 | public void validate() throws org.apache.thrift.TException { 293 | // check for required fields 294 | // check for sub-struct validity 295 | } 296 | 297 | private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { 298 | try { 299 | write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); 300 | } catch (org.apache.thrift.TException te) { 301 | throw new java.io.IOException(te); 302 | } 303 | } 304 | 305 | private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException { 306 | try { 307 | read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); 308 | } catch (org.apache.thrift.TException te) { 309 | throw new java.io.IOException(te); 310 | } 311 | } 312 | 313 | private static class AccumuloExceptionStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory { 314 | @Override 315 | public AccumuloExceptionStandardScheme getScheme() { 316 | return new AccumuloExceptionStandardScheme(); 317 | } 318 | } 319 | 320 | private static class AccumuloExceptionStandardScheme extends org.apache.thrift.scheme.StandardScheme { 321 | 322 | @Override 323 | public void read(org.apache.thrift.protocol.TProtocol iprot, AccumuloException struct) throws org.apache.thrift.TException { 324 | org.apache.thrift.protocol.TField schemeField; 325 | iprot.readStructBegin(); 326 | while (true) 327 | { 328 | schemeField = iprot.readFieldBegin(); 329 | if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 330 | break; 331 | } 332 | switch (schemeField.id) { 333 | case 1: // MSG 334 | if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { 335 | struct.msg = iprot.readString(); 336 | struct.setMsgIsSet(true); 337 | } else { 338 | org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); 339 | } 340 | break; 341 | default: 342 | org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); 343 | } 344 | iprot.readFieldEnd(); 345 | } 346 | iprot.readStructEnd(); 347 | 348 | // check for required fields of primitive type, which can't be checked in the validate method 349 | struct.validate(); 350 | } 351 | 352 | @Override 353 | public void write(org.apache.thrift.protocol.TProtocol oprot, AccumuloException struct) throws org.apache.thrift.TException { 354 | struct.validate(); 355 | 356 | oprot.writeStructBegin(STRUCT_DESC); 357 | if (struct.msg != null) { 358 | oprot.writeFieldBegin(MSG_FIELD_DESC); 359 | oprot.writeString(struct.msg); 360 | oprot.writeFieldEnd(); 361 | } 362 | oprot.writeFieldStop(); 363 | oprot.writeStructEnd(); 364 | } 365 | 366 | } 367 | 368 | private static class AccumuloExceptionTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory { 369 | @Override 370 | public AccumuloExceptionTupleScheme getScheme() { 371 | return new AccumuloExceptionTupleScheme(); 372 | } 373 | } 374 | 375 | private static class AccumuloExceptionTupleScheme extends org.apache.thrift.scheme.TupleScheme { 376 | 377 | @Override 378 | public void write(org.apache.thrift.protocol.TProtocol prot, AccumuloException struct) throws org.apache.thrift.TException { 379 | org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot; 380 | java.util.BitSet optionals = new java.util.BitSet(); 381 | if (struct.isSetMsg()) { 382 | optionals.set(0); 383 | } 384 | oprot.writeBitSet(optionals, 1); 385 | if (struct.isSetMsg()) { 386 | oprot.writeString(struct.msg); 387 | } 388 | } 389 | 390 | @Override 391 | public void read(org.apache.thrift.protocol.TProtocol prot, AccumuloException struct) throws org.apache.thrift.TException { 392 | org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot; 393 | java.util.BitSet incoming = iprot.readBitSet(1); 394 | if (incoming.get(0)) { 395 | struct.msg = iprot.readString(); 396 | struct.setMsgIsSet(true); 397 | } 398 | } 399 | } 400 | 401 | private static S scheme(org.apache.thrift.protocol.TProtocol proto) { 402 | return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme(); 403 | } 404 | private static void unusedMethod() {} 405 | } 406 | 407 | -------------------------------------------------------------------------------- /src/main/thrift-gen-java/org/apache/accumulo/proxy/thrift/TableExistsException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | /** 20 | * Autogenerated by Thrift Compiler (0.17.0) 21 | * 22 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 23 | * @generated 24 | */ 25 | package org.apache.accumulo.proxy.thrift; 26 | 27 | @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"}) 28 | public class TableExistsException extends org.apache.thrift.TException implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { 29 | private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TableExistsException"); 30 | 31 | private static final org.apache.thrift.protocol.TField MSG_FIELD_DESC = new org.apache.thrift.protocol.TField("msg", org.apache.thrift.protocol.TType.STRING, (short)1); 32 | 33 | private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new TableExistsExceptionStandardSchemeFactory(); 34 | private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new TableExistsExceptionTupleSchemeFactory(); 35 | 36 | public @org.apache.thrift.annotation.Nullable java.lang.String msg; // required 37 | 38 | /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ 39 | public enum _Fields implements org.apache.thrift.TFieldIdEnum { 40 | MSG((short)1, "msg"); 41 | 42 | private static final java.util.Map byName = new java.util.HashMap(); 43 | 44 | static { 45 | for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) { 46 | byName.put(field.getFieldName(), field); 47 | } 48 | } 49 | 50 | /** 51 | * Find the _Fields constant that matches fieldId, or null if its not found. 52 | */ 53 | @org.apache.thrift.annotation.Nullable 54 | public static _Fields findByThriftId(int fieldId) { 55 | switch(fieldId) { 56 | case 1: // MSG 57 | return MSG; 58 | default: 59 | return null; 60 | } 61 | } 62 | 63 | /** 64 | * Find the _Fields constant that matches fieldId, throwing an exception 65 | * if it is not found. 66 | */ 67 | public static _Fields findByThriftIdOrThrow(int fieldId) { 68 | _Fields fields = findByThriftId(fieldId); 69 | if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!"); 70 | return fields; 71 | } 72 | 73 | /** 74 | * Find the _Fields constant that matches name, or null if its not found. 75 | */ 76 | @org.apache.thrift.annotation.Nullable 77 | public static _Fields findByName(java.lang.String name) { 78 | return byName.get(name); 79 | } 80 | 81 | private final short _thriftId; 82 | private final java.lang.String _fieldName; 83 | 84 | _Fields(short thriftId, java.lang.String fieldName) { 85 | _thriftId = thriftId; 86 | _fieldName = fieldName; 87 | } 88 | 89 | @Override 90 | public short getThriftFieldId() { 91 | return _thriftId; 92 | } 93 | 94 | @Override 95 | public java.lang.String getFieldName() { 96 | return _fieldName; 97 | } 98 | } 99 | 100 | // isset id assignments 101 | public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; 102 | static { 103 | java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); 104 | tmpMap.put(_Fields.MSG, new org.apache.thrift.meta_data.FieldMetaData("msg", org.apache.thrift.TFieldRequirementType.DEFAULT, 105 | new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); 106 | metaDataMap = java.util.Collections.unmodifiableMap(tmpMap); 107 | org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TableExistsException.class, metaDataMap); 108 | } 109 | 110 | public TableExistsException() { 111 | } 112 | 113 | public TableExistsException( 114 | java.lang.String msg) 115 | { 116 | this(); 117 | this.msg = msg; 118 | } 119 | 120 | /** 121 | * Performs a deep copy on other. 122 | */ 123 | public TableExistsException(TableExistsException other) { 124 | if (other.isSetMsg()) { 125 | this.msg = other.msg; 126 | } 127 | } 128 | 129 | @Override 130 | public TableExistsException deepCopy() { 131 | return new TableExistsException(this); 132 | } 133 | 134 | @Override 135 | public void clear() { 136 | this.msg = null; 137 | } 138 | 139 | @org.apache.thrift.annotation.Nullable 140 | public java.lang.String getMsg() { 141 | return this.msg; 142 | } 143 | 144 | public TableExistsException setMsg(@org.apache.thrift.annotation.Nullable java.lang.String msg) { 145 | this.msg = msg; 146 | return this; 147 | } 148 | 149 | public void unsetMsg() { 150 | this.msg = null; 151 | } 152 | 153 | /** Returns true if field msg is set (has been assigned a value) and false otherwise */ 154 | public boolean isSetMsg() { 155 | return this.msg != null; 156 | } 157 | 158 | public void setMsgIsSet(boolean value) { 159 | if (!value) { 160 | this.msg = null; 161 | } 162 | } 163 | 164 | @Override 165 | public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) { 166 | switch (field) { 167 | case MSG: 168 | if (value == null) { 169 | unsetMsg(); 170 | } else { 171 | setMsg((java.lang.String)value); 172 | } 173 | break; 174 | 175 | } 176 | } 177 | 178 | @org.apache.thrift.annotation.Nullable 179 | @Override 180 | public java.lang.Object getFieldValue(_Fields field) { 181 | switch (field) { 182 | case MSG: 183 | return getMsg(); 184 | 185 | } 186 | throw new java.lang.IllegalStateException(); 187 | } 188 | 189 | /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ 190 | @Override 191 | public boolean isSet(_Fields field) { 192 | if (field == null) { 193 | throw new java.lang.IllegalArgumentException(); 194 | } 195 | 196 | switch (field) { 197 | case MSG: 198 | return isSetMsg(); 199 | } 200 | throw new java.lang.IllegalStateException(); 201 | } 202 | 203 | @Override 204 | public boolean equals(java.lang.Object that) { 205 | if (that instanceof TableExistsException) 206 | return this.equals((TableExistsException)that); 207 | return false; 208 | } 209 | 210 | public boolean equals(TableExistsException that) { 211 | if (that == null) 212 | return false; 213 | if (this == that) 214 | return true; 215 | 216 | boolean this_present_msg = true && this.isSetMsg(); 217 | boolean that_present_msg = true && that.isSetMsg(); 218 | if (this_present_msg || that_present_msg) { 219 | if (!(this_present_msg && that_present_msg)) 220 | return false; 221 | if (!this.msg.equals(that.msg)) 222 | return false; 223 | } 224 | 225 | return true; 226 | } 227 | 228 | @Override 229 | public int hashCode() { 230 | int hashCode = 1; 231 | 232 | hashCode = hashCode * 8191 + ((isSetMsg()) ? 131071 : 524287); 233 | if (isSetMsg()) 234 | hashCode = hashCode * 8191 + msg.hashCode(); 235 | 236 | return hashCode; 237 | } 238 | 239 | @Override 240 | public int compareTo(TableExistsException other) { 241 | if (!getClass().equals(other.getClass())) { 242 | return getClass().getName().compareTo(other.getClass().getName()); 243 | } 244 | 245 | int lastComparison = 0; 246 | 247 | lastComparison = java.lang.Boolean.compare(isSetMsg(), other.isSetMsg()); 248 | if (lastComparison != 0) { 249 | return lastComparison; 250 | } 251 | if (isSetMsg()) { 252 | lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.msg, other.msg); 253 | if (lastComparison != 0) { 254 | return lastComparison; 255 | } 256 | } 257 | return 0; 258 | } 259 | 260 | @org.apache.thrift.annotation.Nullable 261 | @Override 262 | public _Fields fieldForId(int fieldId) { 263 | return _Fields.findByThriftId(fieldId); 264 | } 265 | 266 | @Override 267 | public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { 268 | scheme(iprot).read(iprot, this); 269 | } 270 | 271 | @Override 272 | public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { 273 | scheme(oprot).write(oprot, this); 274 | } 275 | 276 | @Override 277 | public java.lang.String toString() { 278 | java.lang.StringBuilder sb = new java.lang.StringBuilder("TableExistsException("); 279 | boolean first = true; 280 | 281 | sb.append("msg:"); 282 | if (this.msg == null) { 283 | sb.append("null"); 284 | } else { 285 | sb.append(this.msg); 286 | } 287 | first = false; 288 | sb.append(")"); 289 | return sb.toString(); 290 | } 291 | 292 | public void validate() throws org.apache.thrift.TException { 293 | // check for required fields 294 | // check for sub-struct validity 295 | } 296 | 297 | private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { 298 | try { 299 | write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); 300 | } catch (org.apache.thrift.TException te) { 301 | throw new java.io.IOException(te); 302 | } 303 | } 304 | 305 | private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException { 306 | try { 307 | read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); 308 | } catch (org.apache.thrift.TException te) { 309 | throw new java.io.IOException(te); 310 | } 311 | } 312 | 313 | private static class TableExistsExceptionStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory { 314 | @Override 315 | public TableExistsExceptionStandardScheme getScheme() { 316 | return new TableExistsExceptionStandardScheme(); 317 | } 318 | } 319 | 320 | private static class TableExistsExceptionStandardScheme extends org.apache.thrift.scheme.StandardScheme { 321 | 322 | @Override 323 | public void read(org.apache.thrift.protocol.TProtocol iprot, TableExistsException struct) throws org.apache.thrift.TException { 324 | org.apache.thrift.protocol.TField schemeField; 325 | iprot.readStructBegin(); 326 | while (true) 327 | { 328 | schemeField = iprot.readFieldBegin(); 329 | if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 330 | break; 331 | } 332 | switch (schemeField.id) { 333 | case 1: // MSG 334 | if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { 335 | struct.msg = iprot.readString(); 336 | struct.setMsgIsSet(true); 337 | } else { 338 | org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); 339 | } 340 | break; 341 | default: 342 | org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); 343 | } 344 | iprot.readFieldEnd(); 345 | } 346 | iprot.readStructEnd(); 347 | 348 | // check for required fields of primitive type, which can't be checked in the validate method 349 | struct.validate(); 350 | } 351 | 352 | @Override 353 | public void write(org.apache.thrift.protocol.TProtocol oprot, TableExistsException struct) throws org.apache.thrift.TException { 354 | struct.validate(); 355 | 356 | oprot.writeStructBegin(STRUCT_DESC); 357 | if (struct.msg != null) { 358 | oprot.writeFieldBegin(MSG_FIELD_DESC); 359 | oprot.writeString(struct.msg); 360 | oprot.writeFieldEnd(); 361 | } 362 | oprot.writeFieldStop(); 363 | oprot.writeStructEnd(); 364 | } 365 | 366 | } 367 | 368 | private static class TableExistsExceptionTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory { 369 | @Override 370 | public TableExistsExceptionTupleScheme getScheme() { 371 | return new TableExistsExceptionTupleScheme(); 372 | } 373 | } 374 | 375 | private static class TableExistsExceptionTupleScheme extends org.apache.thrift.scheme.TupleScheme { 376 | 377 | @Override 378 | public void write(org.apache.thrift.protocol.TProtocol prot, TableExistsException struct) throws org.apache.thrift.TException { 379 | org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot; 380 | java.util.BitSet optionals = new java.util.BitSet(); 381 | if (struct.isSetMsg()) { 382 | optionals.set(0); 383 | } 384 | oprot.writeBitSet(optionals, 1); 385 | if (struct.isSetMsg()) { 386 | oprot.writeString(struct.msg); 387 | } 388 | } 389 | 390 | @Override 391 | public void read(org.apache.thrift.protocol.TProtocol prot, TableExistsException struct) throws org.apache.thrift.TException { 392 | org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot; 393 | java.util.BitSet incoming = iprot.readBitSet(1); 394 | if (incoming.get(0)) { 395 | struct.msg = iprot.readString(); 396 | struct.setMsgIsSet(true); 397 | } 398 | } 399 | } 400 | 401 | private static S scheme(org.apache.thrift.protocol.TProtocol proto) { 402 | return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme(); 403 | } 404 | private static void unusedMethod() {} 405 | } 406 | 407 | --------------------------------------------------------------------------------