This is an automated email from the ASF dual-hosted git repository. brandonwilliams pushed a commit to branch cassandra-3.11 in repository https://gitbox.apache.org/repos/asf/cassandra.git
commit 7e684482353b763d7f41b9cb15d311bf150174f8 Merge: b5d0626 28004d9 Author: Brandon Williams <brandonwilli...@apache.org> AuthorDate: Thu Jan 20 09:47:23 2022 -0600 Merge branch 'cassandra-3.0' into cassandra-3.11 CHANGES.txt | 1 + build.xml | 4 ++-- .../apache/cassandra/config/DatabaseDescriptorRefTest.java | 2 +- .../cql3/validation/operations/AggregationTest.java | 12 ++++++++++++ 4 files changed, 16 insertions(+), 3 deletions(-) diff --cc CHANGES.txt index 5e8213f,65fe841..c810378 --- a/CHANGES.txt +++ b/CHANGES.txt @@@ -1,16 -1,5 +1,17 @@@ -3.0.26: +3.11.12 + * Upgrade snakeyaml to 1.26 in 3.11 (CASSANDRA=17028) + * Add key validation to ssstablescrub (CASSANDRA-16969) + * Update Jackson from 2.9.10 to 2.12.5 (CASSANDRA-16851) + * Include SASI components to snapshots (CASSANDRA-15134) + * Make assassinate more resilient to missing tokens (CASSANDRA-16847) + * Exclude Jackson 1.x transitive dependency of hadoop* provided dependencies (CASSANDRA-16854) + * Validate SASI tokenizer options before adding index to schema (CASSANDRA-15135) + * Fixup scrub output when no data post-scrub and clear up old use of row, which really means partition (CASSANDRA-16835) + * Fix ant-junit dependency issue (CASSANDRA-16827) + * Reduce thread contention in CommitLogSegment and HintsBuffer (CASSANDRA-16072) + * Avoid sending CDC column if not enabled (CASSANDRA-16770) +Merged from 3.0: + * Upgrade logback to 1.2.9 (CASSANDRA-17204) * Avoid race in AbstractReplicationStrategy endpoint caching (CASSANDRA-16673) * Fix abort when window resizing during cqlsh COPY (CASSANDRA-15230) * Fix slow keycache load which blocks startup for tables with many sstables (CASSANDRA-14898) diff --cc build.xml index 9b4b086,6dd09fe..a094e8b --- a/build.xml +++ b/build.xml @@@ -351,11 -326,10 +351,11 @@@ <dependency groupId="org.slf4j" artifactId="slf4j-api" version="1.7.7"/> <dependency groupId="org.slf4j" artifactId="log4j-over-slf4j" version="1.7.7"/> <dependency groupId="org.slf4j" artifactId="jcl-over-slf4j" version="1.7.7" /> - <dependency groupId="ch.qos.logback" artifactId="logback-core" version="1.1.3"/> - <dependency groupId="ch.qos.logback" artifactId="logback-classic" version="1.1.3"/> + <dependency groupId="ch.qos.logback" artifactId="logback-core" version="1.2.9"/> + <dependency groupId="ch.qos.logback" artifactId="logback-classic" version="1.2.9"/> - <dependency groupId="org.codehaus.jackson" artifactId="jackson-core-asl" version="1.9.2"/> - <dependency groupId="org.codehaus.jackson" artifactId="jackson-mapper-asl" version="1.9.2"/> + <dependency groupId="com.fasterxml.jackson.core" artifactId="jackson-core" version="2.12.5"/> + <dependency groupId="com.fasterxml.jackson.core" artifactId="jackson-databind" version="2.12.5"/> + <dependency groupId="com.fasterxml.jackson.core" artifactId="jackson-annotations" version="2.12.5"/> <dependency groupId="com.googlecode.json-simple" artifactId="json-simple" version="1.1"/> <dependency groupId="com.boundary" artifactId="high-scale-lib" version="1.0.6"/> <dependency groupId="com.github.jbellis" artifactId="jamm" version="${jamm.version}"/> diff --cc test/unit/org/apache/cassandra/config/DatabaseDescriptorRefTest.java index 791212d,0000000..83c6bea mode 100644,000000..100644 --- a/test/unit/org/apache/cassandra/config/DatabaseDescriptorRefTest.java +++ b/test/unit/org/apache/cassandra/config/DatabaseDescriptorRefTest.java @@@ -1,285 -1,0 +1,285 @@@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.cassandra.config; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; +import java.lang.reflect.Method; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import org.junit.Test; + +import org.apache.cassandra.utils.Pair; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +/** + * Verifies that {@link DatabaseDescriptor#clientInitialization()} } and a couple of <i>apply</i> methods + * do not somehow lazily initialize any unwanted part of Cassandra like schema, commit log or start + * unexpected threads. + * + * {@link DatabaseDescriptor#toolInitialization()} is tested via unit tests extending + * {@link org.apache.cassandra.tools.ToolsTester}. + */ +public class DatabaseDescriptorRefTest +{ + static final String[] validClasses = { + "org.apache.cassandra.auth.IInternodeAuthenticator", + "org.apache.cassandra.auth.IAuthenticator", + "org.apache.cassandra.auth.IAuthorizer", + "org.apache.cassandra.auth.IRoleManager", + "org.apache.cassandra.config.DatabaseDescriptor", + "org.apache.cassandra.config.ConfigurationLoader", + "org.apache.cassandra.config.Config", + "org.apache.cassandra.config.Config$1", + "org.apache.cassandra.config.Config$RequestSchedulerId", + "org.apache.cassandra.config.Config$CommitLogSync", + "org.apache.cassandra.config.Config$DiskAccessMode", + "org.apache.cassandra.config.Config$DiskFailurePolicy", + "org.apache.cassandra.config.Config$CommitFailurePolicy", + "org.apache.cassandra.config.Config$DiskOptimizationStrategy", + "org.apache.cassandra.config.Config$InternodeCompression", + "org.apache.cassandra.config.Config$MemtableAllocationType", + "org.apache.cassandra.config.Config$UserFunctionTimeoutPolicy", + "org.apache.cassandra.config.RequestSchedulerOptions", + "org.apache.cassandra.config.ParameterizedClass", + "org.apache.cassandra.config.EncryptionOptions", + "org.apache.cassandra.config.EncryptionOptions$ClientEncryptionOptions", + "org.apache.cassandra.config.EncryptionOptions$ServerEncryptionOptions", + "org.apache.cassandra.config.EncryptionOptions$ServerEncryptionOptions$InternodeEncryption", + "org.apache.cassandra.config.ReplicaFilteringProtectionOptions", + "org.apache.cassandra.config.YamlConfigurationLoader", + "org.apache.cassandra.config.YamlConfigurationLoader$PropertiesChecker", + "org.apache.cassandra.config.YamlConfigurationLoader$PropertiesChecker$1", + "org.apache.cassandra.config.YamlConfigurationLoader$CustomConstructor", + "org.apache.cassandra.config.TransparentDataEncryptionOptions", + "org.apache.cassandra.dht.IPartitioner", - "org.apache.cassandra.distributed.impl.InstanceClassLoader", ++ "org.apache.cassandra.distributed.shared.InstanceClassLoader", + "org.apache.cassandra.distributed.impl.InstanceConfig", + "org.apache.cassandra.distributed.impl.InvokableInstance", + "org.apache.cassandra.distributed.impl.InvokableInstance$CallableNoExcept", + "org.apache.cassandra.distributed.impl.InvokableInstance$InstanceFunction", + "org.apache.cassandra.distributed.impl.InvokableInstance$SerializableBiConsumer", + "org.apache.cassandra.distributed.impl.InvokableInstance$SerializableBiFunction", + "org.apache.cassandra.distributed.impl.InvokableInstance$SerializableCallable", + "org.apache.cassandra.distributed.impl.InvokableInstance$SerializableConsumer", + "org.apache.cassandra.distributed.impl.InvokableInstance$SerializableFunction", + "org.apache.cassandra.distributed.impl.InvokableInstance$SerializableRunnable", + "org.apache.cassandra.distributed.impl.InvokableInstance$SerializableTriFunction", + "org.apache.cassandra.distributed.impl.InvokableInstance$TriFunction", + "org.apache.cassandra.distributed.impl.Message", + "org.apache.cassandra.exceptions.ConfigurationException", + "org.apache.cassandra.exceptions.RequestValidationException", + "org.apache.cassandra.exceptions.CassandraException", + "org.apache.cassandra.exceptions.TransportException", + "org.apache.cassandra.locator.IEndpointSnitch", + "org.apache.cassandra.io.FSWriteError", + "org.apache.cassandra.io.FSError", + "org.apache.cassandra.io.compress.ICompressor", + "org.apache.cassandra.io.compress.LZ4Compressor", + "org.apache.cassandra.io.sstable.metadata.MetadataType", + "org.apache.cassandra.io.util.BufferedDataOutputStreamPlus", + "org.apache.cassandra.io.util.DataOutputBuffer", + "org.apache.cassandra.io.util.DataOutputBufferFixed", + "org.apache.cassandra.io.util.DataOutputStreamPlus", + "org.apache.cassandra.io.util.DataOutputPlus", + "org.apache.cassandra.io.util.DiskOptimizationStrategy", + "org.apache.cassandra.io.util.SpinningDiskOptimizationStrategy", + "org.apache.cassandra.locator.SimpleSeedProvider", + "org.apache.cassandra.locator.SeedProvider", + "org.apache.cassandra.net.BackPressureStrategy", + "org.apache.cassandra.scheduler.IRequestScheduler", + "org.apache.cassandra.security.EncryptionContext", + "org.apache.cassandra.service.CacheService$CacheType", + "org.apache.cassandra.utils.FBUtilities", + "org.apache.cassandra.utils.FBUtilities$1", + "org.apache.cassandra.utils.CloseableIterator", + "org.apache.cassandra.utils.Pair", + "org.apache.cassandra.ConsoleAppender", + "org.apache.cassandra.ConsoleAppender$1", + "org.apache.cassandra.LogbackStatusListener", + "org.apache.cassandra.LogbackStatusListener$ToLoggerOutputStream", + "org.apache.cassandra.LogbackStatusListener$WrappedPrintStream", + "org.apache.cassandra.TeeingAppender", + // generated classes + "org.apache.cassandra.config.ConfigBeanInfo", + "org.apache.cassandra.config.ConfigCustomizer", + "org.apache.cassandra.config.EncryptionOptionsBeanInfo", + "org.apache.cassandra.config.EncryptionOptionsCustomizer", + "org.apache.cassandra.config.EncryptionOptions$ServerEncryptionOptionsBeanInfo", + "org.apache.cassandra.config.EncryptionOptions$ServerEncryptionOptionsCustomizer", + "org.apache.cassandra.ConsoleAppenderBeanInfo", + "org.apache.cassandra.ConsoleAppenderCustomizer", + }; + + static final Set<String> checkedClasses = new HashSet<>(Arrays.asList(validClasses)); + + @Test + @SuppressWarnings({"DynamicRegexReplaceableByCompiledPattern", "UseOfSystemOutOrSystemErr"}) + public void testDatabaseDescriptorRef() throws Throwable + { + PrintStream out = System.out; + PrintStream err = System.err; + + ThreadMXBean threads = ManagementFactory.getThreadMXBean(); + int threadCount = threads.getThreadCount(); + List<Long> existingThreadIDs = Arrays.stream(threads.getAllThreadIds()).boxed().collect(Collectors.toList()); + + ClassLoader delegate = Thread.currentThread().getContextClassLoader(); + + List<Pair<String, Exception>> violations = Collections.synchronizedList(new ArrayList<>()); + + ClassLoader cl = new ClassLoader(null) + { + final Map<String, Class<?>> classMap = new HashMap<>(); + + public URL getResource(String name) + { + return delegate.getResource(name); + } + + public InputStream getResourceAsStream(String name) + { + return delegate.getResourceAsStream(name); + } + + protected Class<?> findClass(String name) throws ClassNotFoundException + { + Class<?> cls = classMap.get(name); + if (cls != null) + return cls; + + if (name.startsWith("org.apache.cassandra.")) + { + // out.println(name); + + if (!checkedClasses.contains(name)) + violations.add(Pair.create(name, new Exception())); + } + + URL url = delegate.getResource(name.replace('.', '/') + ".class"); + if (url == null) + throw new ClassNotFoundException(name); + try (InputStream in = url.openConnection().getInputStream()) + { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + int c; + while ((c = in.read()) != -1) + os.write(c); + byte[] data = os.toByteArray(); + cls = defineClass(name, data, 0, data.length); + classMap.put(name, cls); + return cls; + } + catch (IOException e) + { + throw new ClassNotFoundException(name, e); + } + } + }; + + Thread.currentThread().setContextClassLoader(cl); + + assertEquals("thread started", threadCount, threads.getThreadCount()); + + Class<?> databaseDescriptorClass = Class.forName("org.apache.cassandra.config.DatabaseDescriptor", true, cl); + + // During DatabaseDescriptor instantiation some threads are spawned. We need to take them into account in + // threadCount variable, otherwise they will be considered as new threads spawned by methods below. There is a + // trick: in case of multiple runs of this test in the same JVM the number of such threads will be multiplied by + // the number of runs. That's because DatabaseDescriptor is instantiated via a different class loader. So in + // order to keep calculation logic correct, we ignore existing threads that were spawned during the previous + // runs and change threadCount variable for the new threads only (if they have some specific names). + for (ThreadInfo threadInfo : threads.getThreadInfo(threads.getAllThreadIds())) + { + // All existing threads have been already taken into account in threadCount variable, so we ignore them + if (existingThreadIDs.contains(threadInfo.getThreadId())) + continue; + // Logback AsyncAppender thread needs to be taken into account + if (threadInfo.getThreadName().equals("AsyncAppender-Worker-ASYNC")) + threadCount++; + // Logback basic threads need to be taken into account + if (threadInfo.getThreadName().matches("logback-\\d+")) + threadCount++; + // Dynamic Attach thread needs to be taken into account, generally it is spawned by IDE + if (threadInfo.getThreadName().equals("Attach Listener")) + threadCount++; + } + + for (String methodName : new String[]{ + "clientInitialization", + "applyAddressConfig", + "applyThriftHSHA", + "applyTokensConfig", + // no seed provider in default configuration for clients + // "applySeedProvider", + // definitely not safe for clients - implicitly instantiates schema + // "applyPartitioner", + // definitely not safe for clients - implicitly instantiates StorageService + // "applySnitch", + "applyEncryptionContext", + // starts "REQUEST-SCHEDULER" thread via RoundRobinScheduler + // "applyRequestScheduler", + }) + { + Method method = databaseDescriptorClass.getDeclaredMethod(methodName); + method.invoke(null); + + if (threadCount != threads.getThreadCount()) + { + for (ThreadInfo threadInfo : threads.getThreadInfo(threads.getAllThreadIds())) + out.println("Thread #" + threadInfo.getThreadId() + ": " + threadInfo.getThreadName()); + assertEquals("thread started in " + methodName, threadCount, ManagementFactory.getThreadMXBean().getThreadCount()); + } + + checkViolations(err, violations); + } + } + + private void checkViolations(PrintStream err, List<Pair<String, Exception>> violations) + { + if (!violations.isEmpty()) + { + for (Pair<String, Exception> violation : new ArrayList<>(violations)) + { + err.println(); + err.println(); + err.println("VIOLATION: " + violation.left); + violation.right.printStackTrace(err); + } + + fail(); + } + } +} diff --cc test/unit/org/apache/cassandra/cql3/validation/operations/AggregationTest.java index e4b16ef,6de7052..b8ef4d3 --- a/test/unit/org/apache/cassandra/cql3/validation/operations/AggregationTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/operations/AggregationTest.java @@@ -54,12 -55,12 +55,13 @@@ import org.apache.cassandra.exceptions. import org.apache.cassandra.exceptions.InvalidRequestException; import org.apache.cassandra.schema.KeyspaceMetadata; import org.apache.cassandra.service.ClientState; -import org.apache.cassandra.transport.Server; +import org.apache.cassandra.transport.Event; import org.apache.cassandra.transport.Event.SchemaChange.Change; import org.apache.cassandra.transport.Event.SchemaChange.Target; +import org.apache.cassandra.transport.ProtocolVersion; import org.apache.cassandra.transport.messages.ResultMessage; + import static ch.qos.logback.core.CoreConstants.RECONFIGURE_ON_CHANGE_TASK; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org For additional commands, e-mail: commits-h...@cassandra.apache.org