You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@accumulo.apache.org by ct...@apache.org on 2022/11/09 04:10:19 UTC
[accumulo] branch main updated: Remove Connector and Instance legacy client APIs (#3073)
This is an automated email from the ASF dual-hosted git repository.
ctubbsii pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/accumulo.git
The following commit(s) were added to refs/heads/main by this push:
new 7448970bc2 Remove Connector and Instance legacy client APIs (#3073)
7448970bc2 is described below
commit 7448970bc277bf1365bc0304b7d8f74412547617
Author: Christopher Tubbs <ct...@apache.org>
AuthorDate: Tue Nov 8 23:10:13 2022 -0500
Remove Connector and Instance legacy client APIs (#3073)
* Remove Connector and Instance legacy client APIs
* Improve javadoc wording comparing AccumuloClient with Connector
---
.../accumulo/core/client/AccumuloClient.java | 10 +-
.../apache/accumulo/core/client/BatchWriter.java | 2 +-
.../org/apache/accumulo/core/client/Connector.java | 309 --------------------
.../org/apache/accumulo/core/client/Instance.java | 153 ----------
.../core/client/MutationsRejectedException.java | 29 --
.../core/client/TableOfflineException.java | 8 -
.../accumulo/core/client/ZooKeeperInstance.java | 204 -------------
.../accumulo/core/clientImpl/ClientContext.java | 50 ++--
.../accumulo/core/clientImpl/ConnectorImpl.java | 211 --------------
.../core/fate/zookeeper/ZooCacheFactory.java | 10 +-
.../accumulo/core/singletons/SingletonManager.java | 27 +-
.../org/apache/accumulo/core/util/CleanUp.java | 87 ------
.../core/client/ZooKeeperInstanceTest.java | 197 -------------
.../core/singletons/SingletonManagerTest.java | 43 +--
.../accumulo/minicluster/MiniAccumuloCluster.java | 16 --
.../accumulo/minicluster/MiniAccumuloInstance.java | 53 ----
.../MiniAccumuloClusterClasspathTest.java | 55 ++--
.../MiniAccumuloClusterExistingZooKeepersTest.java | 31 +-
.../MiniAccumuloClusterStartStopTest.java | 9 +-
.../minicluster/MiniAccumuloClusterTest.java | 127 +++++----
.../server/security/SystemCredentialsTest.java | 16 --
.../main/java/org/apache/accumulo/shell/Shell.java | 4 +-
.../accumulo/shell/commands/ScriptCommand.java | 317 ---------------------
.../accumulo/test/functional/AccumuloClientIT.java | 36 ---
.../apache/accumulo/test/functional/CleanUpIT.java | 170 -----------
25 files changed, 162 insertions(+), 2012 deletions(-)
diff --git a/core/src/main/java/org/apache/accumulo/core/client/AccumuloClient.java b/core/src/main/java/org/apache/accumulo/core/client/AccumuloClient.java
index 70537040dc..5c96ebfe9c 100644
--- a/core/src/main/java/org/apache/accumulo/core/client/AccumuloClient.java
+++ b/core/src/main/java/org/apache/accumulo/core/client/AccumuloClient.java
@@ -51,11 +51,11 @@ import org.apache.accumulo.core.security.Authorizations;
* </pre>
*
* <p>
- * If migrating code from Connector to AccumuloClient an important difference to consider is that
- * AccumuloClient is closable and Connector is not. Connector uses static resources and therefore
- * creating them is cheap. AccumuloClient attempts to clean up resources on close, so constantly
- * creating them could perform worse than Connector. Therefore, it would be better to create an
- * AccumuloClient and pass it around.
+ * An important difference with the legacy Connector to consider is that Connector reused global
+ * static resources. AccumuloClient, however, attempts to clean up its resources on close. So,
+ * creating many AccumuloClient objects will perform worse than creating many Connectors did.
+ * Therefore, it is suggested to reuse AccumuloClient instances where possible, rather than create
+ * many of them.
*
* <p>
* AccumuloClient objects are intended to be thread-safe, and can be used by multiple threads.
diff --git a/core/src/main/java/org/apache/accumulo/core/client/BatchWriter.java b/core/src/main/java/org/apache/accumulo/core/client/BatchWriter.java
index e077a8d803..e1d81bf02a 100644
--- a/core/src/main/java/org/apache/accumulo/core/client/BatchWriter.java
+++ b/core/src/main/java/org/apache/accumulo/core/client/BatchWriter.java
@@ -23,7 +23,7 @@ import org.apache.accumulo.core.data.Mutation;
/**
* Send Mutations to a single Table in Accumulo.
* <p>
- * When the user uses a Connector to create a BatchWriter, they specify how much memory and how many
+ * When the user uses a client to create a BatchWriter, they specify how much memory and how many
* threads it should use. As the user adds mutations to the batch writer, it buffers them. Once the
* buffered mutations have used half of the user specified buffer, the mutations are dumped into the
* background to be written by a thread pool. If the user specified memory completely fills up, then
diff --git a/core/src/main/java/org/apache/accumulo/core/client/Connector.java b/core/src/main/java/org/apache/accumulo/core/client/Connector.java
deleted file mode 100644
index 7a639cec5c..0000000000
--- a/core/src/main/java/org/apache/accumulo/core/client/Connector.java
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.accumulo.core.client;
-
-import org.apache.accumulo.core.client.admin.InstanceOperations;
-import org.apache.accumulo.core.client.admin.NamespaceOperations;
-import org.apache.accumulo.core.client.admin.ReplicationOperations;
-import org.apache.accumulo.core.client.admin.SecurityOperations;
-import org.apache.accumulo.core.client.admin.TableOperations;
-import org.apache.accumulo.core.clientImpl.ClientContext;
-import org.apache.accumulo.core.clientImpl.ConnectorImpl;
-import org.apache.accumulo.core.security.Authorizations;
-
-/**
- * Connector connects to an Accumulo instance and allows the user to request readers and writers for
- * the instance as well as various objects that permit administrative operations.
- *
- * The Connector enforces security on the client side by forcing all API calls to be accompanied by
- * user credentials.
- *
- * @deprecated since 2.0.0. Use {@link AccumuloClient} for writing new code. Connector is available
- * for existing code. Use {@link #from(AccumuloClient)} as a bridge between the two.
- */
-@Deprecated(since = "2.0.0")
-public abstract class Connector {
-
- /**
- * Factory method to create a BatchScanner connected to Accumulo.
- *
- * @param tableName
- * the name of the table to query
- * @param authorizations
- * A set of authorization labels that will be checked against the column visibility of
- * each key in order to filter data. The authorizations passed in must be a subset of the
- * accumulo user's set of authorizations. If the accumulo user has authorizations (A1,
- * A2) and authorizations (A2, A3) are passed, then an exception will be thrown.
- * @param numQueryThreads
- * the number of concurrent threads to spawn for querying
- *
- * @return BatchScanner object for configuring and querying
- * @throws TableNotFoundException
- * when the specified table doesn't exist
- */
- public abstract BatchScanner createBatchScanner(String tableName, Authorizations authorizations,
- int numQueryThreads) throws TableNotFoundException;
-
- /**
- * Factory method to create a BatchDeleter connected to Accumulo.
- *
- * @param tableName
- * the name of the table to query and delete from
- * @param authorizations
- * A set of authorization labels that will be checked against the column visibility of
- * each key in order to filter data. The authorizations passed in must be a subset of the
- * accumulo user's set of authorizations. If the accumulo user has authorizations (A1,
- * A2) and authorizations (A2, A3) are passed, then an exception will be thrown.
- * @param numQueryThreads
- * the number of concurrent threads to spawn for querying
- * @param maxMemory
- * size in bytes of the maximum memory to batch before writing
- * @param maxLatency
- * size in milliseconds; set to 0 or Long.MAX_VALUE to allow the maximum time to hold a
- * batch before writing
- * @param maxWriteThreads
- * the maximum number of threads to use for writing data to the tablet servers
- *
- * @return BatchDeleter object for configuring and deleting
- * @throws TableNotFoundException
- * when the specified table doesn't exist
- * @deprecated since 1.5.0; Use
- * {@link #createBatchDeleter(String, Authorizations, int, BatchWriterConfig)}
- * instead.
- */
- @Deprecated(since = "1.5.0")
- public abstract BatchDeleter createBatchDeleter(String tableName, Authorizations authorizations,
- int numQueryThreads, long maxMemory, long maxLatency, int maxWriteThreads)
- throws TableNotFoundException;
-
- /**
- * Factory method to create BatchDeleter
- *
- * @param tableName
- * the name of the table to query and delete from
- * @param authorizations
- * A set of authorization labels that will be checked against the column visibility of
- * each key in order to filter data. The authorizations passed in must be a subset of the
- * accumulo user's set of authorizations. If the accumulo user has authorizations (A1,
- * A2) and authorizations (A2, A3) are passed, then an exception will be thrown.
- * @param numQueryThreads
- * the number of concurrent threads to spawn for querying
- * @param config
- * configuration used to create batch writer. This config takes precedence. Any unset
- * values will be merged with config set when the Connector was created. If no config was
- * set during Connector creation, BatchWriterConfig defaults will be used.
- * @return BatchDeleter object for configuring and deleting
- * @since 1.5.0
- */
- public abstract BatchDeleter createBatchDeleter(String tableName, Authorizations authorizations,
- int numQueryThreads, BatchWriterConfig config) throws TableNotFoundException;
-
- /**
- * Factory method to create a BatchWriter connected to Accumulo.
- *
- * @param tableName
- * the name of the table to insert data into
- * @param maxMemory
- * size in bytes of the maximum memory to batch before writing
- * @param maxLatency
- * time in milliseconds; set to 0 or Long.MAX_VALUE to allow the maximum time to hold a
- * batch before writing
- * @param maxWriteThreads
- * the maximum number of threads to use for writing data to the tablet servers
- *
- * @return BatchWriter object for configuring and writing data to
- * @throws TableNotFoundException
- * when the specified table doesn't exist
- * @deprecated since 1.5.0; Use {@link #createBatchWriter(String, BatchWriterConfig)} instead.
- */
- @Deprecated(since = "1.5.0")
- public abstract BatchWriter createBatchWriter(String tableName, long maxMemory, long maxLatency,
- int maxWriteThreads) throws TableNotFoundException;
-
- /**
- * Factory method to create a BatchWriter connected to Accumulo.
- *
- * @param tableName
- * the name of the table to insert data into
- * @param config
- * configuration used to create batch writer. This config will take precedence. Any unset
- * values will merged with config set when the Connector was created. If no config was
- * set during Connector creation, BatchWriterConfig defaults will be used.
- * @return BatchWriter object for configuring and writing data to
- * @since 1.5.0
- */
- public abstract BatchWriter createBatchWriter(String tableName, BatchWriterConfig config)
- throws TableNotFoundException;
-
- /**
- * Factory method to create a Multi-Table BatchWriter connected to Accumulo. Multi-table batch
- * writers can queue data for multiple tables, which is good for ingesting data into multiple
- * tables from the same source
- *
- * @param maxMemory
- * size in bytes of the maximum memory to batch before writing
- * @param maxLatency
- * size in milliseconds; set to 0 or Long.MAX_VALUE to allow the maximum time to hold a
- * batch before writing
- * @param maxWriteThreads
- * the maximum number of threads to use for writing data to the tablet servers
- *
- * @return MultiTableBatchWriter object for configuring and writing data to
- * @deprecated since 1.5.0; Use {@link #createMultiTableBatchWriter(BatchWriterConfig)} instead.
- */
- @Deprecated(since = "1.5.0")
- public abstract MultiTableBatchWriter createMultiTableBatchWriter(long maxMemory, long maxLatency,
- int maxWriteThreads);
-
- /**
- * Factory method to create a Multi-Table BatchWriter connected to Accumulo. Multi-table batch
- * writers can queue data for multiple tables. Also data for multiple tables can be sent to a
- * server in a single batch. Its an efficient way to ingest data into multiple tables from a
- * single process.
- *
- * @param config
- * configuration used to create multi-table batch writer. This config will take
- * precedence. Any unset values will merged with config set when the Connector was
- * created. If no config was set during Connector creation, BatchWriterConfig defaults
- * will be used.
- * @return MultiTableBatchWriter object for configuring and writing data to
- * @since 1.5.0
- */
- public abstract MultiTableBatchWriter createMultiTableBatchWriter(BatchWriterConfig config);
-
- /**
- * Factory method to create a Scanner connected to Accumulo.
- *
- * @param tableName
- * the name of the table to query data from
- * @param authorizations
- * A set of authorization labels that will be checked against the column visibility of
- * each key in order to filter data. The authorizations passed in must be a subset of the
- * accumulo user's set of authorizations. If the accumulo user has authorizations (A1,
- * A2) and authorizations (A2, A3) are passed, then an exception will be thrown.
- *
- * @return Scanner object for configuring and querying data with
- * @throws TableNotFoundException
- * when the specified table doesn't exist
- */
- public abstract Scanner createScanner(String tableName, Authorizations authorizations)
- throws TableNotFoundException;
-
- /**
- * Factory method to create a ConditionalWriter connected to Accumulo.
- *
- * @param tableName
- * the name of the table to query data from
- * @param config
- * configuration used to create conditional writer
- *
- * @return ConditionalWriter object for writing ConditionalMutations
- * @throws TableNotFoundException
- * when the specified table doesn't exist
- * @since 1.6.0
- */
- public abstract ConditionalWriter createConditionalWriter(String tableName,
- ConditionalWriterConfig config) throws TableNotFoundException;
-
- /**
- * Accessor method for internal instance object.
- *
- * @return the internal instance object
- */
- public abstract Instance getInstance();
-
- /**
- * Get the current user for this connector
- *
- * @return the user name
- */
- public abstract String whoami();
-
- /**
- * Retrieves a TableOperations object to perform table functions, such as create and delete.
- *
- * @return an object to manipulate tables
- */
- public abstract TableOperations tableOperations();
-
- /**
- * Retrieves a NamespaceOperations object to perform namespace functions, such as create and
- * delete.
- *
- * @return an object to manipulate namespaces
- */
- public abstract NamespaceOperations namespaceOperations();
-
- /**
- * Retrieves a SecurityOperations object to perform user security operations, such as creating
- * users.
- *
- * @return an object to modify users and permissions
- */
- public abstract SecurityOperations securityOperations();
-
- /**
- * Retrieves an InstanceOperations object to modify instance configuration.
- *
- * @return an object to modify instance configuration
- */
- public abstract InstanceOperations instanceOperations();
-
- /**
- * Retrieves a ReplicationOperations object to manage replication configuration.
- *
- * @return an object to modify replication configuration
- * @since 1.7.0
- */
- public abstract ReplicationOperations replicationOperations();
-
- /**
- * Creates a Connector from an AccumuloClient. This Connector will no longer work after the
- * AccumuloClient is closed. Also anything derived from the Connector (like a Scanner for example)
- * is unlikely to work after the AccumuloClient is closed.
- *
- * @since 2.0
- */
- public static Connector from(AccumuloClient client)
- throws AccumuloSecurityException, AccumuloException {
- return new ConnectorImpl((ClientContext) client);
- }
-
- /**
- * Creates a new Accumulo Client from a Connector. The returned client should be closed and
- * closing it will not affect the Connector from which it was derived. This method is useful for
- * cases where code written using Connector must call code written using AccumuloClient. Below is
- * an example.
- *
- * <pre>
- * <code>
- * Connector conn = getMyConnector();
- * try(AccumuloClient client = Connector.newClient(conn) {
- * doSomething(client);
- * }
- * </code>
- * </pre>
- *
- * @since 2.1.0
- */
- public static AccumuloClient newClient(Connector conn) {
- return Accumulo.newClient().from(((ConnectorImpl) conn).getAccumuloClient().getProperties())
- .build();
- }
-}
diff --git a/core/src/main/java/org/apache/accumulo/core/client/Instance.java b/core/src/main/java/org/apache/accumulo/core/client/Instance.java
deleted file mode 100644
index 45e664e8d4..0000000000
--- a/core/src/main/java/org/apache/accumulo/core/client/Instance.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.accumulo.core.client;
-
-import java.nio.ByteBuffer;
-import java.util.List;
-
-import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
-import org.apache.accumulo.core.client.security.tokens.PasswordToken;
-
-/**
- * This class represents the information a client needs to know to connect to an instance of
- * accumulo.
- *
- * @deprecated since 2.0.0, use {@link Accumulo#newClient()} and {@link java.util.Properties}
- * instead
- */
-@Deprecated(since = "2.0.0")
-public interface Instance {
- /**
- * Returns the location of the tablet server that is serving the root tablet.
- *
- * @return location in "hostname:port" form
- */
- String getRootTabletLocation();
-
- /**
- * Returns the location(s) of the accumulo manager and any redundant servers.
- *
- * @return a list of locations in "hostname:port" form
- */
- List<String> getMasterLocations();
-
- /**
- * Returns a unique string that identifies this instance of accumulo.
- *
- * @return a UUID
- */
- String getInstanceID();
-
- /**
- * Returns the instance name given at system initialization time.
- *
- * @return current instance name
- */
- String getInstanceName();
-
- /**
- * Returns a comma-separated list of zookeeper servers the instance is using.
- *
- * @return the zookeeper servers this instance is using in "hostname:port" form
- */
- String getZooKeepers();
-
- /**
- * Returns the zookeeper connection timeout.
- *
- * @return the configured timeout to connect to zookeeper
- */
- int getZooKeepersSessionTimeOut();
-
- /**
- * Returns a connection to accumulo.
- *
- * @param user
- * a valid accumulo user
- * @param pass
- * A UTF-8 encoded password. The password may be cleared after making this call.
- * @return the accumulo Connector
- * @throws AccumuloException
- * when a generic exception occurs
- * @throws AccumuloSecurityException
- * when a user's credentials are invalid
- * @deprecated since 1.5, use {@link #getConnector(String, AuthenticationToken)} with
- * {@link PasswordToken}
- */
- @Deprecated(since = "1.5.0")
- default Connector getConnector(String user, byte[] pass)
- throws AccumuloException, AccumuloSecurityException {
- return getConnector(user, new PasswordToken(pass));
- }
-
- /**
- * Returns a connection to accumulo.
- *
- * @param user
- * a valid accumulo user
- * @param pass
- * A UTF-8 encoded password. The password may be cleared after making this call.
- * @return the accumulo Connector
- * @throws AccumuloException
- * when a generic exception occurs
- * @throws AccumuloSecurityException
- * when a user's credentials are invalid
- * @deprecated since 1.5, use {@link #getConnector(String, AuthenticationToken)} with
- * {@link PasswordToken}
- */
- @Deprecated(since = "1.5.0")
- default Connector getConnector(String user, ByteBuffer pass)
- throws AccumuloException, AccumuloSecurityException {
- return getConnector(user, new PasswordToken(pass));
- }
-
- /**
- * Returns a connection to this instance of accumulo.
- *
- * @param user
- * a valid accumulo user
- * @param pass
- * If a mutable CharSequence is passed in, it may be cleared after this call.
- * @return the accumulo Connector
- * @throws AccumuloException
- * when a generic exception occurs
- * @throws AccumuloSecurityException
- * when a user's credentials are invalid
- * @deprecated since 1.5, use {@link #getConnector(String, AuthenticationToken)} with
- * {@link PasswordToken}
- */
- @Deprecated(since = "1.5.0")
- default Connector getConnector(String user, CharSequence pass)
- throws AccumuloException, AccumuloSecurityException {
- return getConnector(user, new PasswordToken(pass));
- }
-
- /**
- * Returns a connection to this instance of accumulo.
- *
- * @param principal
- * a valid accumulo user
- * @param token
- * Use the token type configured for the Accumulo instance you are connecting to. An
- * Accumulo instance with default configurations will use {@link PasswordToken}
- * @since 1.5.0
- */
- Connector getConnector(String principal, AuthenticationToken token)
- throws AccumuloException, AccumuloSecurityException;
-}
diff --git a/core/src/main/java/org/apache/accumulo/core/client/MutationsRejectedException.java b/core/src/main/java/org/apache/accumulo/core/client/MutationsRejectedException.java
index ffe39b9dc4..47852d3104 100644
--- a/core/src/main/java/org/apache/accumulo/core/client/MutationsRejectedException.java
+++ b/core/src/main/java/org/apache/accumulo/core/client/MutationsRejectedException.java
@@ -43,35 +43,6 @@ public class MutationsRejectedException extends AccumuloException {
private final HashSet<String> es = new HashSet<>();
private final int unknownErrors;
- /**
- *
- * @param cvsList
- * list of constraint violations
- * @param hashMap
- * authorization failures
- * @param serverSideErrors
- * server side errors
- * @param unknownErrors
- * number of unknown errors
- *
- * @since 1.7.0
- * @deprecated since 2.0.0, replaced by
- * {@link #MutationsRejectedException(AccumuloClient, List, Map, Collection, int, Throwable)}
- */
- @Deprecated(since = "2.0.0")
- public MutationsRejectedException(Instance instance, List<ConstraintViolationSummary> cvsList,
- Map<TabletId,Set<SecurityErrorCode>> hashMap, Collection<String> serverSideErrors,
- int unknownErrors, Throwable cause) {
- super(
- "# constraint violations : " + cvsList.size() + " security codes: " + hashMap.toString()
- + " # server errors " + serverSideErrors.size() + " # exceptions " + unknownErrors,
- cause);
- this.cvsl.addAll(cvsList);
- this.af.putAll(hashMap);
- this.es.addAll(serverSideErrors);
- this.unknownErrors = unknownErrors;
- }
-
/**
* Creates Mutations rejected exception
*
diff --git a/core/src/main/java/org/apache/accumulo/core/client/TableOfflineException.java b/core/src/main/java/org/apache/accumulo/core/client/TableOfflineException.java
index 2dbeb1476d..bd0e2661e6 100644
--- a/core/src/main/java/org/apache/accumulo/core/client/TableOfflineException.java
+++ b/core/src/main/java/org/apache/accumulo/core/client/TableOfflineException.java
@@ -24,14 +24,6 @@ public class TableOfflineException extends RuntimeException {
private static final long serialVersionUID = 1L;
- /**
- * @deprecated since 2.0.0, replaced by {@link #TableOfflineException(String)}
- */
- @Deprecated(since = "2.0.0")
- public TableOfflineException(Instance instance, String tableId) {
- super("Table with ID (" + tableId + ") is offline");
- }
-
/**
* @since 2.0.0
*/
diff --git a/core/src/main/java/org/apache/accumulo/core/client/ZooKeeperInstance.java b/core/src/main/java/org/apache/accumulo/core/client/ZooKeeperInstance.java
deleted file mode 100644
index 3954b9f12e..0000000000
--- a/core/src/main/java/org/apache/accumulo/core/client/ZooKeeperInstance.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.accumulo.core.client;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static java.util.concurrent.TimeUnit.SECONDS;
-
-import java.util.List;
-import java.util.Properties;
-
-import org.apache.accumulo.core.Constants;
-import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
-import org.apache.accumulo.core.clientImpl.ClientConfConverter;
-import org.apache.accumulo.core.clientImpl.ClientContext;
-import org.apache.accumulo.core.clientImpl.ClientInfo;
-import org.apache.accumulo.core.clientImpl.ClientInfoImpl;
-import org.apache.accumulo.core.clientImpl.InstanceOperationsImpl;
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.conf.ClientProperty;
-import org.apache.accumulo.core.conf.ConfigurationTypeHelper;
-import org.apache.accumulo.core.data.InstanceId;
-import org.apache.accumulo.core.fate.zookeeper.ZooCache;
-import org.apache.accumulo.core.fate.zookeeper.ZooCacheFactory;
-import org.apache.accumulo.core.metadata.schema.TabletMetadata.Location;
-import org.apache.accumulo.core.metadata.schema.TabletMetadata.LocationType;
-import org.apache.accumulo.core.metadata.schema.TabletsMetadata;
-import org.apache.accumulo.core.singletons.SingletonManager;
-import org.apache.accumulo.core.singletons.SingletonManager.Mode;
-import org.apache.accumulo.core.singletons.SingletonReservation;
-import org.apache.accumulo.core.util.OpTimer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * An implementation of instance that looks in zookeeper to find information needed to connect to an
- * instance of accumulo.
- *
- * <p>
- * The advantage of using zookeeper to obtain information about accumulo is that zookeeper is highly
- * available, very responsive, and supports caching.
- *
- * <p>
- * Because it is possible for multiple instances of accumulo to share a single set of zookeeper
- * servers, all constructors require an accumulo instance name.
- *
- * If you do not know the instance names then run accumulo
- * org.apache.accumulo.server.util.ListInstances on an accumulo server.
- *
- * @deprecated since 2.0.0, Use {@link Accumulo#newClient()} instead
- */
-@Deprecated(since = "2.0.0")
-public class ZooKeeperInstance implements Instance {
-
- private static final Logger log = LoggerFactory.getLogger(ZooKeeperInstance.class);
-
- private String instanceId = null;
- private String instanceName = null;
-
- private final ZooCache zooCache;
-
- private final String zooKeepers;
-
- private final int zooKeepersSessionTimeOut;
-
- private ClientConfiguration clientConf;
-
- /**
- *
- * @param instanceName
- * The name of specific accumulo instance. This is set at initialization time.
- * @param zooKeepers
- * A comma separated list of zoo keeper server locations. Each location can contain an
- * optional port, of the format host:port.
- */
- public ZooKeeperInstance(String instanceName, String zooKeepers) {
- this(ClientConfiguration.loadDefault().withInstance(instanceName).withZkHosts(zooKeepers));
- }
-
- ZooKeeperInstance(ClientConfiguration config, ZooCacheFactory zcf) {
- checkArgument(config != null, "config is null");
- // Enable singletons before before getting a zoocache
- SingletonManager.setMode(Mode.CONNECTOR);
- this.clientConf = config;
- this.instanceId = clientConf.get(ClientConfiguration.ClientProperty.INSTANCE_ID);
- this.instanceName = clientConf.get(ClientConfiguration.ClientProperty.INSTANCE_NAME);
- if ((instanceId == null) == (instanceName == null))
- throw new IllegalArgumentException(
- "Expected exactly one of instanceName and instanceId to be set; "
- + (instanceName == null ? "neither" : "both") + " were set");
- this.zooKeepers = clientConf.get(ClientConfiguration.ClientProperty.INSTANCE_ZK_HOST);
- this.zooKeepersSessionTimeOut = (int) ConfigurationTypeHelper
- .getTimeInMillis(clientConf.get(ClientConfiguration.ClientProperty.INSTANCE_ZK_TIMEOUT));
- zooCache = zcf.getZooCache(zooKeepers, zooKeepersSessionTimeOut);
- if (instanceName != null) {
- // Validates that the provided instanceName actually exists
- getInstanceID();
- }
- }
-
- /**
- * @param config
- * Client configuration for specifying connection options. See
- * {@link ClientConfiguration} which extends Configuration with convenience methods
- * specific to Accumulo.
- * @since 1.9.0
- */
- public ZooKeeperInstance(ClientConfiguration config) {
- this(config, new ZooCacheFactory());
- }
-
- @Override
- public String getInstanceID() {
- if (instanceId == null) {
- instanceId = ClientContext.getInstanceID(zooCache, instanceName).canonical();
- }
- ClientContext.verifyInstanceId(zooCache, instanceId, instanceName);
- return instanceId;
- }
-
- @Override
- public List<String> getMasterLocations() {
- return ClientContext.getManagerLocations(zooCache, getInstanceID());
- }
-
- @Override
- public String getRootTabletLocation() {
- OpTimer timer = null;
-
- if (log.isTraceEnabled()) {
- log.trace("tid={} Looking up root tablet location in zookeeper.",
- Thread.currentThread().getId());
- timer = new OpTimer().start();
- }
-
- Location loc = TabletsMetadata
- .getRootMetadata(Constants.ZROOT + "/" + getInstanceID(), zooCache).getLocation();
-
- if (timer != null) {
- timer.stop();
- log.trace("tid={} Found root tablet at {} in {}", Thread.currentThread().getId(), loc,
- String.format("%.3f secs", timer.scale(SECONDS)));
- }
-
- if (loc == null || loc.getType() != LocationType.CURRENT) {
- return null;
- }
-
- return loc.getHostPort();
- }
-
- @Override
- public String getInstanceName() {
- if (instanceName == null)
- instanceName =
- InstanceOperationsImpl.lookupInstanceName(zooCache, InstanceId.of(getInstanceID()));
-
- return instanceName;
- }
-
- @Override
- public String getZooKeepers() {
- return zooKeepers;
- }
-
- @Override
- public int getZooKeepersSessionTimeOut() {
- return zooKeepersSessionTimeOut;
- }
-
- @Override
- public Connector getConnector(String principal, AuthenticationToken token)
- throws AccumuloException, AccumuloSecurityException {
- Properties properties = ClientConfConverter.toProperties(clientConf);
- properties.setProperty(ClientProperty.AUTH_PRINCIPAL.getKey(), principal);
- properties.setProperty(ClientProperty.INSTANCE_NAME.getKey(), getInstanceName());
- ClientInfo info = new ClientInfoImpl(properties, token);
- AccumuloConfiguration serverConf = ClientConfConverter.toAccumuloConf(properties);
- return new org.apache.accumulo.core.clientImpl.ConnectorImpl(
- new ClientContext(SingletonReservation.noop(), info, serverConf, null));
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder(64);
- sb.append("ZooKeeperInstance: ").append(getInstanceName()).append(" ").append(getZooKeepers());
- return sb.toString();
- }
-}
diff --git a/core/src/main/java/org/apache/accumulo/core/clientImpl/ClientContext.java b/core/src/main/java/org/apache/accumulo/core/clientImpl/ClientContext.java
index 67d24ab448..284ae216f9 100644
--- a/core/src/main/java/org/apache/accumulo/core/clientImpl/ClientContext.java
+++ b/core/src/main/java/org/apache/accumulo/core/clientImpl/ClientContext.java
@@ -21,7 +21,6 @@ package org.apache.accumulo.core.clientImpl;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Suppliers.memoizeWithExpiration;
import static java.nio.charset.StandardCharsets.UTF_8;
-import static java.util.Objects.requireNonNull;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.LOCATION;
@@ -509,13 +508,8 @@ public class ClientContext implements AccumuloClient {
*/
public List<String> getManagerLocations() {
ensureOpen();
- return getManagerLocations(zooCache, getInstanceID().canonical());
- }
-
- // available only for sharing code with old ZooKeeperInstance
- public static List<String> getManagerLocations(ZooCache zooCache, String instanceId) {
var zLockManagerPath =
- ServiceLock.path(Constants.ZROOT + "/" + instanceId + Constants.ZMANAGER_LOCK);
+ ServiceLock.path(Constants.ZROOT + "/" + getInstanceID() + Constants.ZMANAGER_LOCK);
OpTimer timer = null;
@@ -548,37 +542,27 @@ public class ClientContext implements AccumuloClient {
public InstanceId getInstanceID() {
ensureOpen();
if (instanceId == null) {
+ // lookup by name
final String instanceName = info.getInstanceName();
- instanceId = getInstanceID(zooCache, instanceName);
- verifyInstanceId(zooCache, instanceId.canonical(), instanceName);
+ String instanceNamePath = Constants.ZROOT + Constants.ZINSTANCES + "/" + instanceName;
+ byte[] data = zooCache.get(instanceNamePath);
+ if (data == null) {
+ throw new RuntimeException(
+ "Instance name " + instanceName + " does not exist in zookeeper. "
+ + "Run \"accumulo org.apache.accumulo.server.util.ListInstances\" to see a list.");
+ }
+ String instanceIdString = new String(data, UTF_8);
+ // verify that the instanceId found via the instanceName actually exists as an instance
+ if (zooCache.get(Constants.ZROOT + "/" + instanceIdString) == null) {
+ throw new RuntimeException("Instance id " + instanceIdString
+ + (instanceName == null ? "" : " pointed to by the name " + instanceName)
+ + " does not exist in zookeeper");
+ }
+ instanceId = InstanceId.of(instanceIdString);
}
return instanceId;
}
- // available only for sharing code with old ZooKeeperInstance
- public static InstanceId getInstanceID(ZooCache zooCache, String instanceName) {
- requireNonNull(zooCache, "zooCache cannot be null");
- requireNonNull(instanceName, "instanceName cannot be null");
- String instanceNamePath = Constants.ZROOT + Constants.ZINSTANCES + "/" + instanceName;
- byte[] data = zooCache.get(instanceNamePath);
- if (data == null) {
- throw new RuntimeException("Instance name " + instanceName + " does not exist in zookeeper. "
- + "Run \"accumulo org.apache.accumulo.server.util.ListInstances\" to see a list.");
- }
- return InstanceId.of(new String(data, UTF_8));
- }
-
- // available only for sharing code with old ZooKeeperInstance
- public static void verifyInstanceId(ZooCache zooCache, String instanceId, String instanceName) {
- requireNonNull(zooCache, "zooCache cannot be null");
- requireNonNull(instanceId, "instanceId cannot be null");
- if (zooCache.get(Constants.ZROOT + "/" + instanceId) == null) {
- throw new RuntimeException("Instance id " + instanceId
- + (instanceName == null ? "" : " pointed to by the name " + instanceName)
- + " does not exist in zookeeper");
- }
- }
-
public String getZooKeeperRoot() {
ensureOpen();
return ZooUtil.getRoot(getInstanceID());
diff --git a/core/src/main/java/org/apache/accumulo/core/clientImpl/ConnectorImpl.java b/core/src/main/java/org/apache/accumulo/core/clientImpl/ConnectorImpl.java
deleted file mode 100644
index b5341fe8ca..0000000000
--- a/core/src/main/java/org/apache/accumulo/core/clientImpl/ConnectorImpl.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.accumulo.core.clientImpl;
-
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
-
-import java.util.List;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.BatchDeleter;
-import org.apache.accumulo.core.client.BatchScanner;
-import org.apache.accumulo.core.client.BatchWriter;
-import org.apache.accumulo.core.client.BatchWriterConfig;
-import org.apache.accumulo.core.client.ConditionalWriter;
-import org.apache.accumulo.core.client.ConditionalWriterConfig;
-import org.apache.accumulo.core.client.MultiTableBatchWriter;
-import org.apache.accumulo.core.client.Scanner;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.admin.InstanceOperations;
-import org.apache.accumulo.core.client.admin.NamespaceOperations;
-import org.apache.accumulo.core.client.admin.ReplicationOperations;
-import org.apache.accumulo.core.client.admin.SecurityOperations;
-import org.apache.accumulo.core.client.admin.TableOperations;
-import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
-import org.apache.accumulo.core.clientImpl.thrift.SecurityErrorCode;
-import org.apache.accumulo.core.rpc.clients.ThriftClientTypes;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.core.singletons.SingletonManager;
-import org.apache.accumulo.core.singletons.SingletonManager.Mode;
-import org.apache.accumulo.core.trace.TraceUtil;
-
-/**
- * This class now delegates to {@link ClientContext}, except for the methods which were not copied
- * over to that.
- */
-@Deprecated(since = "2.0.0")
-public class ConnectorImpl extends org.apache.accumulo.core.client.Connector {
-
- private static final String SYSTEM_TOKEN_NAME =
- "org.apache.accumulo.server.security.SystemCredentials$SystemToken";
- private final ClientContext context;
-
- public ConnectorImpl(ClientContext context) throws AccumuloSecurityException, AccumuloException {
- this.context = context;
- SingletonManager.setMode(Mode.CONNECTOR);
- if (context.getCredentials().getToken().isDestroyed())
- throw new AccumuloSecurityException(context.getCredentials().getPrincipal(),
- SecurityErrorCode.TOKEN_EXPIRED);
- // Skip fail fast for system services; string literal for class name, to avoid dependency on
- // server jar
- final String tokenClassName = context.getCredentials().getToken().getClass().getName();
- if (!SYSTEM_TOKEN_NAME.equals(tokenClassName)) {
- if (!ThriftClientTypes.CLIENT.execute(context,
- client -> client.authenticate(TraceUtil.traceInfo(), context.rpcCreds()))) {
- throw new AccumuloSecurityException("Authentication failed, access denied",
- SecurityErrorCode.BAD_CREDENTIALS);
- }
- }
- }
-
- public ClientContext getAccumuloClient() {
- return context;
- }
-
- @Override
- public org.apache.accumulo.core.client.Instance getInstance() {
- return new org.apache.accumulo.core.client.Instance() {
- @Override
- public String getRootTabletLocation() {
- return context.getRootTabletLocation();
- }
-
- @Override
- public List<String> getMasterLocations() {
- return context.getManagerLocations();
- }
-
- @Override
- public String getInstanceID() {
- return context.getInstanceID().canonical();
- }
-
- @Override
- public String getInstanceName() {
- return context.getInstanceName();
- }
-
- @Override
- public String getZooKeepers() {
- return context.getZooKeepers();
- }
-
- @Override
- public int getZooKeepersSessionTimeOut() {
- return context.getZooKeepersSessionTimeOut();
- }
-
- @Override
- public org.apache.accumulo.core.client.Connector getConnector(String principal,
- AuthenticationToken token) throws AccumuloException, AccumuloSecurityException {
- return org.apache.accumulo.core.client.Connector.from(context);
- }
- };
- }
-
- @Override
- public BatchScanner createBatchScanner(String tableName, Authorizations authorizations,
- int numQueryThreads) throws TableNotFoundException {
- return context.createBatchScanner(tableName, authorizations, numQueryThreads);
- }
-
- @Override
- public BatchDeleter createBatchDeleter(String tableName, Authorizations authorizations,
- int numQueryThreads, long maxMemory, long maxLatency, int maxWriteThreads)
- throws TableNotFoundException {
- return context.createBatchDeleter(tableName, authorizations, numQueryThreads,
- new BatchWriterConfig().setMaxMemory(maxMemory).setMaxLatency(maxLatency, MILLISECONDS)
- .setMaxWriteThreads(maxWriteThreads));
- }
-
- @Override
- public BatchDeleter createBatchDeleter(String tableName, Authorizations authorizations,
- int numQueryThreads, BatchWriterConfig config) throws TableNotFoundException {
- return context.createBatchDeleter(tableName, authorizations, numQueryThreads, config);
- }
-
- @Override
- public BatchWriter createBatchWriter(String tableName, long maxMemory, long maxLatency,
- int maxWriteThreads) throws TableNotFoundException {
- return context.createBatchWriter(tableName, new BatchWriterConfig().setMaxMemory(maxMemory)
- .setMaxLatency(maxLatency, MILLISECONDS).setMaxWriteThreads(maxWriteThreads));
- }
-
- @Override
- public BatchWriter createBatchWriter(String tableName, BatchWriterConfig config)
- throws TableNotFoundException {
- return context.createBatchWriter(tableName, config);
- }
-
- @Override
- public MultiTableBatchWriter createMultiTableBatchWriter(long maxMemory, long maxLatency,
- int maxWriteThreads) {
- return context.createMultiTableBatchWriter(new BatchWriterConfig().setMaxMemory(maxMemory)
- .setMaxLatency(maxLatency, MILLISECONDS).setMaxWriteThreads(maxWriteThreads));
- }
-
- @Override
- public MultiTableBatchWriter createMultiTableBatchWriter(BatchWriterConfig config) {
- return context.createMultiTableBatchWriter(config);
- }
-
- @Override
- public ConditionalWriter createConditionalWriter(String tableName, ConditionalWriterConfig config)
- throws TableNotFoundException {
- return context.createConditionalWriter(tableName, config);
- }
-
- @Override
- public Scanner createScanner(String tableName, Authorizations authorizations)
- throws TableNotFoundException {
- return context.createScanner(tableName, authorizations);
- }
-
- @Override
- public String whoami() {
- return context.whoami();
- }
-
- @Override
- public TableOperations tableOperations() {
- return context.tableOperations();
- }
-
- @Override
- public NamespaceOperations namespaceOperations() {
- return context.namespaceOperations();
- }
-
- @Override
- public SecurityOperations securityOperations() {
- return context.securityOperations();
- }
-
- @Override
- public InstanceOperations instanceOperations() {
- return context.instanceOperations();
- }
-
- @Override
- public ReplicationOperations replicationOperations() {
- return context.replicationOperations();
- }
-
-}
diff --git a/core/src/main/java/org/apache/accumulo/core/fate/zookeeper/ZooCacheFactory.java b/core/src/main/java/org/apache/accumulo/core/fate/zookeeper/ZooCacheFactory.java
index 6587fac7a5..731af0443a 100644
--- a/core/src/main/java/org/apache/accumulo/core/fate/zookeeper/ZooCacheFactory.java
+++ b/core/src/main/java/org/apache/accumulo/core/fate/zookeeper/ZooCacheFactory.java
@@ -27,10 +27,12 @@ import org.apache.accumulo.core.singletons.SingletonService;
/**
* A factory for {@link ZooCache} instances.
* <p>
- * Implementation note: We are using the instances map to track all the instances that have been
- * created, so we can explicitly close them when the last legacy client has gone away. This is part
- * of the "SingletonManager" code, and it is likely that ZooCacheFactory and ZooKeeperInstance can
- * be removed when legacy client code support is no longer required.
+ * Implementation note: We were using the instances map to track all the instances that have been
+ * created, so we could explicitly close them when the SingletonManager detected that the last
+ * legacy client (using Connector/ZooKeeperInstance) has gone away. This class may no longer be
+ * needed, since the legacy client code has been removed, so long as the ZooCache instances it is
+ * tracking are managed as resources within ClientContext or ServerContext, and explicitly closed
+ * when those are closed.
*/
public class ZooCacheFactory {
diff --git a/core/src/main/java/org/apache/accumulo/core/singletons/SingletonManager.java b/core/src/main/java/org/apache/accumulo/core/singletons/SingletonManager.java
index 4badba37ee..0a7a1bbb16 100644
--- a/core/src/main/java/org/apache/accumulo/core/singletons/SingletonManager.java
+++ b/core/src/main/java/org/apache/accumulo/core/singletons/SingletonManager.java
@@ -32,8 +32,7 @@ import com.google.common.base.Preconditions;
* Historically, Accumulo client code that used Connector had no control over these singletons. The
* new AccumuloClient API that replaces Connector is closeable. When all AccumuloClients are closed
* then resources used by the singletons are released. This class coordinates releasing those
- * resources. For compatibility purposes this class will not release resources when the user has
- * created Connectors.
+ * resources.
*
* <p>
* This class is intermediate solution to resource management. Ideally there would be no static
@@ -62,9 +61,10 @@ public class SingletonManager {
*/
SERVER,
/**
- * In this mode singletons are never disabled unless the mode is set back to CLIENT. The user
- * can do this by using util.CleanUp (an old API created for users).
+ * This mode was removed along with Connector in 3.0.0. It no longer does anything, but is kept
+ * here to preserve enum ordinals.
*/
+ @Deprecated(since = "3.0.0")
CONNECTOR,
/**
* In this mode singletons are permanently disabled and entering this mode prevents
@@ -77,7 +77,6 @@ public class SingletonManager {
private static long reservations;
private static Mode mode;
private static boolean enabled;
- private static boolean transitionedFromClientToConnector;
private static List<SingletonService> services;
@VisibleForTesting
@@ -85,7 +84,6 @@ public class SingletonManager {
reservations = 0;
mode = Mode.CLIENT;
enabled = true;
- transitionedFromClientToConnector = false;
services = new ArrayList<>();
}
@@ -158,16 +156,8 @@ public class SingletonManager {
return;
if (SingletonManager.mode == Mode.CLOSED)
throw new IllegalStateException("Cannot leave closed mode once entered");
- if (SingletonManager.mode == Mode.CLIENT && mode == Mode.CONNECTOR) {
- if (transitionedFromClientToConnector) {
- throw new IllegalStateException("Can only transition from " + Mode.CLIENT + " to "
- + Mode.CONNECTOR + " once. This error indicates that "
- + "org.apache.accumulo.core.util.CleanUp.shutdownNow() was called and then later a "
- + "Connector was created. Connectors can not be created after CleanUp.shutdownNow()"
- + " is called.");
- }
-
- transitionedFromClientToConnector = true;
+ if (mode == Mode.CONNECTOR) {
+ throw new IllegalArgumentException("CONNECTOR mode was removed");
}
/*
@@ -196,10 +186,9 @@ public class SingletonManager {
}
} else {
// if we're in a disabled state AND
- // the mode is CONNECTOR or SERVER or if there are active clients,
+ // the mode is SERVER or if there are active clients,
// then enable everything
- if (mode == Mode.CONNECTOR || mode == Mode.SERVER
- || (mode == Mode.CLIENT && reservations > 0)) {
+ if (mode == Mode.SERVER || (mode == Mode.CLIENT && reservations > 0)) {
services.forEach(SingletonManager::enable);
enabled = true;
}
diff --git a/core/src/main/java/org/apache/accumulo/core/util/CleanUp.java b/core/src/main/java/org/apache/accumulo/core/util/CleanUp.java
deleted file mode 100644
index c9ab72e2ad..0000000000
--- a/core/src/main/java/org/apache/accumulo/core/util/CleanUp.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.accumulo.core.util;
-
-import java.util.Set;
-
-import org.apache.accumulo.core.client.AccumuloClient;
-import org.apache.accumulo.core.client.Connector;
-import org.apache.accumulo.core.clientImpl.ConnectorImpl;
-import org.apache.accumulo.core.singletons.SingletonManager;
-import org.apache.accumulo.core.singletons.SingletonManager.Mode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Connector uses static resource that create threads and use memory. The only way to clean up these
- * static resource related to Connectors created using ZookeeperInstance is to use this class.
- *
- * <p>
- * This class is not needed when only using {@link AccumuloClient}. The new AccumuloClient API that
- * replaces Connector is closable. For code that only uses AccumuloClient, when all AccumuloClients
- * are closed resources are cleaned up. Connectors that are derived from an AccumuloClient do not
- * necessitate the use of this code.
- *
- * @deprecated since 2.0.0 Use only {@link AccumuloClient} instead. Also, make sure you close the
- * AccumuloClient instances.
- */
-@Deprecated(since = "2.0.0")
-public class CleanUp {
-
- private static final Logger log = LoggerFactory.getLogger(CleanUp.class);
-
- /**
- * kills all threads created by internal Accumulo singleton resources. After this method is
- * called, no Connector will work in the current classloader.
- *
- * @param conn
- * If available, Connector object to close resources on. Will accept null otherwise.
- */
- public static void shutdownNow(Connector conn) {
- SingletonManager.setMode(Mode.CLIENT);
- waitForZooKeeperClientThreads();
- if (conn != null) {
- ConnectorImpl connImpl = (ConnectorImpl) conn;
- connImpl.getAccumuloClient().close();
- }
- }
-
- /**
- * As documented in https://issues.apache.org/jira/browse/ZOOKEEPER-1816, ZooKeeper.close() is a
- * non-blocking call. This method will wait on the ZooKeeper internal threads to exit.
- */
- private static void waitForZooKeeperClientThreads() {
- Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
- for (Thread thread : threadSet) {
- // find ZooKeeper threads that were created in the same ClassLoader as the current thread.
- if (thread.getClass().getName().startsWith("org.apache.zookeeper.ClientCnxn") && thread
- .getContextClassLoader().equals(Thread.currentThread().getContextClassLoader())) {
-
- // wait for the thread the die
- while (thread.isAlive()) {
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- log.error("{}", e.getMessage(), e);
- }
- }
- }
- }
- }
-}
diff --git a/core/src/test/java/org/apache/accumulo/core/client/ZooKeeperInstanceTest.java b/core/src/test/java/org/apache/accumulo/core/client/ZooKeeperInstanceTest.java
deleted file mode 100644
index 48047c710c..0000000000
--- a/core/src/test/java/org/apache/accumulo/core/client/ZooKeeperInstanceTest.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.accumulo.core.client;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-import java.util.List;
-import java.util.UUID;
-
-import org.apache.accumulo.core.Constants;
-import org.apache.accumulo.core.data.InstanceId;
-import org.apache.accumulo.core.fate.zookeeper.ZooCache;
-import org.apache.accumulo.core.fate.zookeeper.ZooCacheFactory;
-import org.easymock.EasyMock;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-@Deprecated(since = "2.0.0")
-public class ZooKeeperInstanceTest {
- private static final InstanceId IID = InstanceId.of(UUID.randomUUID());
- private static final String IID_STRING = IID.canonical();
- private ZooCacheFactory zcf;
- private ZooCache zc;
- private ZooKeeperInstance zki;
-
- private static final ClientConfiguration.ClientProperty INSTANCE_ID =
- ClientConfiguration.ClientProperty.INSTANCE_ID;
- private static final ClientConfiguration.ClientProperty INSTANCE_NAME =
- ClientConfiguration.ClientProperty.INSTANCE_NAME;
- private static final ClientConfiguration.ClientProperty INSTANCE_ZK_HOST =
- ClientConfiguration.ClientProperty.INSTANCE_ZK_HOST;
- private static final ClientConfiguration.ClientProperty INSTANCE_ZK_TIMEOUT =
- ClientConfiguration.ClientProperty.INSTANCE_ZK_TIMEOUT;
-
- private void mockIdConstruction(ClientConfiguration config) {
- expect(config.get(INSTANCE_ID)).andReturn(IID_STRING);
- expect(config.get(INSTANCE_NAME)).andReturn(null);
- expect(config.get(INSTANCE_ZK_HOST)).andReturn("zk1");
- expect(config.get(INSTANCE_ZK_TIMEOUT)).andReturn("30");
- }
-
- private void mockNameConstruction(ClientConfiguration config) {
- expect(config.get(INSTANCE_ID)).andReturn(null);
- expect(config.get(INSTANCE_NAME)).andReturn("instance");
- expect(config.get(INSTANCE_ZK_HOST)).andReturn("zk1");
- expect(config.get(INSTANCE_ZK_TIMEOUT)).andReturn("30");
- }
-
- @BeforeEach
- public void setUp() {
- ClientConfiguration config = createMock(ClientConfiguration.class);
- mockNameConstruction(config);
- replay(config);
- zcf = createMock(ZooCacheFactory.class);
- zc = createMock(ZooCache.class);
- expect(zcf.getZooCache("zk1", 30000)).andReturn(zc).anyTimes();
- expect(zc.get(Constants.ZROOT + Constants.ZINSTANCES + "/instance"))
- .andReturn(IID_STRING.getBytes(UTF_8));
- expect(zc.get(Constants.ZROOT + "/" + IID_STRING)).andReturn("yup".getBytes());
- replay(zc, zcf);
- zki = new ZooKeeperInstance(config, zcf);
- EasyMock.resetToDefault(zc);
- }
-
- @Test
- public void testInvalidConstruction() {
- ClientConfiguration config = createMock(ClientConfiguration.class);
- expect(config.get(INSTANCE_ID)).andReturn(IID_STRING);
- mockNameConstruction(config);
- replay(config);
- assertThrows(IllegalArgumentException.class, () -> new ZooKeeperInstance(config));
- }
-
- @Test
- public void testInvalidConstruction2() {
- ClientConfiguration config = createMock(ClientConfiguration.class);
- expect(config.get(INSTANCE_ID)).andReturn(null);
- expect(config.get(INSTANCE_NAME)).andReturn(null);
- expect(config.get(INSTANCE_ZK_HOST)).andReturn("zk1");
- expect(config.get(INSTANCE_ZK_TIMEOUT)).andReturn("30");
- replay(config);
- assertThrows(IllegalArgumentException.class, () -> new ZooKeeperInstance(config));
- }
-
- @Test
- public void testSimpleGetters() {
- assertEquals("instance", zki.getInstanceName());
- assertEquals("zk1", zki.getZooKeepers());
- assertEquals(30000, zki.getZooKeepersSessionTimeOut());
- }
-
- @Test
- public void testGetInstanceID_FromCache() {
- expect(zc.get(Constants.ZROOT + Constants.ZINSTANCES + "/instance"))
- .andReturn(IID_STRING.getBytes(UTF_8));
- expect(zc.get(Constants.ZROOT + "/" + IID_STRING)).andReturn("yup".getBytes());
- replay(zc);
- assertEquals(IID_STRING, zki.getInstanceID());
- }
-
- @Test
- public void testGetInstanceID_Direct() {
- ClientConfiguration config = createMock(ClientConfiguration.class);
- mockIdConstruction(config);
- replay(config);
- zki = new ZooKeeperInstance(config, zcf);
- expect(zc.get(Constants.ZROOT + "/" + IID_STRING)).andReturn("yup".getBytes());
- replay(zc);
- assertEquals(IID_STRING, zki.getInstanceID());
- }
-
- @Test
- public void testGetInstanceID_NoMapping() {
- ClientConfiguration config = createMock(ClientConfiguration.class);
- expect(zc.get(Constants.ZROOT + Constants.ZINSTANCES + "/instance")).andReturn(null);
- replay(zc);
- EasyMock.reset(config, zcf);
- assertThrows(RuntimeException.class, () -> new ZooKeeperInstance(config, zcf));
- }
-
- @Test
- public void testGetInstanceID_IDMissingForName() {
- expect(zc.get(Constants.ZROOT + Constants.ZINSTANCES + "/instance"))
- .andReturn(IID_STRING.getBytes(UTF_8));
- expect(zc.get(Constants.ZROOT + "/" + IID_STRING)).andReturn(null);
- replay(zc);
- assertThrows(RuntimeException.class, () -> zki.getInstanceID());
- }
-
- @Test
- public void testGetInstanceID_IDMissingForID() {
- ClientConfiguration config = createMock(ClientConfiguration.class);
- mockIdConstruction(config);
- replay(config);
- zki = new ZooKeeperInstance(config, zcf);
- expect(zc.get(Constants.ZROOT + "/" + IID_STRING)).andReturn(null);
- replay(zc);
- assertThrows(RuntimeException.class, () -> zki.getInstanceID());
- }
-
- @Test
- public void testGetInstanceName() {
- ClientConfiguration config = createMock(ClientConfiguration.class);
- mockIdConstruction(config);
- replay(config);
- zki = new ZooKeeperInstance(config, zcf);
- expect(zc.get(Constants.ZROOT + "/" + IID_STRING)).andReturn("yup".getBytes());
- List<String> children = new java.util.ArrayList<>();
- children.add("child1");
- children.add("child2");
- expect(zc.getChildren(Constants.ZROOT + Constants.ZINSTANCES)).andReturn(children);
- expect(zc.get(Constants.ZROOT + Constants.ZINSTANCES + "/child1"))
- .andReturn(UUID.randomUUID().toString().getBytes(UTF_8));
- expect(zc.get(Constants.ZROOT + Constants.ZINSTANCES + "/child2"))
- .andReturn(IID_STRING.getBytes(UTF_8));
- replay(zc);
- assertEquals("child2", zki.getInstanceName());
- }
-
- @Test
- public void testAllZooKeepersAreUsed() {
- final String zookeepers = "zk1,zk2,zk3", instanceName = "accumulo";
- ZooCacheFactory factory = createMock(ZooCacheFactory.class);
- EasyMock.reset(zc);
- expect(factory.getZooCache(zookeepers, 30000)).andReturn(zc).anyTimes();
- expect(zc.get(Constants.ZROOT + Constants.ZINSTANCES + "/" + instanceName))
- .andReturn(IID_STRING.getBytes(UTF_8));
- expect(zc.get(Constants.ZROOT + "/" + IID_STRING)).andReturn("yup".getBytes());
- replay(zc, factory);
- ClientConfiguration cfg =
- ClientConfiguration.loadDefault().withInstance(instanceName).withZkHosts(zookeepers);
- ZooKeeperInstance zki = new ZooKeeperInstance(cfg, factory);
- assertEquals(zookeepers, zki.getZooKeepers());
- assertEquals(instanceName, zki.getInstanceName());
- }
-}
diff --git a/core/src/test/java/org/apache/accumulo/core/singletons/SingletonManagerTest.java b/core/src/test/java/org/apache/accumulo/core/singletons/SingletonManagerTest.java
index 83d087a9d1..33d82a363a 100644
--- a/core/src/test/java/org/apache/accumulo/core/singletons/SingletonManagerTest.java
+++ b/core/src/test/java/org/apache/accumulo/core/singletons/SingletonManagerTest.java
@@ -94,52 +94,21 @@ public class SingletonManagerTest {
}
@Test
- public void testConnectorPreventsDisable() {
-
- SingletonManager.setMode(Mode.CONNECTOR);
- assertEquals(Mode.CONNECTOR, SingletonManager.getMode());
-
+ public void testConnectorRemoved() {
SingletonReservation resv1 = SingletonManager.getClientReservation();
-
- assertEquals(1, SingletonManager.getReservationCount());
-
- SingletonReservation resv2 = SingletonManager.getClientReservation();
-
- assertEquals(2, SingletonManager.getReservationCount());
-
resv1.close();
- resv2.close();
-
- assertEquals(0, SingletonManager.getReservationCount());
-
- assertEquals(new TestService(true, 0, 0), service1);
- assertEquals(new TestService(true, 1, 0), service2);
-
- SingletonManager.setMode(Mode.CLIENT);
- assertEquals(Mode.CLIENT, SingletonManager.getMode());
assertEquals(new TestService(false, 0, 1), service1);
assertEquals(new TestService(false, 1, 1), service2);
- assertThrows(IllegalStateException.class, () -> SingletonManager.setMode(Mode.CONNECTOR),
- "Should only be able to set mode to CONNECTOR once");
-
- assertEquals(Mode.CLIENT, SingletonManager.getMode());
- }
-
- @Test
- public void testConnectorEnables() {
- SingletonReservation resv1 = SingletonManager.getClientReservation();
- resv1.close();
+ // this should do nothing
+ @SuppressWarnings("deprecation")
+ var e = assertThrows(IllegalArgumentException.class,
+ () -> SingletonManager.setMode(Mode.CONNECTOR));
+ assertTrue(e.getMessage().contains("CONNECTOR"));
assertEquals(new TestService(false, 0, 1), service1);
assertEquals(new TestService(false, 1, 1), service2);
-
- // this should enable services
- SingletonManager.setMode(Mode.CONNECTOR);
-
- assertEquals(new TestService(true, 1, 1), service1);
- assertEquals(new TestService(true, 2, 1), service2);
}
@Test
diff --git a/minicluster/src/main/java/org/apache/accumulo/minicluster/MiniAccumuloCluster.java b/minicluster/src/main/java/org/apache/accumulo/minicluster/MiniAccumuloCluster.java
index 43e0c29788..37d127d939 100644
--- a/minicluster/src/main/java/org/apache/accumulo/minicluster/MiniAccumuloCluster.java
+++ b/minicluster/src/main/java/org/apache/accumulo/minicluster/MiniAccumuloCluster.java
@@ -24,10 +24,7 @@ import java.util.Properties;
import java.util.Set;
import org.apache.accumulo.core.client.AccumuloClient;
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
-import org.apache.accumulo.core.client.security.tokens.PasswordToken;
import org.apache.accumulo.core.clientImpl.ClientInfoImpl;
import org.apache.accumulo.core.util.Pair;
import org.apache.accumulo.miniclusterImpl.MiniAccumuloClusterImpl;
@@ -129,19 +126,6 @@ public class MiniAccumuloCluster implements AutoCloseable {
return new MiniAccumuloConfig(impl.getConfig());
}
- /**
- * Utility method to get a connector to the MAC.
- *
- * @since 1.6.0
- * @deprecated since 2.0.0, replaced by {@link #createAccumuloClient(String, AuthenticationToken)}
- */
- @Deprecated(since = "2.0.0")
- public org.apache.accumulo.core.client.Connector getConnector(String user, String passwd)
- throws AccumuloException, AccumuloSecurityException {
- return org.apache.accumulo.core.client.Connector
- .from(impl.createAccumuloClient(user, new PasswordToken(passwd)));
- }
-
/**
* Utility method to create an {@link AccumuloClient} with connection to the MAC. The
* AccumuloClient object should be closed by user
diff --git a/minicluster/src/main/java/org/apache/accumulo/minicluster/MiniAccumuloInstance.java b/minicluster/src/main/java/org/apache/accumulo/minicluster/MiniAccumuloInstance.java
deleted file mode 100644
index c0dafae522..0000000000
--- a/minicluster/src/main/java/org/apache/accumulo/minicluster/MiniAccumuloInstance.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.accumulo.minicluster;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.conf.SiteConfiguration;
-
-/**
- * @since 1.6.0
- * @deprecated since 2.0.0, Use {@link MiniAccumuloCluster#getClientProperties(File)} instead
- */
-@Deprecated(since = "2.0.0")
-public class MiniAccumuloInstance extends org.apache.accumulo.core.client.ZooKeeperInstance {
-
- /**
- * Construct an {@link org.apache.accumulo.core.client.Instance} entry point to Accumulo using a
- * {@link MiniAccumuloCluster} directory
- */
- public MiniAccumuloInstance(String instanceName, File directory) throws FileNotFoundException {
- super(org.apache.accumulo.core.client.ClientConfiguration
- .fromFile(new File(new File(directory, "conf"), "client.conf")).withInstance(instanceName)
- .withZkHosts(getZooKeepersFromDir(directory)));
- }
-
- // Keep this private to avoid bringing it into the public API
- private static String getZooKeepersFromDir(File directory) {
- if (!directory.isDirectory()) {
- throw new IllegalArgumentException("Not a directory " + directory.getPath());
- }
- File configFile = new File(new File(directory, "conf"), "accumulo.properties");
- var conf = SiteConfiguration.fromFile(configFile).build();
- return conf.get(Property.INSTANCE_ZK_HOST);
- }
-}
diff --git a/minicluster/src/test/java/org/apache/accumulo/minicluster/MiniAccumuloClusterClasspathTest.java b/minicluster/src/test/java/org/apache/accumulo/minicluster/MiniAccumuloClusterClasspathTest.java
index c3c1af4a91..a40d13e225 100644
--- a/minicluster/src/test/java/org/apache/accumulo/minicluster/MiniAccumuloClusterClasspathTest.java
+++ b/minicluster/src/test/java/org/apache/accumulo/minicluster/MiniAccumuloClusterClasspathTest.java
@@ -28,6 +28,8 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
+import org.apache.accumulo.core.client.Accumulo;
+import org.apache.accumulo.core.client.AccumuloClient;
import org.apache.accumulo.core.client.BatchWriter;
import org.apache.accumulo.core.client.BatchWriterConfig;
import org.apache.accumulo.core.client.IteratorSetting;
@@ -92,48 +94,49 @@ public class MiniAccumuloClusterClasspathTest extends WithTestNames {
accumulo.stop();
}
- @SuppressWarnings("deprecation")
@Test
@Timeout(60)
public void testPerTableClasspath() throws Exception {
- org.apache.accumulo.core.client.Connector conn =
- accumulo.getConnector(ROOT_USER, ROOT_PASSWORD);
+ try (AccumuloClient client = Accumulo.newClient().from(accumulo.getClientProperties())
+ .as(ROOT_USER, ROOT_PASSWORD).build()) {
- final String tableName = testName();
+ final String tableName = testName();
- var ntc = new NewTableConfiguration();
- ntc.setProperties(Map.of(Property.TABLE_CLASSLOADER_CONTEXT.getKey(), "cx1"));
- ntc.attachIterator(new IteratorSetting(100, "foocensor", "org.apache.accumulo.test.FooFilter"));
+ var ntc = new NewTableConfiguration();
+ ntc.setProperties(Map.of(Property.TABLE_CLASSLOADER_CONTEXT.getKey(), "cx1"));
+ ntc.attachIterator(
+ new IteratorSetting(100, "foocensor", "org.apache.accumulo.test.FooFilter"));
- conn.tableOperations().create(tableName, ntc);
+ client.tableOperations().create(tableName, ntc);
- try (BatchWriter bw = conn.createBatchWriter(tableName, new BatchWriterConfig())) {
+ try (BatchWriter bw = client.createBatchWriter(tableName, new BatchWriterConfig())) {
- Mutation m1 = new Mutation("foo");
- m1.put("cf1", "cq1", "v2");
- m1.put("cf1", "cq2", "v3");
+ Mutation m1 = new Mutation("foo");
+ m1.put("cf1", "cq1", "v2");
+ m1.put("cf1", "cq2", "v3");
- bw.addMutation(m1);
+ bw.addMutation(m1);
- Mutation m2 = new Mutation("bar");
- m2.put("cf1", "cq1", "v6");
- m2.put("cf1", "cq2", "v7");
+ Mutation m2 = new Mutation("bar");
+ m2.put("cf1", "cq1", "v6");
+ m2.put("cf1", "cq2", "v7");
- bw.addMutation(m2);
+ bw.addMutation(m2);
- }
+ }
- int count = 0;
- try (Scanner scanner = conn.createScanner(tableName, new Authorizations())) {
- for (Entry<Key,Value> entry : scanner) {
- assertFalse(entry.getKey().getRowData().toString().toLowerCase().contains("foo"));
- count++;
+ int count = 0;
+ try (Scanner scanner = client.createScanner(tableName, new Authorizations())) {
+ for (Entry<Key,Value> entry : scanner) {
+ assertFalse(entry.getKey().getRowData().toString().toLowerCase().contains("foo"));
+ count++;
+ }
}
- }
- assertEquals(2, count);
+ assertEquals(2, count);
- conn.tableOperations().delete(tableName);
+ client.tableOperations().delete(tableName);
+ }
}
}
diff --git a/minicluster/src/test/java/org/apache/accumulo/minicluster/MiniAccumuloClusterExistingZooKeepersTest.java b/minicluster/src/test/java/org/apache/accumulo/minicluster/MiniAccumuloClusterExistingZooKeepersTest.java
index 8efedb5d5d..fdff86ee3e 100644
--- a/minicluster/src/test/java/org/apache/accumulo/minicluster/MiniAccumuloClusterExistingZooKeepersTest.java
+++ b/minicluster/src/test/java/org/apache/accumulo/minicluster/MiniAccumuloClusterExistingZooKeepersTest.java
@@ -25,6 +25,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.File;
import java.util.Map;
+import org.apache.accumulo.core.client.Accumulo;
+import org.apache.accumulo.core.client.AccumuloClient;
import org.apache.commons.io.FileUtils;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
@@ -56,28 +58,29 @@ public class MiniAccumuloClusterExistingZooKeepersTest extends WithTestNames {
config = new MiniAccumuloConfig(testDir, SECRET);
}
- @SuppressWarnings("deprecation")
@Test
public void canConnectViaExistingZooKeeper() throws Exception {
try (TestingServer zooKeeper = new TestingServer(); MiniAccumuloCluster accumulo =
new MiniAccumuloCluster(config.setExistingZooKeepers(zooKeeper.getConnectString()))) {
accumulo.start();
+ assertEquals(zooKeeper.getConnectString(), accumulo.getZooKeepers());
- org.apache.accumulo.core.client.Connector conn = accumulo.getConnector("root", SECRET);
- assertEquals(zooKeeper.getConnectString(), conn.getInstance().getZooKeepers());
+ try (AccumuloClient client =
+ Accumulo.newClient().from(accumulo.getClientProperties()).as("root", SECRET).build()) {
- String tableName = "foo";
- conn.tableOperations().create(tableName);
- Map<String,String> tableIds = conn.tableOperations().tableIdMap();
- assertTrue(tableIds.containsKey(tableName));
+ String tableName = "foo";
+ client.tableOperations().create(tableName);
+ Map<String,String> tableIds = client.tableOperations().tableIdMap();
+ assertTrue(tableIds.containsKey(tableName));
- String zkTablePath = String.format("/accumulo/%s/tables/%s/name",
- conn.getInstance().getInstanceID(), tableIds.get(tableName));
- try (CuratorFramework client =
- CuratorFrameworkFactory.newClient(zooKeeper.getConnectString(), new RetryOneTime(1))) {
- client.start();
- assertNotNull(client.checkExists().forPath(zkTablePath));
- assertEquals(tableName, new String(client.getData().forPath(zkTablePath)));
+ String zkTablePath = String.format("/accumulo/%s/tables/%s/name",
+ client.instanceOperations().getInstanceId().canonical(), tableIds.get(tableName));
+ try (CuratorFramework curatorClient =
+ CuratorFrameworkFactory.newClient(zooKeeper.getConnectString(), new RetryOneTime(1))) {
+ curatorClient.start();
+ assertNotNull(curatorClient.checkExists().forPath(zkTablePath));
+ assertEquals(tableName, new String(curatorClient.getData().forPath(zkTablePath)));
+ }
}
}
}
diff --git a/minicluster/src/test/java/org/apache/accumulo/minicluster/MiniAccumuloClusterStartStopTest.java b/minicluster/src/test/java/org/apache/accumulo/minicluster/MiniAccumuloClusterStartStopTest.java
index 549bb50e00..5546547a63 100644
--- a/minicluster/src/test/java/org/apache/accumulo/minicluster/MiniAccumuloClusterStartStopTest.java
+++ b/minicluster/src/test/java/org/apache/accumulo/minicluster/MiniAccumuloClusterStartStopTest.java
@@ -23,6 +23,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.File;
import java.io.IOException;
+import org.apache.accumulo.core.client.Accumulo;
+import org.apache.accumulo.core.client.AccumuloClient;
import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
@@ -71,13 +73,14 @@ public class MiniAccumuloClusterStartStopTest extends WithTestNames {
}
}
- @SuppressWarnings("deprecation")
@Test
public void multipleStopsIsAllowed() throws Exception {
accumulo.start();
- org.apache.accumulo.core.client.Connector conn = accumulo.getConnector("root", "superSecret");
- conn.tableOperations().create("foo");
+ try (AccumuloClient client = Accumulo.newClient().from(accumulo.getClientProperties())
+ .as("root", "superSecret").build()) {
+ client.tableOperations().create("foo");
+ }
accumulo.stop();
accumulo.stop();
diff --git a/minicluster/src/test/java/org/apache/accumulo/minicluster/MiniAccumuloClusterTest.java b/minicluster/src/test/java/org/apache/accumulo/minicluster/MiniAccumuloClusterTest.java
index 61921fa238..445ca4ff36 100644
--- a/minicluster/src/test/java/org/apache/accumulo/minicluster/MiniAccumuloClusterTest.java
+++ b/minicluster/src/test/java/org/apache/accumulo/minicluster/MiniAccumuloClusterTest.java
@@ -32,6 +32,8 @@ import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
+import org.apache.accumulo.core.client.Accumulo;
+import org.apache.accumulo.core.client.AccumuloClient;
import org.apache.accumulo.core.client.BatchWriter;
import org.apache.accumulo.core.client.BatchWriterConfig;
import org.apache.accumulo.core.client.IteratorSetting;
@@ -98,84 +100,87 @@ public class MiniAccumuloClusterTest extends WithTestNames {
@Test
@Timeout(30)
public void test() throws Exception {
- org.apache.accumulo.core.client.Connector conn =
- accumulo.getConnector(ROOT_USER, ROOT_PASSWORD);
+ try (AccumuloClient conn = Accumulo.newClient().from(accumulo.getClientProperties())
+ .as(ROOT_USER, ROOT_PASSWORD).build()) {
- final String tableName = testName();
+ final String tableName = testName();
- IteratorSetting is = new IteratorSetting(10, SummingCombiner.class);
- SummingCombiner.setEncodingType(is, LongCombiner.Type.STRING);
- SummingCombiner.setColumns(is,
- Collections.singletonList(new IteratorSetting.Column("META", "COUNT")));
+ IteratorSetting is = new IteratorSetting(10, SummingCombiner.class);
+ SummingCombiner.setEncodingType(is, LongCombiner.Type.STRING);
+ SummingCombiner.setColumns(is,
+ Collections.singletonList(new IteratorSetting.Column("META", "COUNT")));
- conn.tableOperations().create(tableName, new NewTableConfiguration().attachIterator(is));
+ conn.tableOperations().create(tableName, new NewTableConfiguration().attachIterator(is));
- final String principal = "user1";
- final String password = "pass1";
- conn.securityOperations().createLocalUser(principal, new PasswordToken(password));
- conn.securityOperations().changeUserAuthorizations(principal, new Authorizations("A", "B"));
- conn.securityOperations().grantTablePermission(principal, tableName, TablePermission.WRITE);
- conn.securityOperations().grantTablePermission(principal, tableName, TablePermission.READ);
+ final String principal = "user1";
+ final String password = "pass1";
+ conn.securityOperations().createLocalUser(principal, new PasswordToken(password));
+ conn.securityOperations().changeUserAuthorizations(principal, new Authorizations("A", "B"));
+ conn.securityOperations().grantTablePermission(principal, tableName, TablePermission.WRITE);
+ conn.securityOperations().grantTablePermission(principal, tableName, TablePermission.READ);
- org.apache.accumulo.core.client.Connector uconn = accumulo.getConnector(principal, password);
+ try (AccumuloClient uconn = Accumulo.newClient().from(accumulo.getClientProperties())
+ .as(principal, password).build()) {
- try (BatchWriter bw = uconn.createBatchWriter(tableName, new BatchWriterConfig())) {
+ try (BatchWriter bw = uconn.createBatchWriter(tableName, new BatchWriterConfig())) {
- UUID uuid = UUID.randomUUID();
+ UUID uuid = UUID.randomUUID();
- ColumnVisibility colVisAorB = new ColumnVisibility("A|B");
- Mutation m = new Mutation(uuid.toString());
- m.put("META", "SIZE", colVisAorB, "8");
- m.put("META", "CRC", colVisAorB, "456");
- m.put("META", "COUNT", colVisAorB, "1");
- m.put("DATA", "IMG", new ColumnVisibility("A&B"), "ABCDEFGH");
+ ColumnVisibility colVisAorB = new ColumnVisibility("A|B");
+ Mutation m = new Mutation(uuid.toString());
+ m.put("META", "SIZE", colVisAorB, "8");
+ m.put("META", "CRC", colVisAorB, "456");
+ m.put("META", "COUNT", colVisAorB, "1");
+ m.put("DATA", "IMG", new ColumnVisibility("A&B"), "ABCDEFGH");
- bw.addMutation(m);
- bw.flush();
+ bw.addMutation(m);
+ bw.flush();
- m = new Mutation(uuid.toString());
- m.put("META", "COUNT", colVisAorB, "1");
- m.put("META", "CRC", colVisAorB, "123");
- bw.addMutation(m);
+ m = new Mutation(uuid.toString());
+ m.put("META", "COUNT", colVisAorB, "1");
+ m.put("META", "CRC", colVisAorB, "123");
+ bw.addMutation(m);
- }
-
- int count = 0;
- try (Scanner scanner = uconn.createScanner(tableName, new Authorizations("A"))) {
- for (Entry<Key,Value> entry : scanner) {
- final String actualValue = entry.getValue().toString();
- switch (entry.getKey().getColumnQualifierData().toString()) {
- case "COUNT":
- assertEquals("2", actualValue);
- break;
- case "SIZE":
- assertEquals("8", actualValue);
- break;
- case "CRC":
- assertEquals("123", actualValue);
- break;
- default:
- fail();
- break;
}
- count++;
- }
- }
- assertEquals(3, count);
- count = 0;
- try (Scanner scanner = uconn.createScanner(tableName, new Authorizations("A", "B"))) {
- for (Entry<Key,Value> entry : scanner) {
- if (entry.getKey().getColumnQualifierData().toString().equals("IMG")) {
- assertEquals("ABCDEFGH", entry.getValue().toString());
+ int count = 0;
+ try (Scanner scanner = uconn.createScanner(tableName, new Authorizations("A"))) {
+ for (Entry<Key,Value> entry : scanner) {
+ final String actualValue = entry.getValue().toString();
+ switch (entry.getKey().getColumnQualifierData().toString()) {
+ case "COUNT":
+ assertEquals("2", actualValue);
+ break;
+ case "SIZE":
+ assertEquals("8", actualValue);
+ break;
+ case "CRC":
+ assertEquals("123", actualValue);
+ break;
+ default:
+ fail();
+ break;
+ }
+ count++;
+ }
}
- count++;
+ assertEquals(3, count);
+
+ count = 0;
+ try (Scanner scanner = uconn.createScanner(tableName, new Authorizations("A", "B"))) {
+ for (Entry<Key,Value> entry : scanner) {
+ if (entry.getKey().getColumnQualifierData().toString().equals("IMG")) {
+ assertEquals("ABCDEFGH", entry.getValue().toString());
+ }
+ count++;
+ }
+ }
+
+ assertEquals(4, count);
}
+ conn.tableOperations().delete(tableName);
}
- assertEquals(4, count);
-
- conn.tableOperations().delete(tableName);
}
@Test
diff --git a/server/base/src/test/java/org/apache/accumulo/server/security/SystemCredentialsTest.java b/server/base/src/test/java/org/apache/accumulo/server/security/SystemCredentialsTest.java
index bc75dc7bf7..ecd76424eb 100644
--- a/server/base/src/test/java/org/apache/accumulo/server/security/SystemCredentialsTest.java
+++ b/server/base/src/test/java/org/apache/accumulo/server/security/SystemCredentialsTest.java
@@ -86,22 +86,6 @@ public class SystemCredentialsTest {
assertTrue(hash.startsWith(SystemToken.SALT_PREFIX));
}
- /**
- * This is a test to ensure the SYSTEM_TOKEN_NAME string literal in
- * {@link org.apache.accumulo.core.clientImpl.ConnectorImpl} is kept up-to-date if we move the
- * {@link SystemToken}<br>
- *
- * @deprecated This check will not be needed after Connector is removed
- */
- @Deprecated(since = "2.0.0")
- @Test
- public void testSystemToken() {
- assertEquals("org.apache.accumulo.server.security.SystemCredentials$SystemToken",
- SystemToken.class.getName());
- assertEquals(SystemCredentials.get(instanceId, siteConfig).getToken().getClass(),
- SystemToken.class);
- }
-
@Test
public void testSystemCredentials() {
Credentials a = SystemCredentials.get(instanceId, siteConfig);
diff --git a/shell/src/main/java/org/apache/accumulo/shell/Shell.java b/shell/src/main/java/org/apache/accumulo/shell/Shell.java
index fce386fcf8..7b086292f6 100644
--- a/shell/src/main/java/org/apache/accumulo/shell/Shell.java
+++ b/shell/src/main/java/org/apache/accumulo/shell/Shell.java
@@ -384,9 +384,7 @@ public class Shell extends ShellOptions implements KeywordExecutable {
{new ClasspathCommand(), new org.apache.accumulo.shell.commands.DebugCommand(),
new ListScansCommand(), new ListCompactionsCommand(), new TraceCommand(),
new PingCommand(), new ListBulkCommand(), new ListTabletsCommand()};
- @SuppressWarnings("deprecation")
- Command[] execCommands = {new ExecfileCommand(), new HistoryCommand(), new ExtensionCommand(),
- new org.apache.accumulo.shell.commands.ScriptCommand()};
+ Command[] execCommands = {new ExecfileCommand(), new HistoryCommand(), new ExtensionCommand()};
Command[] exitCommands = {new ByeCommand(), new ExitCommand(), new QuitCommand()};
Command[] helpCommands =
{new AboutCommand(), new HelpCommand(), new InfoCommand(), new QuestionCommand()};
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ScriptCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ScriptCommand.java
deleted file mode 100644
index b5350d6322..0000000000
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/ScriptCommand.java
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.accumulo.shell.commands;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-
-import javax.script.Bindings;
-import javax.script.Compilable;
-import javax.script.CompiledScript;
-import javax.script.Invocable;
-import javax.script.ScriptContext;
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineFactory;
-import javax.script.ScriptEngineManager;
-import javax.script.ScriptException;
-import javax.script.SimpleScriptContext;
-
-import org.apache.accumulo.core.client.AccumuloClient;
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.shell.Shell;
-import org.apache.accumulo.shell.Shell.Command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-
-/**
- * @deprecated since 2.0; this command shouldn't be used; The script command is deprecated; use
- * jshell for scripting instead
- */
-
-@Deprecated(since = "2.1.0")
-public class ScriptCommand extends Command {
-
- // Command to allow user to run scripts, see JSR-223
- // https://www.oracle.com/technetwork/articles/javase/scripting-140262.html
-
- protected Option list, engine, script, file, args, out, function, object;
- private static final String DEFAULT_ENGINE = "rhino";
-
- @SuppressFBWarnings(value = "PATH_TRAVERSAL_IN",
- justification = "app is run in same security context as user providing the filename")
- @Override
- public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception {
-
- boolean invoke = false;
-
- Shell.log.warn("The script command is deprecated; use jshell for scripting instead");
- ScriptEngineManager mgr = new ScriptEngineManager();
-
- if (cl.hasOption(list.getOpt())) {
- listJSREngineInfo(mgr, shellState);
- } else if (cl.hasOption(file.getOpt()) || cl.hasOption(script.getOpt())) {
- String engineName = DEFAULT_ENGINE;
- if (cl.hasOption(engine.getOpt())) {
- engineName = cl.getOptionValue(engine.getOpt());
- }
- ScriptEngine engine = mgr.getEngineByName(engineName);
- if (engine == null) {
- shellState.printException(new Exception(engineName + " not found"));
- return 1;
- }
-
- if (cl.hasOption(object.getOpt()) || cl.hasOption(function.getOpt())) {
- if (!(engine instanceof Invocable)) {
- shellState.printException(
- new Exception(engineName + " does not support invoking functions or methods"));
- return 1;
- }
- invoke = true;
- }
-
- ScriptContext ctx = new SimpleScriptContext();
-
- // Put the following objects into the context so that they
- // are available to the scripts
- // TODO: What else should go in here?
- Bindings b = engine.getBindings(ScriptContext.ENGINE_SCOPE);
- putConnector(b, shellState.getAccumuloClient());
- b.put("client", shellState.getAccumuloClient());
-
- List<Object> argValues = new ArrayList<>();
- if (cl.hasOption(args.getOpt())) {
- String[] argList = cl.getOptionValue(args.getOpt()).split(",");
- for (String arg : argList) {
- String[] parts = arg.split("=");
- if (parts.length == 0) {
- continue;
- } else if (parts.length == 1) {
- b.put(parts[0], null);
- argValues.add(null);
- } else if (parts.length == 2) {
- b.put(parts[0], parts[1]);
- argValues.add(parts[1]);
- }
- }
- }
- ctx.setBindings(b, ScriptContext.ENGINE_SCOPE);
- Object[] argArray = argValues.toArray(new Object[argValues.size()]);
-
- Writer writer = null;
- if (cl.hasOption(out.getOpt())) {
- File f = new File(cl.getOptionValue(out.getOpt()));
- writer = new FileWriter(f, UTF_8);
- ctx.setWriter(writer);
- }
-
- if (cl.hasOption(file.getOpt())) {
- File f = new File(cl.getOptionValue(file.getOpt()));
- if (!f.exists()) {
- if (writer != null) {
- writer.close();
- }
- shellState.printException(new Exception(f.getAbsolutePath() + " not found"));
- return 1;
- }
- Reader reader = new FileReader(f, UTF_8);
- try (reader) {
- engine.eval(reader, ctx);
- if (invoke) {
- this.invokeFunctionOrMethod(shellState, engine, cl, argArray);
- }
- } catch (ScriptException ex) {
- shellState.printException(ex);
- return 1;
- } finally {
- if (writer != null) {
- writer.close();
- }
- }
- } else if (cl.hasOption(script.getOpt())) {
- String inlineScript = cl.getOptionValue(script.getOpt());
- try {
- if (engine instanceof Compilable) {
- Compilable compiledEng = (Compilable) engine;
- CompiledScript script = compiledEng.compile(inlineScript);
- script.eval(ctx);
- if (invoke) {
- this.invokeFunctionOrMethod(shellState, engine, cl, argArray);
- }
- } else {
- engine.eval(inlineScript, ctx);
- if (invoke) {
- this.invokeFunctionOrMethod(shellState, engine, cl, argArray);
- }
- }
- } catch (ScriptException ex) {
- shellState.printException(ex);
- return 1;
- } finally {
- if (writer != null) {
- writer.close();
- }
- }
- }
- if (writer != null) {
- writer.close();
- }
-
- } else {
- printHelp(shellState);
- }
- return 0;
- }
-
- private void putConnector(Bindings b, AccumuloClient client) {
- try {
- b.put("connection", org.apache.accumulo.core.client.Connector.from(client));
- } catch (AccumuloSecurityException | AccumuloException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public String description() {
- return "(deprecated) execute JSR-223 scripts";
- }
-
- @Override
- public int numArgs() {
- return 0;
- }
-
- @Override
- public Options getOptions() {
- final Options o = new Options();
-
- engine = new Option("e", "engine", false, "engine name, defaults to JDK default (Rhino)");
- engine.setArgName("engineName");
- engine.setArgs(1);
- engine.setRequired(false);
- o.addOption(engine);
-
- OptionGroup inputGroup = new OptionGroup();
- list = new Option("l", "list", false, "list available script engines");
- inputGroup.addOption(list);
-
- script = new Option("s", "script", true, "use inline script");
- script.setArgName("script text");
- script.setArgs(1);
- script.setRequired(false);
- inputGroup.addOption(script);
-
- file = new Option("f", "file", true, "use script file");
- file.setArgName("fileName");
- file.setArgs(1);
- file.setRequired(false);
-
- inputGroup.addOption(file);
- inputGroup.setRequired(true);
- o.addOptionGroup(inputGroup);
-
- OptionGroup invokeGroup = new OptionGroup();
- object = new Option("obj", "object", true, "name of object");
- object.setArgs(1);
- object.setArgName("objectName:methodName");
- object.setRequired(false);
- invokeGroup.addOption(object);
-
- function = new Option("fx", "function", true, "invoke a script function");
- function.setArgName("functionName");
- function.setArgs(1);
- function.setRequired(false);
- invokeGroup.addOption(function);
- invokeGroup.setRequired(false);
- o.addOptionGroup(invokeGroup);
-
- args = new Option("a", "args", true, "comma separated list of key=value arguments");
- args.setArgName("property1=value1,propert2=value2,...");
- args.setArgs(Option.UNLIMITED_VALUES);
- args.setRequired(false);
- o.addOption(args);
-
- out = new Option("o", "output", true, "output file");
- out.setArgName("fileName");
- out.setArgs(1);
- out.setRequired(false);
- o.addOption(out);
-
- return o;
- }
-
- private void listJSREngineInfo(ScriptEngineManager mgr, Shell shellState) throws IOException {
- List<ScriptEngineFactory> factories = mgr.getEngineFactories();
- Set<String> lines = new TreeSet<>();
- for (ScriptEngineFactory factory : factories) {
- lines.add("ScriptEngineFactory Info");
- String engName = factory.getEngineName();
- String engVersion = factory.getEngineVersion();
- String langName = factory.getLanguageName();
- String langVersion = factory.getLanguageVersion();
- lines.add("\tScript Engine: " + engName + " (" + engVersion + ")");
- List<String> engNames = factory.getNames();
- for (String name : engNames) {
- lines.add("\tEngine Alias: " + name);
- }
- lines.add("\tLanguage: " + langName + " (" + langVersion + ")");
- }
- shellState.printLines(lines.iterator(), true);
-
- }
-
- private void invokeFunctionOrMethod(Shell shellState, ScriptEngine engine, CommandLine cl,
- Object[] args) {
- try {
- Invocable inv = (Invocable) engine;
- if (cl.hasOption(function.getOpt())) {
- inv.invokeFunction(cl.getOptionValue(function.getOpt()), args);
- } else if (cl.hasOption(object.getOpt())) {
- String objectMethod = cl.getOptionValue(object.getOpt());
- String[] parts = objectMethod.split(":");
- if (parts.length != 2) {
- shellState.printException(new Exception("Object and Method must be supplied"));
- return;
- }
- String objectName = parts[0];
- String methodName = parts[1];
- Object obj = engine.get(objectName);
- inv.invokeMethod(obj, methodName, args);
-
- }
- } catch (Exception e) {
- shellState.printException(e);
- }
- }
-
-}
diff --git a/test/src/main/java/org/apache/accumulo/test/functional/AccumuloClientIT.java b/test/src/main/java/org/apache/accumulo/test/functional/AccumuloClientIT.java
index d5fb850607..694f4ee755 100644
--- a/test/src/main/java/org/apache/accumulo/test/functional/AccumuloClientIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/functional/AccumuloClientIT.java
@@ -72,42 +72,6 @@ public class AccumuloClientIT extends AccumuloClusterHarness {
assertTrue(e.getMessage().toLowerCase().contains("closed"));
}
- @SuppressWarnings("deprecation")
- @Test
- public void testGetConnectorFromAccumuloClient() throws Exception {
- AccumuloClient client = Accumulo.newClient().from(getClientProps()).build();
- org.apache.accumulo.core.client.Connector c =
- org.apache.accumulo.core.client.Connector.from(client);
- assertEquals(client.whoami(), c.whoami());
-
- // this should cause the connector to stop functioning
- client.close();
-
- expectClosed(c::tableOperations);
- }
-
- @SuppressWarnings("deprecation")
- @Test
- public void testGetAccumuloClientFromConnector() throws Exception {
- try (AccumuloClient client1 = Accumulo.newClient().from(getClientProps()).build()) {
- org.apache.accumulo.core.client.Connector c =
- org.apache.accumulo.core.client.Connector.from(client1);
-
- String tableName = getUniqueNames(1)[0];
-
- c.tableOperations().create(tableName);
-
- try (AccumuloClient client2 = org.apache.accumulo.core.client.Connector.newClient(c)) {
- assertTrue(client2.tableOperations().list().contains(tableName));
- }
-
- // closing client2 should not have had an impact on the connector or client1
-
- assertTrue(client1.tableOperations().list().contains(tableName));
- assertTrue(c.tableOperations().list().contains(tableName));
- }
- }
-
@Test
public void testAccumuloClientBuilder() throws Exception {
AccumuloClient c = Accumulo.newClient().from(getClientProps()).build();
diff --git a/test/src/main/java/org/apache/accumulo/test/functional/CleanUpIT.java b/test/src/main/java/org/apache/accumulo/test/functional/CleanUpIT.java
deleted file mode 100644
index 38b03ea4e7..0000000000
--- a/test/src/main/java/org/apache/accumulo/test/functional/CleanUpIT.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.accumulo.test.functional;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.fail;
-
-import java.time.Duration;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.apache.accumulo.core.client.BatchWriter;
-import org.apache.accumulo.core.client.BatchWriterConfig;
-import org.apache.accumulo.core.client.MutationsRejectedException;
-import org.apache.accumulo.core.client.Scanner;
-import org.apache.accumulo.core.data.Key;
-import org.apache.accumulo.core.data.Mutation;
-import org.apache.accumulo.core.data.Value;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.core.singletons.SingletonManager;
-import org.apache.accumulo.harness.SharedMiniClusterBase;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.Iterables;
-
-/**
- * Ensures that all threads spawned for ZooKeeper and Thrift connectivity are reaped after calling
- * CleanUp.shutdown().
- *
- * Because this is destructive across the current context classloader, the normal teardown methods
- * will fail (because they attempt to create a Connector). Until the ZooKeeperInstance and Connector
- * are self-contained WRT resource management, we can't leverage the AccumuloClusterBase.
- */
-public class CleanUpIT extends SharedMiniClusterBase {
- private static final Logger log = LoggerFactory.getLogger(CleanUpIT.class);
-
- @Override
- protected Duration defaultTimeout() {
- return Duration.ofSeconds(30);
- }
-
- @BeforeAll
- public static void setup() throws Exception {
- SharedMiniClusterBase.startMiniCluster();
- }
-
- @AfterAll
- public static void teardown() {
- SharedMiniClusterBase.stopMiniCluster();
- }
-
- @SuppressWarnings("deprecation")
- @Test
- public void run() throws Exception {
-
- // CleanUp for Connectors will not work if there are active AccumuloClients
- assertEquals(0, SingletonManager.getReservationCount());
-
- // CleanUp was created to clean up after connectors. This test intentionally creates a connector
- // instead of an AccumuloClient
- org.apache.accumulo.core.client.Connector conn =
- new org.apache.accumulo.core.client.ZooKeeperInstance(getCluster().getInstanceName(),
- getCluster().getZooKeepers()).getConnector(getPrincipal(), getToken());
-
- String tableName = getUniqueNames(1)[0];
- conn.tableOperations().create(tableName);
-
- BatchWriter bw = conn.createBatchWriter(tableName, new BatchWriterConfig());
-
- Mutation m1 = new Mutation("r1");
- m1.put("cf1", "cq1", 1, "5");
-
- bw.addMutation(m1);
-
- bw.flush();
-
- try (Scanner scanner = conn.createScanner(tableName, new Authorizations())) {
-
- int count = 0;
- for (Entry<Key,Value> entry : scanner) {
- count++;
- if (!entry.getValue().toString().equals("5")) {
- fail("Unexpected value " + entry.getValue());
- }
- }
-
- assertEquals(1, count, "Unexpected count");
-
- int threadCount = countThreads();
- if (threadCount < 2) {
- printThreadNames();
- fail("Not seeing expected threads. Saw " + threadCount);
- }
-
- // explicitly close the scanner to verify that the scanner throws after close when iterated
- scanner.close();
- assertThrows(IllegalStateException.class, () -> Iterables.size(scanner));
- }
-
- // close the scanners before closing the client, because the scanners need the client's cleanup
- // thread pool to execute their cleanup tasks when they are closed, so they don't block
- org.apache.accumulo.core.util.CleanUp.shutdownNow(conn);
-
- Mutation m2 = new Mutation("r2");
- m2.put("cf1", "cq1", 1, "6");
-
- bw.addMutation(m1);
- assertThrows(MutationsRejectedException.class, bw::flush);
-
- // expect this to fail also, want to clean up batch writer threads
- assertThrows(MutationsRejectedException.class, bw::close);
-
- var threadCount = countThreads();
- if (threadCount > 0) {
- printThreadNames();
- fail("Threads did not go away. Saw " + threadCount);
- }
- }
-
- private void printThreadNames() {
- Set<Thread> threads = Thread.getAllStackTraces().keySet();
- Exception e = new Exception();
- for (Thread thread : threads) {
- e.setStackTrace(thread.getStackTrace());
- log.info("thread name: " + thread.getName(), e);
- }
- }
-
- /**
- * count threads that should be cleaned up
- *
- */
- private int countThreads() {
- int count = 0;
- Set<Thread> threads = Thread.getAllStackTraces().keySet();
- for (Thread thread : threads) {
-
- if (thread.getName().toLowerCase().contains("sendthread")
- || thread.getName().toLowerCase().contains("eventthread"))
- count++;
-
- if (thread.getName().toLowerCase().contains("thrift")
- && thread.getName().toLowerCase().contains("pool"))
- count++;
- }
-
- return count;
- }
-}