| /* |
| * 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.testing.randomwalk.concurrent; |
| |
| import java.util.Properties; |
| import java.util.SortedSet; |
| |
| import org.apache.accumulo.core.client.AccumuloException; |
| import org.apache.accumulo.core.client.NamespaceNotFoundException; |
| import org.apache.accumulo.core.client.TableNotFoundException; |
| import org.apache.accumulo.core.conf.Property; |
| import org.apache.accumulo.testing.randomwalk.RandWalkEnv; |
| import org.apache.accumulo.testing.randomwalk.State; |
| import org.apache.accumulo.testing.randomwalk.Test; |
| import org.apache.commons.math3.random.RandomDataGenerator; |
| |
| public class Config extends Test { |
| |
| private static final String LAST_SETTING = "lastSetting"; |
| |
| private static final String LAST_TABLE_SETTING = "lastTableSetting"; |
| |
| private static final String LAST_NAMESPACE_SETTING = "lastNamespaceSetting"; |
| |
| static class Setting { |
| final public Property property; |
| final public long min; |
| final public long max; |
| |
| public Setting(Property property, long min, long max) { |
| this.property = property; |
| this.min = min; |
| this.max = max; |
| } |
| } |
| |
| static Setting s(Property property, long min, long max) { |
| return new Setting(property, min, max); |
| } |
| |
| final Property TSERV_READ_AHEAD_MAXCONCURRENT_deprecated = |
| Property.TSERV_SCAN_EXECUTORS_DEFAULT_THREADS; |
| |
| @SuppressWarnings("deprecation") |
| final Property TSERV_COMPACTION_SERVICE_DEFAULT_MAX_OPEN_deprecated = |
| Property.TSERV_COMPACTION_SERVICE_DEFAULT_MAX_OPEN; |
| |
| @SuppressWarnings("deprecation") |
| final Property TSERV_COMPACTION_SERVICE_DEFAULT_EXECUTORS_deprecated = |
| Property.TSERV_COMPACTION_SERVICE_DEFAULT_EXECUTORS; |
| |
| @SuppressWarnings("deprecation") |
| final Property TSERV_WORKQ_THREADS_deprecated = Property.TSERV_WORKQ_THREADS; |
| |
| // @formatter:off |
| final Setting[] settings = { |
| s(Property.TSERV_BLOOM_LOAD_MAXCONCURRENT, 1, 10), |
| s(Property.TSERV_DATACACHE_SIZE, 0, 1000000000L), |
| s(Property.TSERV_INDEXCACHE_SIZE, 0, 1000000000L), |
| s(Property.TSERV_CLIENT_TIMEOUT, 100, 10000), |
| s(TSERV_COMPACTION_SERVICE_DEFAULT_EXECUTORS_deprecated, 1, 10), |
| s(Property.TSERV_MAJC_DELAY, 100, 10000), |
| s(TSERV_COMPACTION_SERVICE_DEFAULT_MAX_OPEN_deprecated, 3, 100), |
| s(Property.TSERV_MINC_MAXCONCURRENT, 1, 10), |
| s(Property.TSERV_DEFAULT_BLOCKSIZE, 100000, 10000000L), |
| s(Property.TSERV_MAX_IDLE, 10000, 500 * 1000), |
| s(Property.TSERV_MAXMEM, 1000000, 3 * 1024 * 1024 * 1024L), |
| s(TSERV_READ_AHEAD_MAXCONCURRENT_deprecated, 1, 25), |
| s(Property.TSERV_MIGRATE_MAXCONCURRENT, 1, 10), |
| s(Property.TSERV_TOTAL_MUTATION_QUEUE_MAX, 10000, 1024 * 1024), |
| s(Property.TSERV_WAL_SORT_MAX_CONCURRENT, 1, 100), |
| s(Property.TSERV_SCAN_MAX_OPENFILES, 10, 1000), |
| s(Property.TSERV_THREADCHECK, 100, 10000), |
| s(Property.TSERV_MINTHREADS, 1, 100), |
| s(Property.TSERV_SESSION_MAXIDLE, 100, 5 * 60 * 1000), |
| s(Property.TSERV_WAL_SORT_BUFFER_SIZE, 1024 * 1024, 1024 * 1024 * 1024L), |
| s(Property.TSERV_TABLET_SPLIT_FINDMIDPOINT_MAXOPEN, 5, 100), |
| s(Property.TSERV_WAL_BLOCKSIZE, 1024 * 1024,1024 * 1024 * 1024 * 10L), |
| s(TSERV_WORKQ_THREADS_deprecated, 1, 10), |
| s(Property.MANAGER_BULK_TIMEOUT, 10, 600), |
| s(Property.MANAGER_FATE_THREADPOOL_SIZE, 1, 100), |
| s(Property.MANAGER_RECOVERY_DELAY, 0, 100), |
| s(Property.MANAGER_LEASE_RECOVERY_WAITING_PERIOD, 0, 10), |
| s(Property.MANAGER_THREADCHECK, 100, 10000), |
| s(Property.MANAGER_MINTHREADS, 1, 200),}; |
| |
| final Setting[] tableSettings = { |
| s(Property.TABLE_MAJC_RATIO, 1, 10), |
| s(Property.TABLE_SPLIT_THRESHOLD, 10 * 1024, 10L * 1024 * 1024 * 1024), |
| s(Property.TABLE_MINC_COMPACT_IDLETIME, 100, 100 * 60 * 60 * 1000L), |
| s(Property.TABLE_SCAN_MAXMEM, 10 * 1024, 10 * 1024 * 1024), |
| s(Property.TABLE_FILE_COMPRESSED_BLOCK_SIZE, 10 * 1024, 10 * 1024 * 1024L), |
| s(Property.TABLE_FILE_COMPRESSED_BLOCK_SIZE_INDEX, 10 * 1024, 10 * 1024 * 1024L), |
| s(Property.TABLE_FILE_REPLICATION, 0, 5), |
| s(Property.TABLE_FILE_MAX, 2, 50),}; |
| // @formatter:on |
| |
| @Override |
| public void visit(State state, RandWalkEnv env, Properties props) throws Exception { |
| // reset any previous setting |
| Object lastSetting = state.getOkIfAbsent(LAST_SETTING); |
| if (lastSetting != null) { |
| int choice = Integer.parseInt(lastSetting.toString()); |
| Property property = settings[choice].property; |
| log.debug("Setting " + property.getKey() + " back to " + property.getDefaultValue()); |
| env.getAccumuloClient().instanceOperations().setProperty(property.getKey(), |
| property.getDefaultValue()); |
| } |
| lastSetting = state.getOkIfAbsent(LAST_TABLE_SETTING); |
| if (lastSetting != null) { |
| String[] parts = lastSetting.toString().split(","); |
| String table = parts[0]; |
| int choice = Integer.parseInt(parts[1]); |
| Property property = tableSettings[choice].property; |
| if (env.getAccumuloClient().tableOperations().exists(table)) { |
| log.debug("Setting " + property.getKey() + " on " + table + " back to " |
| + property.getDefaultValue()); |
| try { |
| env.getAccumuloClient().tableOperations().setProperty(table, property.getKey(), |
| property.getDefaultValue()); |
| } catch (AccumuloException ex) { |
| if (ex.getCause() instanceof TableNotFoundException) { |
| return; |
| } |
| throw ex; |
| } |
| } |
| } |
| lastSetting = state.getOkIfAbsent(LAST_NAMESPACE_SETTING); |
| if (lastSetting != null) { |
| String[] parts = lastSetting.toString().split(","); |
| String namespace = parts[0]; |
| int choice = Integer.parseInt(parts[1]); |
| Property property = tableSettings[choice].property; |
| if (env.getAccumuloClient().namespaceOperations().exists(namespace)) { |
| log.debug("Setting " + property.getKey() + " on " + namespace + " back to " |
| + property.getDefaultValue()); |
| try { |
| env.getAccumuloClient().namespaceOperations().setProperty(namespace, property.getKey(), |
| property.getDefaultValue()); |
| } catch (AccumuloException ex) { |
| if (ex.getCause() instanceof NamespaceNotFoundException) { |
| return; |
| } |
| throw ex; |
| } |
| } |
| } |
| state.remove(LAST_SETTING); |
| state.remove(LAST_TABLE_SETTING); |
| state.remove(LAST_NAMESPACE_SETTING); |
| RandomDataGenerator random = new RandomDataGenerator(); |
| int dice = random.nextInt(0, 2); |
| if (dice == 0) { |
| changeTableSetting(random, state, env, props); |
| } else if (dice == 1) { |
| changeNamespaceSetting(random, state, env, props); |
| } else { |
| changeSetting(random, state, env, props); |
| } |
| } |
| |
| private void changeTableSetting(RandomDataGenerator random, State state, RandWalkEnv env, |
| Properties props) throws Exception { |
| // pick a random property |
| int choice = random.nextInt(0, tableSettings.length - 1); |
| Setting setting = tableSettings[choice]; |
| |
| // pick a random table |
| SortedSet<String> tables = |
| env.getAccumuloClient().tableOperations().list().tailSet("ctt").headSet("ctu"); |
| if (tables.isEmpty()) |
| return; |
| String table = random.nextSample(tables, 1)[0].toString(); |
| |
| // generate a random value |
| long newValue = random.nextLong(setting.min, setting.max); |
| state.set(LAST_TABLE_SETTING, table + "," + choice); |
| log.debug("Setting " + setting.property.getKey() + " on table " + table + " to " + newValue); |
| try { |
| env.getAccumuloClient().tableOperations().setProperty(table, setting.property.getKey(), |
| "" + newValue); |
| } catch (AccumuloException ex) { |
| if (ex.getCause() instanceof TableNotFoundException) { |
| return; |
| } |
| throw ex; |
| } |
| } |
| |
| private void changeNamespaceSetting(RandomDataGenerator random, State state, RandWalkEnv env, |
| Properties props) throws Exception { |
| // pick a random property |
| int choice = random.nextInt(0, tableSettings.length - 1); |
| Setting setting = tableSettings[choice]; |
| |
| // pick a random table |
| SortedSet<String> namespaces = |
| env.getAccumuloClient().namespaceOperations().list().tailSet("nspc").headSet("nspd"); |
| if (namespaces.isEmpty()) |
| return; |
| String namespace = random.nextSample(namespaces, 1)[0].toString(); |
| |
| // generate a random value |
| long newValue = random.nextLong(setting.min, setting.max); |
| state.set(LAST_NAMESPACE_SETTING, namespace + "," + choice); |
| log.debug( |
| "Setting " + setting.property.getKey() + " on namespace " + namespace + " to " + newValue); |
| try { |
| env.getAccumuloClient().namespaceOperations().setProperty(namespace, |
| setting.property.getKey(), "" + newValue); |
| } catch (AccumuloException ex) { |
| if (ex.getCause() instanceof NamespaceNotFoundException) { |
| return; |
| } |
| throw ex; |
| } |
| } |
| |
| private void changeSetting(RandomDataGenerator random, State state, RandWalkEnv env, |
| Properties props) throws Exception { |
| // pick a random property |
| int choice = random.nextInt(0, settings.length - 1); |
| Setting setting = settings[choice]; |
| // generate a random value |
| long newValue = random.nextLong(setting.min, setting.max); |
| state.set(LAST_SETTING, "" + choice); |
| log.debug("Setting " + setting.property.getKey() + " to " + newValue); |
| env.getAccumuloClient().instanceOperations().setProperty(setting.property.getKey(), |
| "" + newValue); |
| } |
| |
| } |