diff --git a/.github/workflows/VeniceCI-CompatibilityTests.yml b/.github/workflows/VeniceCI-CompatibilityTests.yml index 3b8a3ff64db..80dcb4fc491 100644 --- a/.github/workflows/VeniceCI-CompatibilityTests.yml +++ b/.github/workflows/VeniceCI-CompatibilityTests.yml @@ -55,27 +55,16 @@ jobs: jdk: [8, 11, 17] runs-on: ubuntu-latest timeout-minutes: 120 - outputs: - alpini_touched: ${{ steps.check_alpini_files_changed.outputs.alpini }} steps: - uses: actions/checkout@v4 with: # Checkout as many commits as needed for the diff fetch-depth: 2 - - name: Check if files have changed - uses: dorny/paths-filter@v3 - id: check_alpini_files_changed - with: - filters: | - alpini: - - 'internal/alpini/**' - uses: actions/checkout@v4 - if: steps.check_alpini_files_changed.outputs.alpini == 'true' with: fetch-depth: 0 - name: Set up JDK uses: actions/setup-java@v4 - if: steps.check_alpini_files_changed.outputs.alpini == 'true' with: java-version: ${{ matrix.jdk }} distribution: 'temurin' @@ -92,19 +81,16 @@ jobs: # echo "java.security file after modifications: " # cat "$JAVA_HOME/conf/security/java.security" - shell: bash - if: steps.check_alpini_files_changed.outputs.alpini == 'true' run: | git remote set-head origin --auto git remote add upstream https://github.com/linkedin/venice git fetch upstream - name: Setup Gradle - if: steps.check_alpini_files_changed.outputs.alpini == 'true' uses: gradle/actions/setup-gradle@v4 - name: Run alpini unit tests - if: steps.check_alpini_files_changed.outputs.alpini == 'true' run: ./gradlew --continue --no-daemon -DmaxParallelForks=1 alpiniUnitTest - name: Package Build Artifacts - if: steps.check_alpini_files_changed.outputs.alpini == 'true' && (success() || failure()) + if: (success() || failure()) shell: bash run: | mkdir ${{ github.job }}-artifacts @@ -112,81 +98,10 @@ jobs: rsync -R --files-from=artifacts.list . ${{ github.job }}-artifacts tar -zcvf ${{ github.job }}-jdk${{ matrix.jdk }}-logs.tar.gz ${{ github.job }}-artifacts - name: Upload Build Artifacts - if: steps.check_alpini_files_changed.outputs.alpini == 'true' && (success() || failure()) + if: (success() || failure()) uses: actions/upload-artifact@v4 with: - name: ${{ github.job }} - path: ${{ github.job }}-jdk${{ matrix.jdk }}-logs.tar.gz - retention-days: 30 - - AlpiniFunctionalTests: - strategy: - fail-fast: false - matrix: - jdk: [17] - runs-on: ubuntu-latest - timeout-minutes: 120 - outputs: - alpini_touched: ${{ steps.check_alpini_files_changed.outputs.alpini }} - steps: - - uses: actions/checkout@v4 - with: - # Checkout as many commits as needed for the diff - fetch-depth: 2 - - name: Check if files have changed - uses: dorny/paths-filter@v3 - id: check_alpini_files_changed - with: - filters: | - alpini: - - 'internal/alpini/**' - - uses: actions/checkout@v4 - if: steps.check_alpini_files_changed.outputs.alpini == 'true' - with: - fetch-depth: 0 - - name: Set up JDK - uses: actions/setup-java@v4 - if: steps.check_alpini_files_changed.outputs.alpini == 'true' - with: - java-version: ${{ matrix.jdk }} - distribution: 'temurin' - cache: 'gradle' - # - name: Allow Deprecated TLS versions for Alpini tests - # run: | - # echo "java.security file before modifications: " - # cat "$JAVA_HOME/conf/security/java.security" - - # # This is possibly flaky but - # sed -i 's/TLSv1, //g' "$JAVA_HOME/conf/security/java.security" # Allow TLSv1 - # sed -i 's/TLSv1.1, //g' "$JAVA_HOME/conf/security/java.security" # Allow TLSv1.1 - - # echo "java.security file after modifications: " - # cat "$JAVA_HOME/conf/security/java.security" - - shell: bash - if: steps.check_alpini_files_changed.outputs.alpini == 'true' - run: | - git remote set-head origin --auto - git remote add upstream https://github.com/linkedin/venice - git fetch upstream - - name: Setup Gradle - if: steps.check_alpini_files_changed.outputs.alpini == 'true' - uses: gradle/actions/setup-gradle@v4 - - name: Run alpini functional tests - if: steps.check_alpini_files_changed.outputs.alpini == 'true' - run: ./gradlew --continue --no-daemon -DmaxParallelForks=1 alpiniFunctionalTest - - name: Package Build Artifacts - if: steps.check_alpini_files_changed.outputs.alpini == 'true' && (success() || failure()) - shell: bash - run: | - mkdir ${{ github.job }}-artifacts - find . -path "**/build/reports/*" -or -path "**/build/test-results/*" > artifacts.list - rsync -R --files-from=artifacts.list . ${{ github.job }}-artifacts - tar -zcvf ${{ github.job }}-jdk${{ matrix.jdk }}-logs.tar.gz ${{ github.job }}-artifacts - - name: Upload Build Artifacts - if: steps.check_alpini_files_changed.outputs.alpini == 'true' && (success() || failure()) - uses: actions/upload-artifact@v4 - with: - name: ${{ github.job }} + name: ${{ github.job }}-jdk${{ matrix.jdk }} path: ${{ github.job }}-jdk${{ matrix.jdk }}-logs.tar.gz retention-days: 30 @@ -257,7 +172,7 @@ jobs: strategy: fail-fast: false runs-on: ubuntu-latest - needs: [AvroCompatibilityTests, AlpiniUnitTests, AlpiniFunctionalTests, PulsarVeniceIntegrationTests] + needs: [AvroCompatibilityTests, AlpiniUnitTests, PulsarVeniceIntegrationTests] timeout-minutes: 120 steps: - name: AllIsWell diff --git a/build.gradle b/build.gradle index 1de60db243c..b6e02f175de 100644 --- a/build.gradle +++ b/build.gradle @@ -387,7 +387,6 @@ subprojects { def ALPINI_TEST_FILTER = 'com.linkedin.alpini.*' def ALPINI_NETTY_TEST_FILTER = 'io.netty.*' def ALPINI_UNIT_TEST_TASK_NAME = 'alpiniUnitTest' - def ALPINI_FUNCTIONAL_TEST_TASK_NAME = 'alpiniFunctionalTest' tasks.withType(Test) { mustRunAfter tasks.withType(SpotBugsTask) @@ -419,7 +418,7 @@ subprojects { println "jvmArgs=$allJvmArgs" } - if (name != ALPINI_UNIT_TEST_TASK_NAME && name != ALPINI_FUNCTIONAL_TEST_TASK_NAME) { + if (name != ALPINI_UNIT_TEST_TASK_NAME) { filter { excludeTestsMatching ALPINI_TEST_FILTER excludeTestsMatching ALPINI_NETTY_TEST_FILTER @@ -564,17 +563,6 @@ subprojects { } } - task "$ALPINI_FUNCTIONAL_TEST_TASK_NAME"(type: Test) { - useTestNG() { - includeGroups 'functional' - } - filter { - includeTestsMatching ALPINI_TEST_FILTER - includeTestsMatching ALPINI_NETTY_TEST_FILTER - failOnNoMatchingTests = false - } - } - tasks.withType(Jar) { zip64 = true duplicatesStrategy = DuplicatesStrategy.FAIL diff --git a/gradle/spotbugs/exclude.xml b/gradle/spotbugs/exclude.xml index d97431bb029..3d5a8dbf544 100644 --- a/gradle/spotbugs/exclude.xml +++ b/gradle/spotbugs/exclude.xml @@ -258,6 +258,12 @@ + + + + + + diff --git a/internal/alpini/common/alpini-common-base/build.gradle b/internal/alpini/common/alpini-common-base/build.gradle index 32a9bbfe766..8a6f421fbda 100644 --- a/internal/alpini/common/alpini-common-base/build.gradle +++ b/internal/alpini/common/alpini-common-base/build.gradle @@ -4,7 +4,6 @@ configurations { dependencies { testImplementation libraries.testng - implementation project(':internal:alpini:common:alpini-common-const') implementation libraries.jacksonDatabind implementation libraries.jsr305 implementation libraries.log4j2api diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/misc/CollectionUtil.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/misc/CollectionUtil.java index 22edad2f3fc..ea9ecd62e7d 100644 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/misc/CollectionUtil.java +++ b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/misc/CollectionUtil.java @@ -1,30 +1,19 @@ package com.linkedin.alpini.base.misc; -import java.util.AbstractMap; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; -import java.util.IdentityHashMap; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Set; import java.util.Spliterator; import java.util.Spliterators; -import java.util.concurrent.ConcurrentMap; -import java.util.function.BiConsumer; -import java.util.function.BinaryOperator; import java.util.function.Function; -import java.util.function.Supplier; -import java.util.stream.Collector; import java.util.stream.Stream; import java.util.stream.StreamSupport; -import javax.annotation.Nonnull; /** @@ -37,26 +26,14 @@ public static boolean isNotEmpty(Collection collection) { return collection != null && !collection.isEmpty(); } - public static Set setOf(T value) { - return Collections.singleton(value); - } - @SafeVarargs public static Set setOf(T... values) { if (values == null || values.length == 0) { return Collections.emptySet(); } else if (values.length == 1) { - return setOf(values[0]); - } else { - return setOf(Arrays.asList(values)); - } - } - - public static Set setOf(Collection values) { - if (values == null || values.isEmpty()) { - return Collections.emptySet(); + return Collections.singleton(values[0]); } else { - return Collections.unmodifiableSet(new HashSet<>(values)); + return Collections.unmodifiableSet(new HashSet<>(Arrays.asList(values))); } } @@ -87,329 +64,12 @@ public static Map mapOf(K key, V value) { return Collections.singletonMap(key, value); } - @SafeVarargs - public static Map mapOfEntries(ImmutableMapEntry... values) { - if (values == null || values.length == 0) { - return Collections.emptyMap(); - } else if (values.length == 1) { - return mapOf(values[0].getKey(), values[0].getValue()); - } else { - return mapOfEntries(setOf(values)); - } - } - - private static Map mapOfEntries(Set> entries) { - return Collections.unmodifiableMap(new HashMap<>(new AbstractMap() { - @Override - @Nonnull - public Set> entrySet() { - return entries; - } - })); - } - - public static Map mapOf(K key1, V value1, K key2, V value2) { - return mapOfEntries(ImmutableMapEntry.make(key1, value1), ImmutableMapEntry.make(key2, value2)); - } - - public static Map mapOf(K key1, V value1, K key2, V value2, K key3, V value3) { - return mapOfEntries( - ImmutableMapEntry.make(key1, value1), - ImmutableMapEntry.make(key2, value2), - ImmutableMapEntry.make(key3, value3)); - } - - public static Map mapOf(K key1, V value1, K key2, V value2, K key3, V value3, K key4, V value4) { - return mapOfEntries( - ImmutableMapEntry.make(key1, value1), - ImmutableMapEntry.make(key2, value2), - ImmutableMapEntry.make(key3, value3), - ImmutableMapEntry.make(key4, value4)); - } - - public static Collector>> batchOf(int size) { - return new BatchCollector<>(size); - } - - private static class BatchCollector implements Collector>, List>> { - private final int _batchSize; - - private BatchCollector(int batchSize) { - Preconditions.checkState(batchSize > 0); - _batchSize = batchSize; - } - - @Override - public Supplier>> supplier() { - return LinkedList::new; - } - - @Override - public BiConsumer>, T> accumulator() { - return this::accumulate; - } - - private void accumulate(LinkedList> list, T element) { - if (list.isEmpty() || list.getLast().size() >= _batchSize) { - list.addLast(new ArrayList<>(_batchSize)); - } - list.getLast().add(Objects.requireNonNull(element)); - } - - @Override - public BinaryOperator>> combiner() { - return this::combine; - } - - private LinkedList> combine(LinkedList> a, LinkedList> b) { - LinkedList> result = new LinkedList<>(); - result.addAll(a); - result.addAll(b); - return result; - } - - @Override - public Function>, List>> finisher() { - return builders -> builders; - } - - @Override - public Set characteristics() { - return Collections.singleton(Characteristics.IDENTITY_FINISH); - } - } - - public static SetBuilder setBuilder() { - return new SetBuilder<>(); - } - - public static ListBuilder listBuilder() { - return new ListBuilder<>(); - } - - public static MapBuilder mapBuilder() { - return new MapBuilder<>(); - } - - private static class CollectionBuilder> { - protected LinkedList _list = new LinkedList<>(); - - private CollectionBuilder() { - } - - @SuppressWarnings("unchecked") - protected B self() { - return (B) this; - } - - public B add(@Nonnull T value) { - _list.add(Objects.requireNonNull(value)); - return self(); - } - - @SafeVarargs - public final B add(T... values) { - return addAll(Arrays.asList(values)); - } - - public B addAll(Collection values) { - _list.addAll(values); - return self(); - } - - public B addAll(Iterator values) { - values.forEachRemaining(this::add); - return self(); - } - } - - public static final class SetBuilder extends CollectionBuilder> { - private SetBuilder() { - } - - public Set build() { - return setOf(_list); - } - } - - public static final class ListBuilder extends CollectionBuilder> { - private ListBuilder() { - } - - public List build() { - return listOf(_list); - } - } - - public static final class MapBuilder extends CollectionBuilder, MapBuilder> { - private MapBuilder() { - } - - public MapBuilder put(K key, V value) { - return super.add(ImmutableMapEntry.make(key, value)); - } - - public MapBuilder putAll(Map values) { - return super.addAll(values.entrySet().stream().map(ImmutableMapEntry::make).iterator()); - } - - @SuppressWarnings("unchecked") - public Map build() { - List> list = (List>) (List) this._list; - return mapOfEntries(setOf(list)); - } - } - - @SuppressWarnings("unchecked") - public static Stream stream(Spliterator spliterator, boolean parallel) { - return (Stream) StreamSupport.stream(spliterator, parallel); - } - - public static Stream stream(Iterable iterable) { - return stream(iterable.spliterator(), false); - } - public static Stream stream(Iterator iterator) { - return stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED), false); - } - - @SafeVarargs - public static Stream stream(T... source) { - return source != null && source.length > 0 ? Arrays.stream(source) : Stream.empty(); - } - - @SuppressWarnings("unchecked") - @SafeVarargs - public static Iterable concat(Iterable... sources) { - return sources != null && sources.length > 0 - ? () -> stream(sources).flatMap((Function, Stream>) CollectionUtil::stream).iterator() - : Collections.emptySet(); - } - - @SafeVarargs - public static Iterator concat(Iterator... sources) { - return sources != null && sources.length > 0 - ? stream(sources).flatMap(CollectionUtil::stream).iterator() - : Collections.emptyIterator(); - } - - @SafeVarargs - public static Object deepToStringObject(T... array) { - return new Object() { - public final String toString() { - return Arrays.deepToString(array); - } - }; + return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED), false); } public static T applyFactoryModifiers(T pipelineFactory, List> modifiers) { return modifiers.stream() .collect(() -> pipelineFactory, (factory, modifier) -> modifier.apply(factory), (ignore1, ignore2) -> {}); } - - /** - * ComputeIfAbsent on a ConcurrentHashMap should be a very light weight operation if the key already exists. - * Due to a bug in Java 8 (https://bugs.openjdk.java.net/browse/JDK-8161372), a lock is acquired regardless. - * This Util rewrites the computeIfAbsent as get and putIfAbsent to avoid the lock if the key - * already exists. - * - * @author Abhishek Andhavarapu <aandhava@linkedin.com> - */ - public static V computeIfAbsent( - @Nonnull ConcurrentMap map, - @Nonnull K key, - @Nonnull Function mappingFunction) { - V value = map.get(key); - if (value == null) { - value = mappingFunction.apply(key); - if (value != null) { - V existing = map.putIfAbsent(key, value); - if (existing != null) { - value = existing; - } - } - } - return value; - } - - /** - * Accepts a mapping function to compute the value, and only register when the old value is not set. - */ - - public static V computeIfAbsent( - @Nonnull ConcurrentMap map, - @Nonnull K key, - @Nonnull Function mappingFunction, - BiConsumer register) { - V value = map.get(key); - if (value == null) { - value = mappingFunction.apply(key); - if (value != null) { - // Returns the old value - V existing = map.putIfAbsent(key, value); - if (existing != null) { - value = existing; - } else { - // Run the register only when previous value is empty. - register.accept(key, value); - } - } - } - return value; - } - - /** - * Clones an array with arbitrary levels of nesting. - */ - public static V[] deepCloneArray(@Nonnull V[] array) { - // noinspection rawtypes - return deepCloneArray(array, new IdentityHashMap()); - } - - @SuppressWarnings("rawtypes") - private static V[] deepCloneArray(@Nonnull V[] array, IdentityHashMap cloneMapRaw) { - @SuppressWarnings("unchecked") - IdentityHashMap cloneMap = (IdentityHashMap) cloneMapRaw; - V[] clone = cloneMap.get(array); - if (clone == null) { - clone = array.clone(); - cloneMap.put(array, clone); - for (int i = clone.length - 1; i >= 0; i--) { - V value = clone[i]; - if (value == null || !value.getClass().isArray()) { - continue; - } - if (value.getClass().getComponentType().isPrimitive()) { - // noinspection unchecked - clone[i] = (V) cloneMapRaw.computeIfAbsent(value, v -> { - switch (v.getClass().getComponentType().getSimpleName()) { - case "boolean": - return ((boolean[]) v).clone(); - case "byte": - return ((byte[]) v).clone(); - case "short": - return ((short[]) v).clone(); - case "char": - return ((char[]) v).clone(); - case "int": - return ((int[]) v).clone(); - case "float": - return ((float[]) v).clone(); - case "long": - return ((long[]) v).clone(); - case "double": - return ((double[]) v).clone(); - default: - assert false; - return null; - } - }); - continue; - } - // noinspection unchecked - clone[i] = (V) deepCloneArray((Object[]) value, cloneMapRaw); - } - } - return clone; - } } diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/misc/CounterQueue.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/misc/CounterQueue.java deleted file mode 100644 index cad4ae8658a..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/misc/CounterQueue.java +++ /dev/null @@ -1,132 +0,0 @@ -package com.linkedin.alpini.base.misc; - -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.atomic.AtomicReferenceArray; -import java.util.concurrent.atomic.LongAdder; -import java.util.function.Supplier; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** - * A queue implemented with a circular buffer of AtomicReferences - * Example of using: - * 1. Initializing a SlidingWindow: RetryCountSlidingWindow w = new RetryCountSlidingWindow(500, _windowLen, scheduler); - * 2. Inside a thread, usually an io worker to get a queue: CounterQueue q = w.getQueue(); - * 3. increase the count: q.increaseCount(isRetry); - * - * For more examples, please refer to the class of TestRetryCountSlidingWindow - * - * @author solu - * Date: 4/26/21 - */ -public class CounterQueue { - private static final Logger LOG = LogManager.getLogger(CounterQueue.class); - - private final LongAdder _totalCount = new LongAdder(); - private final LongAdder _totalRetryCount = new LongAdder(); - - public long getTotalCount() { - return _totalCount.longValue(); - } - - public long getTotalRetryCount() { - return _totalRetryCount.longValue(); - } - - private final Supplier _retryCounterSupplier; - - private final AtomicReferenceArray _queue; - // the _index would be accessed by more than one thread. Although volatile would not work with ++, only increaseCount - // would change its value. For other thread such as oldCounter cleaning thread, even if it sees an outdated value, it - // won't be a big deal because in method removeOldCounters: - // 1. we use another variable to read from the index: i = _index; - // 2. we use mod again on i to make sure the value is right: i %= _queueLength; - private volatile int _index = 0; - - /** - * Non-thread safe method but it would only be called by a single thread. So the increment of _index does not have - * to be protected by AtomicReference. A volatile suffices. - * @param isRetry - */ - public void increaseCount(boolean isRetry) { - - // getting an absolute timestamp ticking from 01/01/1970 in second. - long currentSecond = RetryCounter.getCurrentSecond(); - // finding the right slot - // Usually the _index would point to the latest timeslot. However, it may be way behind the current second if the - // thread has not gotten any chance to either serve a request or get to be scheduled to run. - T rc = _queue.get(_index); - int queueLength = _queue.length(); - while (rc != null && rc.getTimestamp() < currentSecond) { - if (currentSecond - rc.getTimestamp() > queueLength) { - removeFromTotal(_index, currentSecond, rc); - } - - _index = (_index + 1) % queueLength; - rc = _queue.get(_index); - } - - // if we are out here it is either we got the right Counter or we need to initialize a new one - // in case there is a recurring thread that may be resetting the retryCounter, - // we need to re-examine the condition. - while (rc == null) { - rc = _retryCounterSupplier.get(); - if (!_queue.compareAndSet(_index, null, rc)) { - rc = _queue.get(_index); - } - } - rc.increment(isRetry); - - if (isRetry) { - _totalRetryCount.increment(); - } - _totalCount.increment(); - } - - private void removeFromTotal(int i, long currentSecond, T rc) { - // if some one already changed the value to null, meaning that the removal from total has already been done. - // So we don't need to do anything. - boolean iWouldbeTheOneToRemoveIt = _queue.compareAndSet(i, rc, null); - if (iWouldbeTheOneToRemoveIt) { - LOG.debug( - "Removing counter {} because current - its timestamp is {} > {}", - rc, - currentSecond - rc.getTimestamp(), - _queue.length()); - _totalCount.add(-rc.getTotalCount()); - _totalRetryCount.add(-rc.getRetryCount()); - } - } - - void removeOldCounters() { - long currentSecond = RetryCounter.getCurrentSecond(); - // starting from currentIndex + 1. This is a circular buffer. So the most possible outdated counter is - // right after the currentIndex. - int queueLength = _queue.length(); - for (int i = _index + 1; i < _index + queueLength; i++) { - int actualIndex = i % queueLength; - T rc = _queue.get(actualIndex); - if (rc != null && currentSecond - rc.getTimestamp() > queueLength) { - removeFromTotal(actualIndex, currentSecond, rc); - } else { - // we can safely break as we removed all the outdated counters. - // but even if we dont' break here, it is not big deal. - break; - } - } - } - - /** - * Initialize the queue and register itself to the queue map. - * @param queueLength - * @param retryCounterSupplier - */ - public CounterQueue(int queueLength, Map> queueMap, Supplier retryCounterSupplier) { - _queue = new AtomicReferenceArray<>(queueLength); - queueMap.put(Thread.currentThread().getName(), this); - this._retryCounterSupplier = Objects.requireNonNull(retryCounterSupplier, "Null retryCounterSupplier"); - } - -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/misc/ExceptionUtil.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/misc/ExceptionUtil.java index 0cec53b4bb4..d302a972445 100644 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/misc/ExceptionUtil.java +++ b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/misc/ExceptionUtil.java @@ -295,30 +295,4 @@ public static T checkException(@Nonnull Callable callable, @Nonnull Strin } private static final StackTraceElement[] EMPTY_STACK_TRACE_ELEMENTS = new StackTraceElement[0]; - - public static T throwException(Throwable cause) { - if (_throwMethod == null) { - try { - // noinspection unchecked - _throwMethod = Class.forName("com.linkedin.alpini.base.misc.Netty4ThrowException") - .asSubclass(ExceptionThrower.class) - .newInstance(); - } catch (Exception ex) { - _throwMethod = ExceptionUtil::throw0; - } - } - _throwMethod.throwException(cause); - return null; - } - - private static void throw0(Throwable exception) throws T { - // noinspection unchecked - throw (T) exception; - } - - private static ExceptionThrower _throwMethod; - - public interface ExceptionThrower { - void throwException(Throwable exception); - } } diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/misc/Joiner.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/misc/Joiner.java deleted file mode 100644 index 8f37c37a548..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/misc/Joiner.java +++ /dev/null @@ -1,196 +0,0 @@ -package com.linkedin.alpini.base.misc; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Iterator; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.stream.Stream; -import javax.annotation.CheckReturnValue; -import javax.annotation.Nonnull; - - -/** - * A replacement to the use of the Google collections class of the same name, - * @author Antony T Curtis {@literal } - */ -public class Joiner { - private static final Predicate SKIP_NULLS = o -> o != null; - private static final Function, Stream> DEFAULT_STREAM = s -> s; - private static final Function DEFAULT_MAPPER = - o -> o instanceof CharSequence ? (CharSequence) o : o.toString(); - - private final String _delimiter; - private final Function _mapper; - private final Function, Stream> _stream; - - public Joiner(@Nonnull String delimiter) { - this(delimiter, DEFAULT_MAPPER, DEFAULT_STREAM); - } - - private Joiner( - @Nonnull String delimiter, - @Nonnull Function mapper, - @Nonnull Function, Stream> stream) { - _delimiter = delimiter; - _mapper = mapper; - _stream = stream; - } - - @CheckReturnValue - public static @Nonnull Joiner on(char delimiter) { - return on(Character.toString(delimiter)); - } - - @CheckReturnValue - public static @Nonnull Joiner on(@Nonnull String delimiter) { - return new Joiner(delimiter); - } - - @Nonnull - @SuppressWarnings("unchecked") - private Stream streamOf(@Nonnull Stream stream) { - return (Stream) _stream.apply(stream); - } - - public @Nonnull Stream streamOf(@Nonnull Iterable iterable) { - return streamOf(CollectionUtil.stream(iterable)); - } - - public @Nonnull Stream streamOf(@Nonnull Iterator iterator) { - return streamOf(CollectionUtil.stream(iterator)); - } - - private @Nonnull String joinStream(@Nonnull Stream stream) { - // Manual implementation to preserve existing behaviour because the java.utils.StringJoiner may change - // otherwise TestJoiner.testDontConvertCharSequenceToString test fails. - CharSequence[] array = stream.map(_mapper).toArray(CharSequence[]::new); - if (array.length == 0) { - return ""; - } else if (array.length == 1) { - return array[0].toString(); - } else { - StringBuilder sb = new StringBuilder(); - sb.append(array[0]); - for (int i = 1; i < array.length; i++) { - sb.append(_delimiter).append(array[i]); - } - return sb.toString(); - } - } - - private @Nonnull B appendStream(@Nonnull B sb, @Nonnull Stream stream) throws IOException { - Iterator it = stream.map(_mapper).iterator(); - if (it.hasNext()) { - sb.append(it.next()); - while (it.hasNext()) { - sb.append(_delimiter).append(it.next()); - } - } - return sb; - } - - @CheckReturnValue - public @Nonnull @SafeVarargs final String join(@Nonnull A... array) { - return joinStream(streamOf(Arrays.stream(array))); - } - - @CheckReturnValue - public @Nonnull final String join(A first, A second, @Nonnull A[] array) { - Iterable prefix = Arrays.asList(first, second); - Iterable suffix = Arrays.asList(array); - return join(CollectionUtil.concat(prefix, suffix)); - } - - @CheckReturnValue - public @Nonnull String join(@Nonnull Iterable iterable) { - return joinStream(streamOf(iterable)); - } - - @CheckReturnValue - public @Nonnull String join(@Nonnull Iterator iterator) { - return joinStream(streamOf(iterator)); - } - - @CheckReturnValue - public @Nonnull @SafeVarargs final B appendTo(@Nonnull B sb, @Nonnull T... array) - throws IOException { - return appendStream(sb, streamOf(Arrays.stream(array))); - } - - @CheckReturnValue - public @Nonnull final B appendTo(@Nonnull B sb, T first, T second, @Nonnull T[] array) - throws IOException { - Iterable prefix = Arrays.asList(first, second); - Iterable suffix = Arrays.asList(array); - return appendTo(sb, CollectionUtil.concat(prefix, suffix)); - } - - @CheckReturnValue - public @Nonnull B appendTo(@Nonnull B sb, @Nonnull Iterable iterable) - throws IOException { - return appendStream(sb, streamOf(iterable)); - } - - @CheckReturnValue - public @Nonnull B appendTo(@Nonnull B sb, @Nonnull Iterator iterator) - throws IOException { - return appendStream(sb, streamOf(iterator)); - } - - @CheckReturnValue - public @Nonnull @SafeVarargs final StringBuilder appendTo(@Nonnull StringBuilder sb, @Nonnull T... array) { - return (StringBuilder) catchIoException(this::appendTo, (Appendable) sb, array); - } - - @CheckReturnValue - public @Nonnull final StringBuilder appendTo(@Nonnull StringBuilder sb, T first, T second, @Nonnull T[] array) { - Iterable prefix = Arrays.asList(first, second); - Iterable suffix = Arrays.asList(array); - return appendTo(sb, CollectionUtil.concat(prefix, suffix)); - } - - @CheckReturnValue - public @Nonnull StringBuilder appendTo(@Nonnull StringBuilder sb, @Nonnull Iterable iterable) { - return (StringBuilder) catchIoException(this::appendTo, (Appendable) sb, iterable); - } - - @CheckReturnValue - public @Nonnull StringBuilder appendTo(@Nonnull StringBuilder sb, @Nonnull Iterator iterator) { - return (StringBuilder) catchIoException(this::appendTo, (Appendable) sb, iterator); - } - - private interface Method { - T run(T first, V second) throws IOException; - } - - private static T catchIoException(Method method, T first, V second) { - return ExceptionUtil.checkException(() -> method.run(first, second), "Should not occur"); - } - - @CheckReturnValue - public @Nonnull Joiner skipNulls() { - if (_stream == DEFAULT_STREAM) { - return skipNulls(this); - } - throw new UnsupportedOperationException(); - } - - @CheckReturnValue - private @Nonnull static Joiner skipNulls(final @Nonnull Joiner joiner) { - return new Joiner(joiner._delimiter, joiner._mapper, o -> joiner.streamOf(o).filter(SKIP_NULLS)); - } - - @CheckReturnValue - public @Nonnull Joiner useForNull(final @Nonnull String nullText) { - if (_stream == DEFAULT_STREAM) { - return useForNull(this, nullText); - } - throw new UnsupportedOperationException(); - } - - @CheckReturnValue - private static @Nonnull Joiner useForNull(final @Nonnull Joiner joiner, final @Nonnull String nullText) { - return new Joiner(joiner._delimiter, o -> o != null ? joiner._mapper.apply(o) : nullText, joiner::streamOf); - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/misc/RetryCountSlidingWindow.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/misc/RetryCountSlidingWindow.java deleted file mode 100644 index e4d19defc1b..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/misc/RetryCountSlidingWindow.java +++ /dev/null @@ -1,143 +0,0 @@ -package com.linkedin.alpini.base.misc; - -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** - * A Sliding Window implementation that is implemented as followed: - * 1. Each thread maintains a ThreadLocal queue to count certain metric by removing the data that is out of the time - * range. - * 2. A dedicated thread collected the counts from those ThreadLocalQueue and sum them up into a thread-safe counter - * periodically - * - * Since the internal ThreadLocal instance is not a static one. Please do not create more than one - * RetryCountSlidingWindow. And please refer to the explanation just right above the ThreadLocal instance for why - * we made it a non-static variable. - * - * @author solu - * Date: 4/26/21 - */ -public class RetryCountSlidingWindow { - private static int stalenessTorlerantSeconds = 5; - private static final Logger LOG = LogManager.getLogger(RetryCountSlidingWindow.class); - - private int _slidingWindowLengthInSecond = 5; - final ConcurrentMap> _queueMap = new ConcurrentHashMap<>(); - - // Normally java recommends static on ThreadLocal variable. However, static variable is hard to unit test. - // So here we took the trade off by putting it as an instance variable to show that we are willing to take the risk - // that if someone accidentally created two RetryCountSlidingWindow instances, we would end up with two CounterQueue - // for a given thread if that thread calls gets on those RetryCounterSlidingWindow for more than once. - // This is just a trade off between testability and a possible memory leak. We need devs to be careful here for not - // creating more than on RetryCountSlidingWindow. - // Here is a simple unit test that proves one thread can have two instances of ThreadLocal if the ThreadLocal is - // an instance instead of a static one - /* - public class TestThreadLocal { - class Blah { - ThreadLocal _threadLocal = ThreadLocal.withInitial(Object::new); - } - - @Test - public void test() { - Blah b1 = new Blah(); - Blah b2 = new Blah(); - - Object o1 = b1._threadLocal.get(); - Object o2 = b2._threadLocal.get(); - - Assert.assertEquals(o1, o2); - } - } - */ - private final ThreadLocal _queues = - ThreadLocal.withInitial(() -> new CounterQueue<>(_slidingWindowLengthInSecond, _queueMap, RetryCounter::new)); - - private volatile double _retryRatio = 0.0; - private volatile long _totalCount = 0L; - private volatile long _retryCount = 0L; - - private volatile long _lastUpdateTsByUpdated = 0L; - - // An alternative of Google guava's checkArgument. It would be an overkill to take the whole fruit just for its - // checkArgument. - private void examineInput(int v, String vName) { - if (v <= 0) { - String msg = "Invalid " + vName + ": " + v; - LOG.error(msg); - throw new IllegalArgumentException(msg); - } - } - - public double getRetryRatio() { - long currentSecond = RetryCounter.getCurrentSecond(); - // if there is no thread to update the queues within last STALENESS_TORLERANT_SECONDS seconds, update the queues. - // even if there are multiple threads calling updateCount, it is still OK as updateCount is a thread-safe method. - if (currentSecond - _lastUpdateTsByUpdated > stalenessTorlerantSeconds) { - updateCount(); - } - return _retryRatio; - } - - public long getTotalCount() { - return _totalCount; - } - - public long getRetryCount() { - return _retryCount; - } - - /** - * Return a ThreadLocal Queue for I/O workers to keep counting retriy request count and total count. - * @return - */ - public CounterQueue getQueue() { - return _queues.get(); - } - - public RetryCountSlidingWindow( - int updateIntervalMs, - int slidingWindowLengthInSecond, - ScheduledExecutorService updateExecutor) { - examineInput(slidingWindowLengthInSecond, "slidingWindowLengthInSecond"); - examineInput(updateIntervalMs, "updateIntervalMs"); - - this._slidingWindowLengthInSecond = slidingWindowLengthInSecond; - - LOG.info( - "Building a RetrySlidingWindow with updateInterval = {} ms and slidingWindowLength = {} seconds", - updateIntervalMs, - slidingWindowLengthInSecond); - ScheduledExecutorService updater = Objects.requireNonNull(updateExecutor, "Null updateExecutor"); - updater.scheduleWithFixedDelay(this::updateCount, 0, updateIntervalMs, TimeUnit.MILLISECONDS); - } - - private void updateCount() { - _lastUpdateTsByUpdated = RetryCounter.getCurrentSecond(); - new SimpleCount().count(); - } - - private class SimpleCount { - long total; - long retry; - - public void count() { - _queueMap.values().forEach(q -> { - q.removeOldCounters(); - total += q.getTotalCount(); - retry += q.getTotalRetryCount(); - }); - - _retryRatio = total > 0 ? (double) retry / (double) total : 0.0; - _totalCount = total; - _retryCount = retry; - } - } - -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/misc/TouchTimer.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/misc/TouchTimer.java deleted file mode 100644 index f95ae2f549d..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/misc/TouchTimer.java +++ /dev/null @@ -1,357 +0,0 @@ -/* - * $Id$ - */ -package com.linkedin.alpini.base.misc; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.Formatter; -import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; -import javax.annotation.Nonnegative; -import javax.annotation.Nonnull; -import org.apache.logging.log4j.util.StringBuilderFormattable; - - -/** - * Handy utility class to track the timing while processing a request. A class can create a TouchTimer, - * then "touch" it at various points during processing. At the end, if the request took a long time, - * it can log the output. For example: - * - *
- * void doSomething()
- * {
- *      TouchTimer timer = new TouchTimer();
- *      timer.touch("Calling fooService");
- *      fooService.doSomething();
- *
- *      timer.touch("Calling barService");
- *      barService.doSomething();
- *
- *      timer.touch("All Done!");
- *
- *      if(timer.getElapsedTimeMillis() > 1000)
- *      {
- *         log.warn("doSomething took over a second to complete! " + timer);
- *      }
- * }
- * 
- * - * The block of code tracks the time to call each service. If the total time spent was greater than 1 second, it logs - * a message. The logged message will include timing for each "touch". The timer is thread safe, and output from - * TouchTimer.toString() will include the thread name along with each touch. - * - * @author Jemiah Westerman <jwesterman@linkedin.com> - * @version $Revision$ - */ -public final class TouchTimer implements StringBuilderFormattable { - /** - * Default maximum number of messages allowed on one timer. - * This is a safety to prevent a timer from growing without bounds - * if someone has it in a ThreadLocal or a static or something like that. - */ - public static final int DEFAULT_MAX_MESSAGES; - - public static final String MAX_MESSAGES_PROPERTY = "com.linkedin.alpini.base.misc.TouchTimer.max"; - - /** - * Message used to indicate that the maximum number of messages has been reached. - */ - private static final String MAX_MESSAGES_WARNING; - - private static final String DATE_FORMAT = "%1$tY/%1$tm/%1$td %1$tT.%1$tL"; - - /** - * Stores a singleton (deduped) copy of the thread name. The deduplication ensures that if we reference the same thread - * name multiple times, that we only reference a single instance of that String on the heap. - */ - private static final ThreadLocal DEDUPED_THREAD_NAME = new ThreadLocal<>(); - - private final int _maxMessageCount; - - /** Non-null sentinel; _first._next points to the oldest message in the list. */ - private Message _first = new Message(0, null, null, null, null); - - /** Last (most recent) message in the list. */ - private volatile Message _last = _first; - - /** Number of messages in the list. */ - private int _messageCount; - - private final long _startTimeMillis; - private final long _startTimeNanos; - - /** - * Default constructor - */ - public TouchTimer() { - this(DEFAULT_MAX_MESSAGES); - } - - /** - * Alternative constructor - * @param maxMessageCount Maximum number of messages - */ - public TouchTimer(@Nonnegative int maxMessageCount) { - this(maxMessageCount, Time.currentTimeMillis(), Time.nanoTime()); - } - - public TouchTimer( - @Nonnegative long startTimeMillis, - @Nonnegative long startTimeNanos, - @Nonnegative int maxMessageCount) { - this(maxMessageCount, startTimeMillis, startTimeNanos); - addMessage(new Message(startTimeNanos, getDedupedThreadName(), "start", null, null)); - } - - private TouchTimer(int maxMessageCount, long startTimeMillis, long startTimeNanos) { - _maxMessageCount = maxMessageCount; - _startTimeMillis = startTimeMillis; - _startTimeNanos = startTimeNanos; - } - - public long getStartTimeMillis() { - return _startTimeMillis; - } - - public long getStartTimeNanos() { - return _startTimeNanos; - } - - /** - * Add an event to this timer. - * @param name event name - * @param klass class generating the event - */ - public void touch(Class klass, String name, Object... args) { - String threadName = getDedupedThreadName(); - - addMessage( - new Message(Time.nanoTime(), threadName, name, args != null && args.length > 0 ? args.clone() : null, klass)); - } - - /** - * Add an event to this timer. - * @param name event name - */ - public void touch(Class klass, String name) { - String threadName = getDedupedThreadName(); - - addMessage(new Message(Time.nanoTime(), threadName, name, null, klass)); - } - - /** - * Add an event to this timer. - * @param name event name - */ - public void touch(String name, Object... args) { - touch(null, name, args); - } - - /** - * Add an event to this timer. - * @param name event name - */ - public void touch(String name) { - touch(null, name); - } - - /** - * Add a new message to the list in a thread-safe way without using synchronization nor locks. - * @param message message to add - */ - private void addMessage(@Nonnull Message message) { - Message last = _last; - for (;;) { - message._count = last._count + 1; - if (message._count > _maxMessageCount) { - // DEFAULT_MAX_MESSAGES exceeded, discard the message - return; - } - if (last._next == null && NEXT_UPDATER.compareAndSet(last, null, message)) { - _messageCount = message._count; - _last = message; - - // We exceeded DEFAULT_MAX_MESSAGES. Add a warning and don't store any more touches for this timer. - if (message._count == _maxMessageCount) { - message._next = new Message( - Time.nanoTime(), - message._threadName, - _maxMessageCount == DEFAULT_MAX_MESSAGES ? MAX_MESSAGES_WARNING : getMaxMessagesWarning(_maxMessageCount), - null, - message._klass); - } - - return; - } - last = last._next; - } - } - - private static long nanosToMillis(long nanos) { - return TimeUnit.NANOSECONDS.toMillis(nanos); - } - - /** - * Return the total time elapsed between the first and last events. - * @return time in milliseconds - */ - public long getElapsedTimeMillis() { - return nanosToMillis(getElapsedTimeNanos()); - } - - /** - * Return the total time elapsed between the first and last events. - * @return time in nanoseconds - */ - public long getElapsedTimeNanos() { - return _messageCount == 0 ? 0 : _last._nanos - _first._next._nanos; - } - - @Override - public String toString() { - StringBuilder trace = new StringBuilder(); - formatTo(trace); - return trace.toString(); - } - - @Override - public void formatTo(StringBuilder trace) { - Formatter formatter = new Formatter(trace); - - trace.append("Total Time: "); - TimeFormat.formatTimespan(getElapsedTimeMillis(), trace); - trace.append(" Trace: "); - - long prevMessageNanos = 0; - - Message current = _first._next; - while (current != null) { - // If this is not the first message then out the time since the previous message - if (prevMessageNanos != 0) { - trace.append(' '); - TimeFormat.formatTimespan(nanosToMillis(current._nanos - prevMessageNanos), trace); - trace.append(' '); - } - - trace.append("[").append(current._threadName).append(' '); - - // if a class was given, then build the message name using the class name. - if (current._klass != null) { - String longClassName = current._klass.getName(); - int lastDot = longClassName.lastIndexOf('.'); - trace.append(longClassName.subSequence(lastDot + 1, longClassName.length())).append(':'); - } - - if (current._args == null) { - trace.append(current._name); - } else { - formatter.format(current._name, current._args); - } - - trace.append(' '); - - long timeStamp = _startTimeMillis + nanosToMillis(current._nanos - _startTimeNanos); - formatter.format(DATE_FORMAT, new Date(timeStamp)); - - trace.append(']'); - - prevMessageNanos = current._nanos; - current = current._next; - } - } - - /** Return the messages list for this TouchTimer. For use in unit tests. */ - /* package private */ List getMessages() { - List messages = new ArrayList(_messageCount); - Message current = _first._next; - while (current != null) { - messages.add(current); - current = current._next; - } - return Collections.unmodifiableList(messages); - } - - /** - * Visit all the messages for this TouchTimer - * @param visitor message visitor - */ - public void forEachMessage(@Nonnull Visitor visitor) { - Message current = _first._next; - while (current != null) { - long timeStamp = _startTimeMillis + nanosToMillis(current._nanos - _startTimeNanos); - visitor.visit( - timeStamp, - current._threadName, - current._klass, - current._name, - current._args != null ? current._args.clone() : null); - current = current._next; - } - } - - /** - * Return the deduplicated name of the current thread. Deduplication makes suer that multiple references to the same thread name - * reference a single String instance. - */ - /*package private*/ static String getDedupedThreadName() { - // Get the de-duped thread name from the map from the ThreadLocal. - // If the name wasn't already cached or if it the name has changed, then we have to update the ThreadLocal. - String localThreadName = Thread.currentThread().getName(); - String dedupedThreadName = DEDUPED_THREAD_NAME.get(); - if (dedupedThreadName == null || !dedupedThreadName.equals(localThreadName)) { - DEDUPED_THREAD_NAME.set(localThreadName); - dedupedThreadName = localThreadName; - } - - // Return the deduped name - return dedupedThreadName; - } - - /** - * Message Visitor interface - */ - public interface Visitor { - void visit(long timestamp, String threadName, Class klass, String message, Object[] args); - } - - /** - * Stores an individual "touch" with the timestamp and relevant data. We try to keep the memory footprint as small - * as possible, so we just store references to the arguments instead of storing the fully formatted String as it - * would be printed in the log. Since the vast majority of these will not be logged (typical use case is to only log - * very slow requests), it is preferable to only do that final formatting if and when we actually need it. - */ - /* package private */ static final class Message { - final long _nanos; - final String _threadName; - final String _name; - final Object[] _args; - final Class _klass; - int _count; - volatile Message _next; - - public Message(long nanos, String threadName, String name, Object[] args, Class klass) { - _nanos = nanos; - _threadName = threadName; - _name = name; - _args = args; - _klass = klass; - } - } - - private static final AtomicReferenceFieldUpdater NEXT_UPDATER = - AtomicReferenceFieldUpdater.newUpdater(Message.class, Message.class, "_next"); - - private static String getMaxMessagesWarning(int maxMessageCount) { - return "TouchTimer Warning: Exceeded the maximum number of messages allowed (" + maxMessageCount - + "). No further messages will be logged for this timer."; - } - - static { - DEFAULT_MAX_MESSAGES = Integer.parseUnsignedInt(System.getProperty(MAX_MESSAGES_PROPERTY, "2000")); - - MAX_MESSAGES_WARNING = getMaxMessagesWarning(DEFAULT_MAX_MESSAGES); - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/misc/TriFunction.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/misc/TriFunction.java deleted file mode 100644 index 0359c4c7cb4..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/misc/TriFunction.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.linkedin.alpini.base.misc; - -@FunctionalInterface -public interface TriFunction { - /** - * Applies this function to the given arguments. - * - * @param t the first function argument - * @param u the second function argument - * @param s the third function argument - * @return the function result - */ - R apply(T t, U u, S s); -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/monitoring/CallCompletion.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/monitoring/CallCompletion.java deleted file mode 100644 index 970131f267a..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/monitoring/CallCompletion.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.linkedin.alpini.base.monitoring; - -import com.linkedin.alpini.base.misc.Time; -import javax.annotation.Nonnegative; -import javax.annotation.Nonnull; - - -/** - * @author Antony T Curtis {@literal } - */ -public interface CallCompletion extends AutoCloseable { - default void close() { - close(Time.nanoTime()); - } - - default void closeWithError() { - closeWithError(Time.nanoTime()); - } - - default void closeWithError(@Nonnull Throwable error) { - closeWithError(Time.nanoTime(), error); - } - - default void closeCompletion(T value, Throwable error) { - closeCompletion(Time.nanoTime(), value, error); - } - - void close(@Nonnegative long endTimeNanos); - - default void closeWithError(@Nonnegative long endTimeNanos) { - closeWithError(endTimeNanos, CallTracker.GENERIC_EXCEPTION); - } - - void closeWithError(@Nonnegative long endTimeNanos, @Nonnull Throwable error); - - default void closeCompletion(@Nonnegative long endTimeNanos, T value, Throwable error) { - if (error == null) { - close(endTimeNanos); - } else { - closeWithError(endTimeNanos, error); - } - } - - static CallCompletion combine(CallCompletion... completions) { - CallCompletion[] array = completions.clone(); - return new CallCompletion() { - @Override - public void close(long endTimeNanos) { - for (CallCompletion cc: array) { - if (cc != null) { - cc.close(endTimeNanos); - } - } - } - - @Override - public void closeWithError(long endTimeNanos, @Nonnull Throwable error) { - for (CallCompletion cc: array) { - if (cc != null) { - cc.closeWithError(endTimeNanos, error); - } - } - } - }; - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/monitoring/CallTracker.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/monitoring/CallTracker.java deleted file mode 100644 index f4c7ae37a06..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/monitoring/CallTracker.java +++ /dev/null @@ -1,143 +0,0 @@ -package com.linkedin.alpini.base.monitoring; - -import com.linkedin.alpini.base.misc.ExceptionUtil; -import com.linkedin.alpini.base.misc.Time; -import com.linkedin.alpini.base.statistics.LongStats; -import java.util.concurrent.TimeUnit; -import javax.annotation.CheckReturnValue; -import javax.annotation.Nonnegative; -import javax.annotation.Nonnull; - - -/** - * @author Antony T Curtis {@literal } - */ -public interface CallTracker { - Exception GENERIC_EXCEPTION = ExceptionUtil.withoutStackTrace(new Exception()); - - @Nonnull - @CheckReturnValue - default CallCompletion startCall() { - return startCall(Time.nanoTime()); - } - - @Nonnull - @CheckReturnValue - CallCompletion startCall(@Nonnegative long startTimeNanos); - - default void trackCall(long duration) { - trackCall(duration, TimeUnit.MILLISECONDS); - } - - default void trackCall(long duration, @Nonnull TimeUnit timeUnit) { - trackCallWithError(duration, timeUnit, null); - } - - default void trackCallWithError(long duration) { - trackCallWithError(duration, TimeUnit.MILLISECONDS); - } - - default void trackCallWithError(long duration, @Nonnull TimeUnit timeUnit) { - trackCallWithError(duration, timeUnit, GENERIC_EXCEPTION); - } - - default void trackCallWithError(long duration, Throwable throwable) { - trackCallWithError(duration, TimeUnit.MILLISECONDS, throwable); - } - - void trackCallWithError(long duration, @Nonnull TimeUnit timeUnit, Throwable throwable); - - long getCurrentStartCountTotal(); - - long getCurrentCallCountTotal(); - - long getCurrentErrorCountTotal(); - - int getCurrentConcurrency(); - - @Nonnull - @CheckReturnValue - double[] getAverageConcurrency(); - - @Nonnull - @CheckReturnValue - int[] getMaxConcurrency(); - - @Nonnull - @CheckReturnValue - int[] getStartFrequency(); - - @Nonnull - @CheckReturnValue - long[] getStartCount(); - - @Nonnull - @CheckReturnValue - int[] getErrorFrequency(); - - @Nonnull - @CheckReturnValue - long[] getErrorCount(); - - @Nonnull - @CheckReturnValue - CallStats getCallStats(); - - void reset(); - - long getLastResetTime(); - - long getTimeSinceLastStartCall(); - - interface CallStats { - long getCallCountTotal(); - - long getCallStartCountTotal(); - - long getErrorCountTotal(); - - int getConcurrency(); - - double getAverageConcurrency1min(); - - double getAverageConcurrency5min(); - - double getAverageConcurrency15min(); - - int getMaxConcurrency1min(); - - int getMaxConcurrency5min(); - - int getMaxConcurrency15min(); - - int getStartFrequency1min(); - - int getStartFrequency5min(); - - int getStartFrequency15min(); - - int getErrorFrequency1min(); - - int getErrorFrequency5min(); - - int getErrorFrequency15min(); - - long getOutstandingStartTimeAvg(); - - int getOutstandingCount(); - - /** - * Returns the call time stats in nanoseconds. - * @return {@linkplain LongStats} object. - */ - LongStats getCallTimeStats(); - } - - static CallTracker create() { - return new CallTrackerImpl(); - } - - static CallTracker nullTracker() { - return NullCallTracker.INSTANCE; - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/monitoring/CallTrackerImpl.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/monitoring/CallTrackerImpl.java deleted file mode 100644 index a03999d0a40..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/monitoring/CallTrackerImpl.java +++ /dev/null @@ -1,844 +0,0 @@ -package com.linkedin.alpini.base.monitoring; - -import com.linkedin.alpini.base.concurrency.ConcurrentAccumulator; -import com.linkedin.alpini.base.misc.Time; -import com.linkedin.alpini.base.statistics.AbstractQuantileEstimation; -import com.linkedin.alpini.base.statistics.LongStats; -import com.linkedin.alpini.base.statistics.LongStatsAggregator; -import com.linkedin.alpini.base.statistics.LongStatsArrayAggregator; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicIntegerArray; -import java.util.concurrent.atomic.AtomicReference; -import java.util.concurrent.locks.ReentrantLock; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.function.UnaryOperator; -import java.util.stream.Collector; -import javax.annotation.Nonnegative; -import javax.annotation.Nonnull; - - -/** - * Tracker for "load average" of a call. - * - * @author Antony T Curtis {@literal } - */ -public class CallTrackerImpl implements CallTracker { - private static final int SECONDS_PER_BUCKET = 1; - private static final long NANOS_PER_BUCKET = TimeUnit.SECONDS.toNanos(SECONDS_PER_BUCKET); - private static final int NUMBER_OF_BUCKETS = 15 * 60 / SECONDS_PER_BUCKET + 1; - private static final long SUNSET_NANOS = NANOS_PER_BUCKET * NUMBER_OF_BUCKETS; - private static final long NANOS_PER_SECOND = TimeUnit.SECONDS.toNanos(1); - - private static final double LONG_STATS_EPSILON = 0.0005; - private static final int LONG_STATS_SAMPLES = 2000; - - private static final Stats NULL_STATS = new Stats(); - - private final ReentrantLock _lock = new ReentrantLock(); - - private int _lastIndex; - private long _nextNanos = Time.nanoTime(); - private final long[] _nanosBuckets = new long[NUMBER_OF_BUCKETS]; - private final long[] _startBuckets = new long[NUMBER_OF_BUCKETS]; - private final long[] _errorBuckets = new long[NUMBER_OF_BUCKETS]; - private final int[] _maxConBuckets = new int[NUMBER_OF_BUCKETS]; - - public enum Mode { - SKIP_LIST { - @Override - LongStatsAggregator constructor(double epsilon, int samples) { - return new LongStatsAggregator(epsilon, samples); - } - }, - ARRAY_LIST { - @Override - LongStatsAggregator constructor(double epsilon, int samples) { - return new LongStatsArrayAggregator(epsilon, samples); - } - }; - - abstract LongStatsAggregator constructor(double epsilon, int samples); - } - - public static Mode defaultMode = Mode.SKIP_LIST; - - private final LongStatsAggregator _callTimeStatsAggregator = - defaultMode.constructor(LONG_STATS_EPSILON, LONG_STATS_SAMPLES); - private final AtomicIntegerArray _concurrencyArray; - private final AtomicIntegerArray _maxConcurrencyArray; - - private final ConcurrentAccumulator _stats; - private long _lastResetTime = Time.currentTimeMillis(); - private long _lastStartTime = 0L; - - private Predicate _testSuccessful = ignored -> false; - - public CallTrackerImpl() { - this(Runtime.getRuntime().availableProcessors()); - } - - public CallTrackerImpl(@Nonnegative int ncpu) { - this(ncpu, ConcurrentAccumulator.defaultMode); - } - - public CallTrackerImpl(@Nonnegative int ncpu, @Nonnull ConcurrentAccumulator.Mode accumulatorMode) { - _concurrencyArray = new AtomicIntegerArray(cpuBuckets(Math.max(1, Math.min(ncpu, 64)))); - _maxConcurrencyArray = new AtomicIntegerArray(_concurrencyArray.length()); - _stats = new ConcurrentAccumulator<>(accumulatorMode, Stats.COLLECTOR); - } - - private static final ThreadLocal LOCAL = ThreadLocal.withInitial(LocalState::new); - - private static final class LocalState { - private final Reset reset = new Reset(); - private final Start start = new Start(); - private final EndTimeSuccess endSuccess = new EndTimeSuccess(); - private final EndTimeFailure endFailure = new EndTimeFailure(); - private State last; - private State result; - private State idle; - - private Start start(long startTimeNanos) { - start._startTimeNanos = startTimeNanos; - return start; - } - - private EndTimeSuccess endSuccess(long now, long startTimeNanos) { - endSuccess.now = now; - endSuccess.startTimeNanos = startTimeNanos; - return endSuccess; - } - - private EndTimeFailure endFailure(long now, long startTimeNanos) { - endFailure.now = now; - endFailure.startTimeNanos = startTimeNanos; - return endFailure; - } - - private Stats combine(Stats stats, Stats other) { - return combine(state(stats), state(other)); - } - - private Stats combine(State state, State other) { - state._started += other._started; - state._completed += other._completed; - state._completedWithError += other._completedWithError; - state._nanosRunning += other._nanosRunning; - state._startTimeSum += other._startTimeSum; - state._concurrency += other._concurrency; - idle = other; - return new Stats(state); - } - - void localDone() { - result = null; - if (idle == null) { - idle = last; - last = null; - } - } - - public State state(Stats stats) { - State oldState = stats.get(); - for (;;) { - State newState = copyStats(oldState); - if (stats.compareAndSet(oldState, newState)) { - break; - } - idle = newState; - oldState = stats.get(); - } - State last = this.last; - this.last = null; - localDone(); - return last; - } - - private State copyStats(State state) { - return result(state).recycle( - state._started, - state._completed, - state._completedWithError, - state._nanosRunning, - state._startTimeSum, - state._concurrency); - } - - private State result(State state) { - last = state; - if (result == null) { - if (idle == null) { - result = new State(); - } else { - result = idle; - idle = null; - } - } - return result; - } - - private final class Reset extends Change { - @Override - public State apply(State state) { - long adjust = Math.min(state._started, state._completed); - return result(state).recycle( - state._started - adjust, - state._completed - adjust, - 0, - state._nanosRunning, - state._startTimeSum, - state._concurrency); - } - - public void done() { - localDone(); - } - } - - private final class Start extends Change { - private long _startTimeNanos; - - @Override - public State apply(State state) { - return result(state).recycle( - state._started + 1, - state._completed, - state._completedWithError, - state._nanosRunning - _startTimeNanos, - state._startTimeSum + _startTimeNanos, - state._concurrency + 1); - } - - public void done() { - localDone(); - } - } - - private final class EndTimeSuccess extends Change { - private long now; - private long startTimeNanos; - - @Override - public State apply(State state) { - return result(state).recycle( - state._started, - state._completed + 1, - state._completedWithError, - state._nanosRunning + now, - state._startTimeSum - startTimeNanos, - state._concurrency - 1); - } - - public void done() { - localDone(); - } - } - - private final class EndTimeFailure extends Change { - private long now; - private long startTimeNanos; - - @Override - public State apply(State state) { - return result(state).recycle( - state._started, - state._completed + 1, - state._completedWithError + 1, - state._nanosRunning + now, - state._startTimeSum - startTimeNanos, - state._concurrency - 1); - } - - public void done() { - localDone(); - } - } - } - - private static abstract class Change implements UnaryOperator { - public abstract State apply(State state); - - public abstract void done(); - } - - private static final class State { - long _started; - long _completed; - long _completedWithError; - long _nanosRunning; - long _startTimeSum; - long _concurrency; - - private State recycle( - long started, - long completed, - long completedWithError, - long nanosRunning, - long startTimeSum, - long concurrency) { - _started = started; - _completed = completed; - _completedWithError = completedWithError; - _nanosRunning = nanosRunning; - _startTimeSum = startTimeSum; - _concurrency = concurrency; - return this; - } - - private int concurrency() { - return Math.toIntExact(_concurrency); - } - } - - private static final class Stats extends AtomicReference { - Stats() { - this(new State()); - } - - Stats(State state) { - super(state); - } - - private static final Collector COLLECTOR = Collector.of( - Stats::new, - Stats::accumulate, - Stats::combine, - Function.identity(), - Collector.Characteristics.UNORDERED, - Collector.Characteristics.IDENTITY_FINISH); - - private Stats combine(Stats other) { - return LOCAL.get().combine(this, other); - } - - private void accumulate(Change change) { - super.updateAndGet(change); - change.done(); - } - - private State state() { - return LOCAL.get().state(this); - } - } - - private void tick(final long now) { - assert _lock.isHeldByCurrentThread(); - if (_nextNanos + SUNSET_NANOS < now) { - _nextNanos = now - SUNSET_NANOS; - _lastIndex = 0; - } - long nextNanos = _nextNanos; - if (nextNanos <= now) { - Stats stats = stats(); - int maxConcurrency = 0; - for (int i = _maxConcurrencyArray.length() - 1; i >= 0; i--) { - maxConcurrency += _maxConcurrencyArray.getAndSet(i, 0); - } - int index = _lastIndex; - do { - if (NUMBER_OF_BUCKETS == ++index) { - index = 0; - } - State state = stats.state(); - _nanosBuckets[index] = state._nanosRunning + state._concurrency * nextNanos; - _startBuckets[index] = state._started; - _errorBuckets[index] = state._completedWithError; - _maxConBuckets[index] = maxConcurrency; - nextNanos += NANOS_PER_BUCKET; - } while (nextNanos <= now); - _lastIndex = index; - _nextNanos = nextNanos; - } - } - - public void setTestSuccessful(@Nonnull Predicate test) { - _testSuccessful = test; - } - - protected boolean isSuccessfulException(@Nonnull Throwable exception) { - return _testSuccessful.test(exception); - } - - private boolean isSuccessful(Throwable exception) { - return exception == null || exception != GENERIC_EXCEPTION && isSuccessfulException(exception); - } - - private final class Completion extends AtomicReference implements CallCompletion { - private final long _startTimeNanos; - private final long _threadId = Thread.currentThread().getId(); - private final int _slot = foldUp(_threadId) & (_concurrencyArray.length() - 1); - - private Completion(long startTimeNanos) { - this._startTimeNanos = startTimeNanos; - set(this); - } - - @Override - public void close(@Nonnegative long now) { - long duration = Math.max(0L, now - _startTimeNanos); - LocalState local = LOCAL.get(); - close(local, now, duration, local.endSuccess(now, _startTimeNanos)); - } - - @Override - public void closeWithError(@Nonnegative long endTimeNanos) { - closeWithError(endTimeNanos, GENERIC_EXCEPTION); - } - - @Override - public void closeWithError(@Nonnegative long now, @Nonnull Throwable error) { - long duration = Math.max(0L, now - _startTimeNanos); - LocalState local = LOCAL.get(); - close( - local, - now, - duration, - isSuccessful(error) ? local.endSuccess(now, _startTimeNanos) : local.endFailure(now, _startTimeNanos)); - } - - private void close(LocalState local, long now, long duration, Change change) { - if (!compareAndSet(this, null)) { - return; - } - _stats.accept(change); - _callTimeStatsAggregator.accept(duration); - _concurrencyArray.getAndDecrement(_slot); - checkTick(now); - } - } - - @Override - @Nonnull - public CallCompletion startCall(@Nonnegative long startTimeNanos) { - _lastStartTime = Math.max(_lastStartTime, startTimeNanos); - - Completion cc = new Completion(startTimeNanos); - - checkTick(startTimeNanos); - - LocalState local = LOCAL.get(); - _stats.accept(local.start(startTimeNanos)); - - int con = _concurrencyArray.incrementAndGet(cc._slot); - if (con > _maxConcurrencyArray.get(cc._slot)) { - _maxConcurrencyArray.accumulateAndGet(cc._slot, con, Math::max); - } - - return cc; - } - - @Override - public void trackCallWithError(long duration, @Nonnull TimeUnit timeUnit, Throwable throwable) { - long now = Time.nanoTime(); - duration = timeUnit.toNanos(duration); - long startTimeNanos = now - duration; - - _lastStartTime = Math.max(_lastStartTime, startTimeNanos); - LocalState local = LOCAL.get(); - _stats.accept(local.start(startTimeNanos)); - - _stats.accept( - isSuccessful(throwable) ? local.endSuccess(now, startTimeNanos) : local.endFailure(now, startTimeNanos)); - - _callTimeStatsAggregator.accept(duration); - - checkTick(now); - } - - private void checkTick(long now) { - if (_nextNanos <= now && _lock.tryLock()) { - try { - tick(now); - } finally { - _lock.unlock(); - } - } - } - - @Nonnull - private Stats stats() { - Stats stats = _stats.get(); - if (stats == null) { - stats = NULL_STATS; - } - return stats; - } - - private long getTotalRuntimeNanos(State state, long now) { - return state._nanosRunning + state._concurrency * now; - } - - public long getTotalRuntimeNanos() { - return getTotalRuntimeNanos(stats().state(), Time.nanoTime()); - } - - @Override - public long getCurrentStartCountTotal() { - return stats().state()._started; - } - - @Override - public long getCurrentCallCountTotal() { - return stats().state()._completed; - } - - @Override - public long getCurrentErrorCountTotal() { - return stats().state()._completedWithError; - } - - @Override - public int getCurrentConcurrency() { - return stats().state().concurrency(); - } - - private static int calcIndex(int pos, int buckets) { - pos -= buckets - 1; - if (pos < 0) { - pos += NUMBER_OF_BUCKETS; - } - return pos; - } - - /** - * Returns the average concurrency over a period of time. - * @return array of 1, 5 and 15 minute average concurrency. - */ - @Override - @Nonnull - public double[] getAverageConcurrency() { - long now = Time.nanoTime(); - _lock.lock(); - try { - tick(now); - return getAverageConcurrency(now, stats().state()); - } finally { - _lock.unlock(); - } - } - - private double[] getAverageConcurrency(long now, State state) { - assert _lock.isHeldByCurrentThread(); - long delta1; - long delta5; - long delta15; - - long currentTotal = getTotalRuntimeNanos(state, now); - - int lastIndex = _lastIndex; - - int index1 = calcIndex(lastIndex, 60 / SECONDS_PER_BUCKET); - int index5 = calcIndex(lastIndex, 300 / SECONDS_PER_BUCKET); - int index15 = calcIndex(lastIndex, 900 / SECONDS_PER_BUCKET); - - delta1 = currentTotal - _nanosBuckets[index1]; - delta5 = currentTotal - _nanosBuckets[index5]; - delta15 = currentTotal - _nanosBuckets[index15]; - - return new double[] { ((double) delta1) / (60 * NANOS_PER_SECOND), ((double) delta5) / (300 * NANOS_PER_SECOND), - ((double) delta15) / (900 * NANOS_PER_SECOND) }; - } - - @Override - @Nonnull - public int[] getMaxConcurrency() { - checkTick(Time.nanoTime()); - return getMaxConcurrency(stats().state()); - } - - private int[] getMaxConcurrency(State state) { - int lastIndex = _lastIndex; - - int index1 = calcIndex(lastIndex, 60 / SECONDS_PER_BUCKET); - int index5 = calcIndex(lastIndex, 300 / SECONDS_PER_BUCKET); - int index15 = calcIndex(lastIndex, 900 / SECONDS_PER_BUCKET); - - int index = lastIndex; - - int concurrency1 = 0; - for (; index != index1; index = (index == 0 ? NUMBER_OF_BUCKETS : index) - 1) { - concurrency1 = Math.max(concurrency1, _maxConBuckets[index]); - } - - int concurrency5 = concurrency1; - for (; index != index5; index = (index == 0 ? NUMBER_OF_BUCKETS : index) - 1) { - concurrency5 = Math.max(concurrency5, _maxConBuckets[index]); - } - - int concurrency15 = concurrency5; - for (; index != index15; index = (index == 0 ? NUMBER_OF_BUCKETS : index) - 1) { - concurrency15 = Math.max(concurrency15, _maxConBuckets[index]); - } - - return new int[] { concurrency1, concurrency5, concurrency15 }; - } - - private static int div(long numerator, int denominator) { - return (int) ((numerator + denominator - 1) / denominator); - } - - @Override - @Nonnull - public int[] getStartFrequency() { - checkTick(Time.nanoTime()); - return getStartFrequency(stats().state()); - } - - @Override - @Nonnull - public long[] getStartCount() { - checkTick(Time.nanoTime()); - return getStartCount(stats().state()); - } - - private int[] getStartFrequency(State state) { - return getFrequency(state._started, _startBuckets); - } - - private long[] getStartCount(State state) { - return getDiffCount(state._started, _startBuckets); - } - - @Override - @Nonnull - public int[] getErrorFrequency() { - checkTick(Time.nanoTime()); - return getErrorFrequency(stats().state()); - } - - public long[] getErrorCount() { - checkTick(Time.nanoTime()); - return getErrorCount(stats().state()); - } - - private int[] getErrorFrequency(State state) { - return getFrequency(state._completedWithError, _errorBuckets); - } - - private long[] getErrorCount(State state) { - return getDiffCount(state._completedWithError, _errorBuckets); - } - - private int[] getFrequency(long currentTotal, long[] buckets) { - return getFrequency0(currentTotal, buckets); - } - - private long[] getDiffCount(long currentTotal, long[] buckets) { - int lastIndex = _lastIndex; - int index1 = calcIndex(lastIndex, 60 / SECONDS_PER_BUCKET); - int index5 = calcIndex(lastIndex, 300 / SECONDS_PER_BUCKET); - int index15 = calcIndex(lastIndex, 900 / SECONDS_PER_BUCKET); - long value1 = currentTotal - buckets[index1]; - long value5 = currentTotal - buckets[index5]; - long value15 = currentTotal - buckets[index15]; - return new long[] { value1, value5, value15 }; - } - - private int[] getFrequency0(long currentTotal, long[] buckets) { - long[] diffCounts = getDiffCount(currentTotal, buckets); - int value1 = div(diffCounts[0], 60); - int value5 = div(diffCounts[1], 300); - int value15 = div(diffCounts[2], 900); - return new int[] { value1, value5, value15 }; - } - - @Override - @Nonnull - public CallStats getCallStats() { - long now = Time.nanoTime(); - _lock.lock(); - try { - tick(now); - return new CallStatsImpl(now, this, stats().state(), _callTimeStatsAggregator.getLongStats()); - } finally { - _lock.unlock(); - } - } - - public AbstractQuantileEstimation.Quantile computeQuantile(long sample, @Nonnull TimeUnit timeUnit) { - return _callTimeStatsAggregator.computeQuantile(timeUnit.toNanos(sample)); - } - - @Override - public void reset() { - _lastResetTime = Time.currentTimeMillis(); - LocalState local = LOCAL.get(); - _stats.accept(local.reset); - _callTimeStatsAggregator.reset(); - } - - @Override - public long getLastResetTime() { - return _lastResetTime; - } - - @Override - public long getTimeSinceLastStartCall() { - return _lastStartTime == 0L ? 0L : TimeUnit.NANOSECONDS.toMillis(Time.nanoTime() - _lastStartTime); - } - - private static int cpuBuckets(int proc) { - proc--; - proc |= proc >>> 1; - proc |= proc >>> 2; - proc |= proc >>> 4; - proc |= proc >>> 8; - proc |= proc >>> 16; - return Math.max(1, ++proc); - } - - private static int foldUp(long value) { - return (int) (0xffL & (value ^ (value >>> 8) ^ (value >>> 16) ^ (value >>> 24) ^ (value >>> 32) ^ (value >>> 40) - ^ (value >>> 48) ^ (value >>> 52))); - } - - private static final class CallStatsImpl implements CallStats { - private final long _callCountTotal; - private final long _callStartCountTotal; - private final long _errorCountTotal; - private final int _currentConcurrency; - private final double[] _concurrencyAvg; - private final int[] _maxConcurrency; - private final int[] _errorFrequency; - private final int[] _startFrequency; - private final long _outstandingStartTimes; - private final LongStats _callTimeStats; - - private CallStatsImpl(long now, CallTrackerImpl callTracker, State state, LongStats callTimeStats) { - _callCountTotal = state._completed; - _callStartCountTotal = state._started; - _errorCountTotal = state._completedWithError; - _currentConcurrency = state.concurrency(); - _concurrencyAvg = callTracker.getAverageConcurrency(now, state); - _maxConcurrency = callTracker.getMaxConcurrency(state); - _errorFrequency = callTracker.getErrorFrequency(state); - _startFrequency = callTracker.getStartFrequency(state); - _outstandingStartTimes = state._startTimeSum; - _callTimeStats = callTimeStats; - } - - @Override - public long getCallCountTotal() { - return _callCountTotal; - } - - @Override - public long getCallStartCountTotal() { - return _callStartCountTotal; - } - - @Override - public long getErrorCountTotal() { - return _errorCountTotal; - } - - @Override - public int getConcurrency() { - return _currentConcurrency; - } - - @Override - public double getAverageConcurrency1min() { - return _concurrencyAvg[0]; - } - - @Override - public double getAverageConcurrency5min() { - return _concurrencyAvg[1]; - } - - @Override - public double getAverageConcurrency15min() { - return _concurrencyAvg[2]; - } - - @Override - public long getOutstandingStartTimeAvg() { - int outstanding = getConcurrency(); - return outstanding > 0 ? _outstandingStartTimes / outstanding : 0; - } - - @Override - public int getOutstandingCount() { - return getConcurrency(); - } - - @Override - public int getMaxConcurrency1min() { - return _maxConcurrency[0]; - } - - @Override - public int getMaxConcurrency5min() { - return _maxConcurrency[1]; - } - - @Override - public int getMaxConcurrency15min() { - return _maxConcurrency[2]; - } - - @Override - public int getErrorFrequency1min() { - return _errorFrequency[0]; - } - - @Override - public int getErrorFrequency5min() { - return _errorFrequency[1]; - } - - @Override - public int getErrorFrequency15min() { - return _errorFrequency[2]; - } - - @Override - public int getStartFrequency1min() { - return _startFrequency[0]; - } - - @Override - public int getStartFrequency5min() { - return _startFrequency[1]; - } - - @Override - public int getStartFrequency15min() { - return _startFrequency[2]; - } - - @Override - public LongStats getCallTimeStats() { - return _callTimeStats; - } - - @Override - public String toString() { - return String.format( - "callCountTotal=%d startCountTotal=%d errorCountTotal=%d" - + " concurrency=%d concurrencyAvg=%.3f,%.3f,%.3f concurrencyMax=%d,%d,%d" - + " startFrequency=%d,%d,%d errorFrequency=%d,%d,%d" + " outstanding=%d outstandingStartTimeAvg=%d %s", - getCallCountTotal(), - getCallStartCountTotal(), - getErrorCountTotal(), - getConcurrency(), - getAverageConcurrency1min(), - getAverageConcurrency5min(), - getAverageConcurrency15min(), - getMaxConcurrency1min(), - getMaxConcurrency5min(), - getMaxConcurrency15min(), - getStartFrequency1min(), - getStartFrequency5min(), - getStartFrequency15min(), - getErrorFrequency1min(), - getErrorFrequency5min(), - getErrorFrequency15min(), - getOutstandingCount(), - getOutstandingStartTimeAvg(), - _callTimeStats); - } - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/monitoring/NullCallTracker.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/monitoring/NullCallTracker.java deleted file mode 100644 index cc1f9974a71..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/monitoring/NullCallTracker.java +++ /dev/null @@ -1,263 +0,0 @@ -package com.linkedin.alpini.base.monitoring; - -import com.linkedin.alpini.base.statistics.LongStats; -import java.util.concurrent.TimeUnit; -import javax.annotation.Nonnegative; -import javax.annotation.Nonnull; - - -/** - * Created by acurtis on 3/30/17. - */ -public final class NullCallTracker implements CallTracker { - public static final CallTracker INSTANCE = new NullCallTracker(); - - @Nonnull - @Override - public CallCompletion startCall(@Nonnegative long startTimeNanos) { - return CALL_COMPLETION; - } - - @Override - public void trackCall(long duration, @Nonnull TimeUnit timeUnit) { - } - - @Override - public void trackCallWithError(long duration, @Nonnull TimeUnit timeUnit, Throwable throwable) { - } - - @Override - public long getCurrentStartCountTotal() { - return 0; - } - - @Override - public long getCurrentCallCountTotal() { - return 0; - } - - @Override - public long getCurrentErrorCountTotal() { - return 0; - } - - @Override - public int getCurrentConcurrency() { - return 0; - } - - @Nonnull - @Override - public double[] getAverageConcurrency() { - return new double[0]; - } - - @Nonnull - @Override - public int[] getMaxConcurrency() { - return new int[0]; - } - - @Nonnull - @Override - public int[] getStartFrequency() { - return new int[0]; - } - - @Nonnull - @Override - public long[] getStartCount() { - return new long[0]; - } - - @Nonnull - @Override - public int[] getErrorFrequency() { - return new int[0]; - } - - @Nonnull - @Override - public long[] getErrorCount() { - return new long[0]; - } - - @Nonnull - @Override - public CallStats getCallStats() { - return CALL_STATS; - } - - @Override - public void reset() { - } - - @Override - public long getLastResetTime() { - return 0; - } - - @Override - public long getTimeSinceLastStartCall() { - return 0; - } - - private static final CallCompletion CALL_COMPLETION = new CallCompletion() { - @Override - public void close(@Nonnegative long endTimeNanos) { - } - - @Override - public void closeWithError(@Nonnegative long endTimeNanos, @Nonnull Throwable error) { - } - }; - - private static final CallStats CALL_STATS = new CallStats() { - @Override - public long getCallCountTotal() { - return 0; - } - - @Override - public long getCallStartCountTotal() { - return 0; - } - - @Override - public long getErrorCountTotal() { - return 0; - } - - @Override - public int getConcurrency() { - return 0; - } - - @Override - public double getAverageConcurrency1min() { - return 0; - } - - @Override - public double getAverageConcurrency5min() { - return 0; - } - - @Override - public double getAverageConcurrency15min() { - return 0; - } - - @Override - public int getMaxConcurrency1min() { - return 0; - } - - @Override - public int getMaxConcurrency5min() { - return 0; - } - - @Override - public int getMaxConcurrency15min() { - return 0; - } - - @Override - public int getStartFrequency1min() { - return 0; - } - - @Override - public int getStartFrequency5min() { - return 0; - } - - @Override - public int getStartFrequency15min() { - return 0; - } - - @Override - public int getErrorFrequency1min() { - return 0; - } - - @Override - public int getErrorFrequency5min() { - return 0; - } - - @Override - public int getErrorFrequency15min() { - return 0; - } - - @Override - public long getOutstandingStartTimeAvg() { - return 0; - } - - @Override - public int getOutstandingCount() { - return 0; - } - - @Override - public LongStats getCallTimeStats() { - return LONG_STATS; - } - }; - - private static final LongStats LONG_STATS = new LongStats() { - @Override - public long getLongCount() { - return 0; - } - - @Override - public double getAverage() { - return 0; - } - - @Override - public double getStandardDeviation() { - return 0; - } - - @Override - public Long getMinimum() { - return null; - } - - @Override - public Long getMaximum() { - return null; - } - - @Override - public Long get50Pct() { - return null; - } - - @Override - public Long get90Pct() { - return null; - } - - @Override - public Long get95Pct() { - return null; - } - - @Override - public Long get99Pct() { - return null; - } - - @Override - public Long get99_9Pct() { - return null; - } - }; -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/monitoring/package-info.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/monitoring/package-info.java deleted file mode 100644 index c6db4c83d25..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/monitoring/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * @author Antony T Curtis {@literal } - */ -package com.linkedin.alpini.base.monitoring; diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/AsyncPool.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/AsyncPool.java deleted file mode 100644 index f42156c710f..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/AsyncPool.java +++ /dev/null @@ -1,108 +0,0 @@ -package com.linkedin.alpini.base.pool; - -import com.linkedin.alpini.base.pool.impl.AsyncPoolImpl; -import com.linkedin.alpini.base.pool.impl.RateLimitedCreateLifeCycle; -import com.linkedin.alpini.base.registry.Shutdownable; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionException; -import java.util.concurrent.Executor; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import javax.annotation.Nonnull; - - -/** - * @author Antony T Curtis {@literal } - */ -public interface AsyncPool { - void start(); - - int size(); - - CompletableFuture acquire(); - - void release(T entity); - - void dispose(T entity); - - default CompletableFuture shutdownPool() { - if (this instanceof Shutdownable) { - ((Shutdownable) this).shutdown(); - return CompletableFuture.supplyAsync(() -> { - try { - ((Shutdownable) this).waitForShutdown(); - return null; - } catch (InterruptedException e) { - throw new CompletionException(e); - } - }); - } else { - return CompletableFuture.completedFuture(null); - } - } - - interface LifeCycle { - CompletableFuture create(); - - CompletableFuture testOnRelease(T entity); - - CompletableFuture testAfterIdle(T entity); - - CompletableFuture destroy(T entity); - - default CompletableFuture shutdown() { - return CompletableFuture.completedFuture(null); - } - - default W unwrap(Class iface) { - if (isWrapperFor(iface)) { - return iface.cast(this); - } else { - throw new IllegalArgumentException(); - } - } - - default boolean isWrapperFor(Class iface) { - return iface.isAssignableFrom(getClass()); - } - } - - PoolStats getPoolStats(); - - static AsyncPool create( - @Nonnull LifeCycle lifeCycle, - @Nonnull Executor executor, - int maxConcurrentCreate, - int maxWaiters, - int minimumEntities, - int maximumEntities, - long maxIdleTime, - @Nonnull TimeUnit maxIdleUnit) { - return new AsyncPoolImpl<>( - lifeCycle, - executor, - maxConcurrentCreate, - maxWaiters, - minimumEntities, - maximumEntities, - maxIdleTime, - maxIdleUnit); - } - - static LifeCycle rateLimitCreate( - @Nonnull AsyncPool.LifeCycle lifeCycle, - @Nonnull ScheduledExecutorService executor, - long minimumTimeDelay, - long maximumTimeDelay, - long timeIncrement, - @Nonnull TimeUnit unit) { - return new RateLimitedCreateLifeCycle<>( - lifeCycle, - executor, - minimumTimeDelay, - maximumTimeDelay, - timeIncrement, - unit); - } - -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/AsyncQOSPool.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/AsyncQOSPool.java deleted file mode 100644 index 02404788e3e..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/AsyncQOSPool.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.linkedin.alpini.base.pool; - -import com.linkedin.alpini.base.pool.impl.AsyncQOSPoolImpl; -import com.linkedin.alpini.base.queuing.QOSPolicy; -import com.linkedin.alpini.consts.QOS; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; -import java.util.concurrent.TimeUnit; - - -/** - * @author Antony T Curtis {@literal } - */ -public interface AsyncQOSPool extends AsyncPool { - CompletableFuture acquire(String queueName, QOS qos); - - static AsyncQOSPool create( - LifeCycle lifeCycle, - QOSPolicy.StaticConfig qosPolicyConfig, - Executor executor, - int maxConcurrentCreate, - int minimumEntities, - int maximumEntities, - long maxIdleTime, - TimeUnit maxIdleUnit) { - return new AsyncQOSPoolImpl<>( - lifeCycle, - qosPolicyConfig, - executor, - maxConcurrentCreate, - minimumEntities, - maximumEntities, - maxIdleTime, - maxIdleUnit); - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/PoolStats.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/PoolStats.java deleted file mode 100644 index d2c577220aa..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/PoolStats.java +++ /dev/null @@ -1,194 +0,0 @@ -package com.linkedin.alpini.base.pool; - -/** - * @author Antony T Curtis {@literal } - */ -public interface PoolStats { - /** - * Get the total number of pool objects created between - * the starting of the Pool and the call to getStats(). - * Does not include create errors. - * @return The total number of pool objects created - */ - long getTotalCreated(); - - /** - * Get the total number of pool objects destroyed between - * the starting of the Pool and the call to getStats(). - * Includes lifecycle validation failures, disposes, - * and timed-out objects, but does not include destroy errors. - * @return The total number of pool objects destroyed - */ - long getTotalDestroyed(); - - /** - * Get the total number of lifecycle create errors between - * the starting of the Pool and the call to getStats(). - * @return The total number of create errors - */ - long getTotalCreateErrors(); - - /** - * Get the total number of lifecycle destroy errors between - * the starting of the Pool and the call to getStats(). - * @return The total number of destroy errors - */ - long getTotalDestroyErrors(); - - /** - * Get the number of pool objects checked out at the time of - * the call to getStats(). - * @return The number of checked out pool objects - */ - double getCheckedOut1min(); - - double getCheckedOut5min(); - - double getCheckedOut15min(); - - int getMaxCheckedOut1min(); - - double getCheckedOutTimeAvg(); - - double getCheckedOutTime50Pct(); - - double getCheckedOutTime95Pct(); - - double getCheckedOutTime99Pct(); - - /** - * Get the configured maximum pool size. - * @return The maximum pool size - */ - int getMaxPoolSize(); - - /** - * Get the configured minimum pool size. - * @return The minimum pool size - */ - int getMinPoolSize(); - - /** - * Get the pool size at the time of the call to getStats(). - * @return The pool size - */ - int getPoolSize(); - - /** - * Get the number of objects that are idle(not checked out) - * in the pool. - * @return The number of idle objects - */ - int getIdleCount(); - - double getWaiters1min(); - - double getWaiters5min(); - - double getWaiters15min(); - - /** - * Get the average wait time to get a pooled object. - * @return The average wait time. - */ - double getWaitTimeAvg(); - - /** - * Get the 50 percentage wait time to get a pooled object. - * @return 50 percentage wait time. - */ - double getWaitTime50Pct(); - - /** - * Get the 95 percentage wait time to get a pooled object. - * @return 95 percentage wait time. - */ - double getWaitTime95Pct(); - - /** - * Get the 99 percentage wait time to get a pooled object. - * @return 99 percentage wait time. - */ - double getWaitTime99Pct(); - - /** - * Get stats collected from {@link AsyncPool.LifeCycle} - * @return Lifecycle stats - */ - LifeCycleStats getLifecycleStats(); - - interface LifeCycleStats { - /** - * Get the average time to create an object. - * @return The average create time. - */ - double getCreateTimeAvg(); - - /** - * Get the 50 percentage time to create an object. - * @return 50 percentage create time. - */ - double getCreateTime50Pct(); - - /** - * Get the 95 percentage time to create an object. - * @return 95 percentage create time. - */ - double getCreateTime95Pct(); - - /** - * Get the 99 percentage time to create an object. - * @return 99 percentage create time. - */ - double getCreateTime99Pct(); - - /** - * Get the average time to create an object. - * @return The average create time. - */ - double getTestTimeAvg(); - - /** - * Get the 50 percentage time to create an object. - * @return 50 percentage create time. - */ - double getTestTime50Pct(); - - /** - * Get the 95 percentage time to create an object. - * @return 95 percentage create time. - */ - double getTestTime95Pct(); - - /** - * Get the 99 percentage time to create an object. - * @return 99 percentage create time. - */ - double getTestTime99Pct(); - - /** - * Get the average time to create an object. - * @return The average create time. - */ - double getDestroyTimeAvg(); - - /** - * Get the 50 percentage time to create an object. - * @return 50 percentage create time. - */ - double getDestroyTime50Pct(); - - /** - * Get the 95 percentage time to create an object. - * @return 95 percentage create time. - */ - double getDestroyTime95Pct(); - - /** - * Get the 99 percentage time to create an object. - * @return 99 percentage create time. - */ - double getDestroyTime99Pct(); - - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/impl/AsyncPoolImpl.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/impl/AsyncPoolImpl.java deleted file mode 100644 index ee280407ab6..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/impl/AsyncPoolImpl.java +++ /dev/null @@ -1,656 +0,0 @@ -package com.linkedin.alpini.base.pool.impl; - -import com.linkedin.alpini.base.misc.Time; -import com.linkedin.alpini.base.monitoring.CallCompletion; -import com.linkedin.alpini.base.monitoring.CallTracker; -import com.linkedin.alpini.base.pool.AsyncPool; -import com.linkedin.alpini.base.pool.PoolStats; -import com.linkedin.alpini.base.registry.ShutdownableResource; -import com.linkedin.alpini.base.statistics.LongStats; -import java.util.IdentityHashMap; -import java.util.Objects; -import java.util.concurrent.CancellationException; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executor; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Function; -import java.util.function.Supplier; -import javax.annotation.Nonnull; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** - * @author Antony T Curtis {@literal } - */ -public class AsyncPoolImpl implements AsyncPool, ShutdownableResource { - private static final Logger LOG = LogManager.getLogger(AsyncPoolImpl.class); - - private final LifeCycle _lifeCycle; - private final ConcurrentLinkedQueue _idleQueue; - private final ConcurrentLinkedQueue> _waiters; - private final IdentityHashMap _checkedOut; - private final AtomicInteger _totalEntities; - private final AtomicInteger _totalWaiters; - private final CallTracker _waitersCallTracker; - private final CallTracker _checkedOutCallTracker; - private final int _minimumEntities; - private final int _maximumEntities; - private final long _maxIdleTime; - private final int _maxWaiters; - private final Executor _executor; - private final Semaphore _concurrentCreate; - private CompletableFuture _shutdown; - private CompletableFuture _shutdownCompleted; - private ShutdownException _shutdownException; - - public AsyncPoolImpl( - LifeCycle lifeCycle, - Executor executor, - int maxConcurrentCreate, - int maxWaiters, - int minimumEntities, - int maximumEntities, - long maxIdleTime, - TimeUnit maxIdleUnit) { - _lifeCycle = Objects.requireNonNull(lifeCycle, "lifeCycle"); - _executor = Objects.requireNonNull(executor, "executor"); - checkLowerBound(maxConcurrentCreate, 1, "maxConcurrentCreate"); - _maxWaiters = checkLowerBound(maxWaiters, 1, "maxWaiters"); - _maxIdleTime = Objects.requireNonNull(maxIdleUnit, "maxIdleUnit").toNanos(maxIdleTime); - if (_maxIdleTime < 1) { - throw new IllegalArgumentException("maxIdleTime"); - } - _minimumEntities = checkLowerBound(minimumEntities, 0, "minimumEntries"); - _maximumEntities = checkLowerBound(maximumEntities, minimumEntities, "maximumEntries"); - _idleQueue = new ConcurrentLinkedQueue<>(); - _waiters = new ConcurrentLinkedQueue<>(); - _checkedOut = new IdentityHashMap<>(); - _totalEntities = new AtomicInteger(); - _totalWaiters = new AtomicInteger(); - _waitersCallTracker = createCallTracker(); - _checkedOutCallTracker = createCallTracker(); - _concurrentCreate = new Semaphore(maxConcurrentCreate); - } - - protected CallTracker createCallTracker() { - return CallTracker.create(); - } - - private static int checkLowerBound(int value, int bound, String message) { - if (value < bound) { - throw new IllegalArgumentException(message); - } - return value; - } - - @Override - public void start() { - if (_shutdown == null && _totalEntities.get() < _minimumEntities && _concurrentCreate.tryAcquire()) { - _totalEntities.incrementAndGet(); - create(); - } - } - - protected final CallCompletion startWaiters() { - return _waitersCallTracker.startCall(); - } - - protected CompletableFuture checkout(@Nonnull CompletableFuture future, @Nonnull CallCompletion waiter) { - return future.whenComplete((entity, ex) -> { - if (entity != null) { - CallCompletion checkout = _checkedOutCallTracker.startCall(); - CallCompletion cc; - synchronized (_checkedOut) { - cc = _checkedOut.put(entity, checkout); - } - if (cc != null) { - LOG.warn("Entry already checked out {}", entity); - cc.closeWithError(); - } - } - waiter.closeCompletion(entity, ex); - }); - } - - @Override - public CompletableFuture acquire() { - return checkout(acquire0(), startWaiters()); - } - - protected final CompletableFuture acquire0() { - long now = Time.currentTimeMillis(); - IdleEntity idle; - while ((idle = _idleQueue.poll()) != null) { - if (idle._idleNanos + _maxIdleTime < now) { - T entity = idle.get(); - CompletableFuture.supplyAsync(idle, _executor) - .thenCompose(_lifeCycle::testAfterIdle) - .thenAccept(success -> afterTest(success, entity)); - } else { - return CompletableFuture.completedFuture(idle.get()); - } - } - CompletableFuture future = new CompletableFuture<>(); - if (_shutdown != null) { - synchronized (this) { - future.obtrudeException(_shutdownException); - return future; - } - } - if (_waiters.add(future)) { - int totalWaiters = _totalWaiters.incrementAndGet(); - - outer: while (!future.isDone() && (idle = _idleQueue.poll()) != null) { // SUPPRESS CHECKSTYLE InnerAssignment - if (idle._idleNanos + _maxIdleTime < now) { - T entity = idle.get(); - CompletableFuture.supplyAsync(idle, _executor) - .thenCompose(_lifeCycle::testAfterIdle) - .thenAccept(success -> afterTest(success, entity)); - } else { - CompletableFuture waiter; - while ((waiter = _waiters.poll()) != future) { - _totalWaiters.getAndDecrement(); - if (waiter.complete(idle.get())) { - continue outer; - } - } - future.obtrudeValue(idle.get()); - return future; - } - } - if (_idleQueue.isEmpty() && _totalEntities.get() < _maximumEntities && _concurrentCreate.tryAcquire()) { - _totalEntities.incrementAndGet(); - create(); - } - - if (totalWaiters > _maxWaiters) { - CompletableFuture waiter; - int rejected = 0; - TooManyWaitersException rejectedException = new TooManyWaitersException(); - while (totalWaiters + rejected > _maximumEntities && (waiter = _waiters.poll()) != null) { // SUPPRESS - // CHECKSTYLE - // InnerAssignment - rejected--; - waiter.completeExceptionally(rejectedException); - } - _totalWaiters.addAndGet(rejected); - } - } else { - future.obtrudeException(new IllegalStateException()); - } - return future; - } - - private void afterTest(boolean success, T entity) { - if (success && _shutdown == null) { - CompletableFuture future; - while ((future = _waiters.poll()) != null) { - _totalWaiters.getAndDecrement(); - if (future.complete(entity)) { - return; - } - } - _idleQueue.add(new IdleEntity(entity)); - } else { - dispose0(entity); - } - } - - @Override - public void release(T entity) { - synchronized (_checkedOut) { - CallCompletion cc = _checkedOut.remove(entity); - if (cc == null) { - throw new IllegalStateException("Cannot release object which was not checked out"); - } - cc.close(); - } - release0(entity); - } - - protected final void release0(T entity) { - _lifeCycle.testOnRelease(Objects.requireNonNull(entity)).exceptionally(ex -> { - LOG.warn("error in lifecycle testOnRelease", ex); - return false; - }).thenAccept(success -> afterTest(success, entity)); - } - - @Override - public void dispose(T entity) { - synchronized (_checkedOut) { - CallCompletion cc = _checkedOut.remove(entity); - if (cc == null) { - throw new IllegalStateException("Cannot dispose object which was not checked out"); - } - cc.closeWithError(); - } - release0(entity); - } - - protected final void dispose0(T entity) { - _lifeCycle.destroy(Objects.requireNonNull(entity)).exceptionally(ex -> { - LOG.warn("error in lifecycle destroy", ex); - return null; - }).thenRun(() -> { - if (_shutdown == null && _minimumEntities > _totalEntities.get() - 1 && _concurrentCreate.tryAcquire()) { - create(); - return; - } - int total = _totalEntities.decrementAndGet(); - if (_shutdown != null && total == 0) { - _shutdown.complete(Boolean.TRUE); - } - }); - } - - private void create() { - if (_shutdown != null) { - _concurrentCreate.release(); - if (_totalEntities.decrementAndGet() == 0) { - _shutdown.complete(Boolean.TRUE); - } - } - _lifeCycle.create().whenComplete((newEntity, ex) -> { - _concurrentCreate.release(); - if (ex != null) { - LOG.warn("error in lifecycle create", ex); - } - }).thenAccept(newEntity -> { - if (newEntity != null) { - afterTest(true, newEntity); - } else { - int total = _totalEntities.decrementAndGet(); - if (_shutdown != null && total == 0) { - _shutdown.complete(Boolean.TRUE); - } - } - }).thenRun(this::start); - } - - @Override - public int size() { - return _totalEntities.get(); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean isShutdown() { - return _shutdown != null; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean isTerminated() { - return isShutdown() && _shutdown.isDone(); - } - - /** - * {@inheritDoc} - */ - @Override - public synchronized void shutdown() { - if (_shutdown == null) { - _shutdownException = new ShutdownException(); - _shutdown = new CompletableFuture<>(); - _shutdownCompleted = _shutdown.thenCompose(ignore -> _lifeCycle.shutdown()); - - CompletableFuture future; - while ((future = _waiters.poll()) != null) { - _totalWaiters.getAndDecrement(); - future.completeExceptionally(_shutdownException); - } - - IdleEntity idle; - while ((idle = _idleQueue.poll()) != null) { - dispose0(idle.get()); - } - - if (_totalEntities.get() == 0) { - _shutdown.complete(Boolean.TRUE); - } - } - } - - /** - * {@inheritDoc} - */ - @Override - public CompletableFuture shutdownPool() { - shutdown(); - return _shutdownCompleted.thenApply(Function.identity()); - } - - /** - * {@inheritDoc} - */ - @Override - public void waitForShutdown() throws InterruptedException, IllegalStateException { - CompletableFuture shutdown = _shutdownCompleted; - if (shutdown == null) { - throw new IllegalStateException(); - } else { - try { - shutdown.get(); - } catch (ExecutionException e) { - throw new InterruptedException(e.getCause().getMessage()); - } - } - } - - /** - * {@inheritDoc} - */ - @Override - public void waitForShutdown(long timeoutInMs) throws InterruptedException, IllegalStateException, TimeoutException { - CompletableFuture shutdown = _shutdownCompleted; - if (shutdown == null) { - throw new IllegalStateException(); - } else { - try { - shutdown.get(timeoutInMs, TimeUnit.MILLISECONDS); - } catch (ExecutionException e) { - throw new InterruptedException(e.getCause().getMessage()); - } - } - } - - @Override - public PoolStats getPoolStats() { - CallTracker.CallStats createStats; - CallTracker.CallStats testStats; - CallTracker.CallStats destroyStats; - - if (_lifeCycle.isWrapperFor(LifeCycleStatsCollector.class)) { - LifeCycleStatsCollector statsCollector = _lifeCycle.unwrap(LifeCycleStatsCollector.class); - createStats = statsCollector.getCreateCallStats(); - testStats = statsCollector.getTestCallStats(); - destroyStats = statsCollector.getDestroyCallStats(); - } else { - createStats = NullStats.getInstance(); - testStats = NullStats.getInstance(); - destroyStats = NullStats.getInstance(); - } - - CallTracker.CallStats waitStats = _waitersCallTracker.getCallStats(); - CallTracker.CallStats checkedOut = _checkedOutCallTracker.getCallStats(); - - return new PoolStatsImpl( - _maximumEntities, - _minimumEntities, - _totalEntities.get(), - _idleQueue.size(), - createStats, - testStats, - destroyStats, - waitStats, - checkedOut); - } - - private static class PoolStatsImpl implements PoolStats { - private final int _maxPoolSize; - private final int _minPoolSize; - private final int _poolSize; - private final int _idleCount; - private final CallTracker.CallStats _createStats; - private final CallTracker.CallStats _testStats; - private final CallTracker.CallStats _destroyStats; - private final CallTracker.CallStats _waitStats; - private final CallTracker.CallStats _checkedOut; - - private PoolStatsImpl( - int maxPoolSize, - int minPoolSize, - int poolSize, - int idleCount, - CallTracker.CallStats createStats, - CallTracker.CallStats testStats, - CallTracker.CallStats destroyStats, - CallTracker.CallStats waitStats, - CallTracker.CallStats checkedOut) { - _maxPoolSize = maxPoolSize; - _minPoolSize = minPoolSize; - _poolSize = poolSize; - _idleCount = idleCount; - _createStats = createStats; - _testStats = testStats; - _destroyStats = destroyStats; - _waitStats = waitStats; - _checkedOut = checkedOut; - } - - @Override - public long getTotalCreated() { - return _createStats.getCallCountTotal() - _createStats.getErrorCountTotal(); - } - - @Override - public long getTotalDestroyed() { - return _destroyStats.getCallCountTotal() - _destroyStats.getErrorCountTotal(); - } - - @Override - public long getTotalCreateErrors() { - return _createStats.getErrorCountTotal(); - } - - @Override - public long getTotalDestroyErrors() { - return _destroyStats.getErrorCountTotal(); - } - - @Override - public double getCheckedOut1min() { - return _checkedOut.getAverageConcurrency1min(); - } - - @Override - public double getCheckedOut5min() { - return _checkedOut.getAverageConcurrency5min(); - } - - @Override - public double getCheckedOut15min() { - return _checkedOut.getAverageConcurrency15min(); - } - - @Override - public int getMaxCheckedOut1min() { - return _checkedOut.getMaxConcurrency1min(); - } - - @Override - public double getCheckedOutTimeAvg() { - return nanosToMillis(_checkedOut.getCallTimeStats().getAverage()); - } - - @Override - public double getCheckedOutTime50Pct() { - return nanosToMillis(_checkedOut.getCallTimeStats().get50Pct()); - } - - @Override - public double getCheckedOutTime95Pct() { - return nanosToMillis(_checkedOut.getCallTimeStats().get95Pct()); - } - - @Override - public double getCheckedOutTime99Pct() { - return nanosToMillis(_checkedOut.getCallTimeStats().get99Pct()); - } - - @Override - public int getMaxPoolSize() { - return _maxPoolSize; - } - - @Override - public int getMinPoolSize() { - return _minPoolSize; - } - - @Override - public int getPoolSize() { - return _poolSize; - } - - @Override - public int getIdleCount() { - return _idleCount; - } - - @Override - public double getWaiters1min() { - return _waitStats.getAverageConcurrency1min(); - } - - @Override - public double getWaiters5min() { - return _waitStats.getAverageConcurrency5min(); - } - - @Override - public double getWaiters15min() { - return _waitStats.getAverageConcurrency15min(); - } - - @Override - public double getWaitTimeAvg() { - return nanosToMillis(_waitStats.getCallTimeStats().getAverage()); - } - - @Override - public double getWaitTime50Pct() { - return nanosToMillis(_waitStats.getCallTimeStats().get50Pct()); - } - - @Override - public double getWaitTime95Pct() { - return nanosToMillis(_waitStats.getCallTimeStats().get95Pct()); - } - - @Override - public double getWaitTime99Pct() { - return nanosToMillis(_waitStats.getCallTimeStats().get99Pct()); - } - - @Override - public LifeCycleStats getLifecycleStats() { - return new LifeCycleStatsImpl( - _createStats.getCallTimeStats(), - _testStats.getCallTimeStats(), - _destroyStats.getCallTimeStats()); - } - } - - private static class LifeCycleStatsImpl implements PoolStats.LifeCycleStats { - private final LongStats _createCallStats; - private final LongStats _testCallStats; - private final LongStats _destroyCallStats; - - private LifeCycleStatsImpl(LongStats createCallStats, LongStats testCallStats, LongStats destroyCallStats) { - _createCallStats = createCallStats; - _testCallStats = testCallStats; - _destroyCallStats = destroyCallStats; - } - - @Override - public double getCreateTimeAvg() { - return nanosToMillis(_createCallStats.getAverage()); - } - - @Override - public double getCreateTime50Pct() { - return nanosToMillis(_createCallStats.get50Pct()); - } - - @Override - public double getCreateTime95Pct() { - return nanosToMillis(_createCallStats.get95Pct()); - } - - @Override - public double getCreateTime99Pct() { - return nanosToMillis(_createCallStats.get99Pct()); - } - - @Override - public double getTestTimeAvg() { - return nanosToMillis(_testCallStats.getAverage()); - } - - @Override - public double getTestTime50Pct() { - return nanosToMillis(_testCallStats.get50Pct()); - } - - @Override - public double getTestTime95Pct() { - return nanosToMillis(_testCallStats.get95Pct()); - } - - @Override - public double getTestTime99Pct() { - return nanosToMillis(_testCallStats.get99Pct()); - } - - @Override - public double getDestroyTimeAvg() { - return nanosToMillis(_destroyCallStats.getAverage()); - } - - @Override - public double getDestroyTime50Pct() { - return nanosToMillis(_destroyCallStats.get50Pct()); - } - - @Override - public double getDestroyTime95Pct() { - return nanosToMillis(_destroyCallStats.get95Pct()); - - } - - @Override - public double getDestroyTime99Pct() { - return nanosToMillis(_destroyCallStats.get99Pct()); - } - } - - private static double nanosToMillis(double nanos) { - return Double.isFinite(nanos) ? nanos / 1000000.0 : Double.NaN; - } - - private static double nanosToMillis(Long nanos) { - return nanos != null ? nanos / 1000000.0 : Double.NaN; - } - - private class IdleEntity implements Supplier { - private final long _idleNanos; - private final T _idleEntity; - - private IdleEntity(T idleEntity) { - _idleNanos = Time.nanoTime(); - _idleEntity = idleEntity; - } - - @Override - public T get() { - return _idleEntity; - } - } - - public static class TooManyWaitersException extends CancellationException { - } - - public static class ShutdownException extends CancellationException { - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/impl/AsyncQOSPoolImpl.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/impl/AsyncQOSPoolImpl.java deleted file mode 100644 index b934e0e7c35..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/impl/AsyncQOSPoolImpl.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.linkedin.alpini.base.pool.impl; - -import com.linkedin.alpini.base.pool.AsyncQOSPool; -import com.linkedin.alpini.base.queuing.QOSBasedRequestRunnable; -import com.linkedin.alpini.base.queuing.QOSPolicy; -import com.linkedin.alpini.base.queuing.SimpleQueue; -import com.linkedin.alpini.consts.QOS; -import java.util.Objects; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; -import java.util.concurrent.TimeUnit; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** - * @author Antony T Curtis {@literal } - */ -public class AsyncQOSPoolImpl extends AsyncPoolImpl implements AsyncQOSPool { - private static final Logger LOG = LogManager.getLogger(AsyncQOSPool.class); - private final SimpleQueue _pending; - - public AsyncQOSPoolImpl( - LifeCycle lifeCycle, - QOSPolicy.StaticConfig qosPolicyConfig, - Executor executor, - int maxConcurrentCreate, - int minimumEntities, - int maximumEntities, - long maxIdleTime, - TimeUnit maxIdleUnit) { - this( - lifeCycle, - QOSPolicy.getQOSPolicy(Objects.requireNonNull(qosPolicyConfig, "qosPolicyConfig")), - executor, - maxConcurrentCreate, - minimumEntities, - maximumEntities, - maxIdleTime, - maxIdleUnit); - } - - private AsyncQOSPoolImpl( - LifeCycle lifeCycle, - SimpleQueue pendingQueue, - Executor executor, - int maxConcurrentCreate, - int minimumEntities, - int maximumEntities, - long maxIdleTime, - TimeUnit maxIdleUnit) { - super( - lifeCycle, - executor, - maxConcurrentCreate, - minimumEntities, - minimumEntities, - maximumEntities, - maxIdleTime, - maxIdleUnit); - _pending = Objects.requireNonNull(pendingQueue, "pendingQueue"); - } - - @Override - public CompletableFuture acquire() { - return checkout(acquire0("", QOS.NORMAL), startWaiters()); - } - - @Override - public CompletableFuture acquire(String queueName, QOS qos) { - return checkout(acquire0(Objects.requireNonNull(queueName), Objects.requireNonNull(qos)), startWaiters()); - } - - protected final CompletableFuture acquire0(String queueName, QOS qos) { - CompletableFuture future = super.acquire0(); - if (future.isCompletedExceptionally()) { - return future; - } - try { - Waiter w = new Waiter(queueName, qos, new CompletableFuture<>()); - - if (_pending.add(w)) { - return w._future; - } else { - w._future.obtrudeException(new IllegalStateException()); - return w._future; - } - } finally { - future.whenComplete(this::issue); - } - } - - private void issue(T entity, Throwable ex) { - Waiter w; - if (ex == null) { - while ((w = _pending.poll()) != null) { - if (w._future.complete(entity)) { - return; - } - } - release0(entity); - } else { - while ((w = _pending.poll()) != null) { - if (w._future.completeExceptionally(ex)) { - return; - } - } - LOG.warn("Dropped exception", ex); - } - } - - private class Waiter extends QOSBasedRequestRunnable { - private final CompletableFuture _future; - - public Waiter(String queueName, QOS qos, CompletableFuture future) { - super(queueName, qos, null); - _future = future; - } - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/impl/LifeCycleFilter.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/impl/LifeCycleFilter.java deleted file mode 100644 index 92d006c6800..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/impl/LifeCycleFilter.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.linkedin.alpini.base.pool.impl; - -import com.linkedin.alpini.base.pool.AsyncPool; -import java.util.Objects; -import java.util.concurrent.CompletableFuture; - - -/** - * @author Antony T Curtis {@literal } - */ -public class LifeCycleFilter implements AsyncPool.LifeCycle { - private final AsyncPool.LifeCycle _lifeCycle; - - public LifeCycleFilter(AsyncPool.LifeCycle lifeCycle) { - _lifeCycle = Objects.requireNonNull(lifeCycle); - } - - @Override - public CompletableFuture create() { - return _lifeCycle.create(); - } - - @Override - public CompletableFuture testOnRelease(T entity) { - return _lifeCycle.testOnRelease(entity); - } - - @Override - public CompletableFuture testAfterIdle(T entity) { - return _lifeCycle.testAfterIdle(entity); - } - - @Override - public CompletableFuture destroy(T entity) { - return _lifeCycle.destroy(entity); - } - - @Override - public W unwrap(Class iface) { - if (iface.isAssignableFrom(getClass())) { - return iface.cast(this); - } else { - return _lifeCycle.unwrap(iface); - } - } - - @Override - public boolean isWrapperFor(Class iface) { - return iface.isAssignableFrom(getClass()) || _lifeCycle.isWrapperFor(iface); - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/impl/LifeCycleStatsCollector.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/impl/LifeCycleStatsCollector.java deleted file mode 100644 index 164020354cb..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/impl/LifeCycleStatsCollector.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.linkedin.alpini.base.pool.impl; - -import com.linkedin.alpini.base.monitoring.CallCompletion; -import com.linkedin.alpini.base.monitoring.CallTracker; -import com.linkedin.alpini.base.pool.AsyncPool; -import java.util.concurrent.CompletableFuture; -import javax.annotation.Nonnull; - - -/** - * @author Antony T Curtis {@literal } - */ -public class LifeCycleStatsCollector extends LifeCycleFilter { - private final CallTracker _createCallTracker; - private final CallTracker _testCallTracker; - private final CallTracker _destroyCallTracker; - - public LifeCycleStatsCollector(@Nonnull AsyncPool.LifeCycle lifeCycle) { - super(lifeCycle); - - _createCallTracker = createCallTracker(); - _testCallTracker = createCallTracker(); - _destroyCallTracker = createCallTracker(); - } - - protected CallTracker createCallTracker() { - return CallTracker.create(); - } - - @Override - public CompletableFuture create() { - CallCompletion completion = _createCallTracker.startCall(); - return super.create().whenComplete(completion::closeCompletion); - } - - public CallTracker.CallStats getCreateCallStats() { - return _createCallTracker.getCallStats(); - } - - @Override - public CompletableFuture testOnRelease(T entity) { - CallCompletion completion = _testCallTracker.startCall(); - return super.testOnRelease(entity).whenComplete(completion::closeCompletion); - } - - @Override - public CompletableFuture testAfterIdle(T entity) { - CallCompletion completion = _testCallTracker.startCall(); - return super.testAfterIdle(entity).whenComplete(completion::closeCompletion); - } - - public CallTracker.CallStats getTestCallStats() { - return _testCallTracker.getCallStats(); - } - - @Override - public CompletableFuture destroy(T entity) { - CallCompletion completion = _destroyCallTracker.startCall(); - return super.destroy(entity).whenComplete(completion::closeCompletion); - } - - public CallTracker.CallStats getDestroyCallStats() { - return _destroyCallTracker.getCallStats(); - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/impl/NullStats.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/impl/NullStats.java deleted file mode 100644 index 1f2794f95e1..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/impl/NullStats.java +++ /dev/null @@ -1,166 +0,0 @@ -package com.linkedin.alpini.base.pool.impl; - -import com.linkedin.alpini.base.monitoring.CallTracker; -import com.linkedin.alpini.base.statistics.LongStats; - - -/** - * @author Antony T Curtis {@literal } - */ -public class NullStats implements CallTracker.CallStats { - private static final NullStats INSTANCE = new NullStats(); - - public static CallTracker.CallStats getInstance() { - return INSTANCE; - } - - private NullStats() { - } - - @Override - public long getCallCountTotal() { - return 0; - } - - @Override - public long getCallStartCountTotal() { - return 0; - } - - @Override - public long getErrorCountTotal() { - return 0; - } - - @Override - public int getConcurrency() { - return 0; - } - - @Override - public double getAverageConcurrency1min() { - return 0; - } - - @Override - public double getAverageConcurrency5min() { - return 0; - } - - @Override - public double getAverageConcurrency15min() { - return 0; - } - - @Override - public int getMaxConcurrency1min() { - return 0; - } - - @Override - public int getMaxConcurrency5min() { - return 0; - } - - @Override - public int getMaxConcurrency15min() { - return 0; - } - - @Override - public int getStartFrequency1min() { - return 0; - } - - @Override - public int getStartFrequency5min() { - return 0; - } - - @Override - public int getStartFrequency15min() { - return 0; - } - - @Override - public int getErrorFrequency1min() { - return 0; - } - - @Override - public int getErrorFrequency5min() { - return 0; - } - - @Override - public int getErrorFrequency15min() { - return 0; - } - - @Override - public long getOutstandingStartTimeAvg() { - return 0; - } - - @Override - public int getOutstandingCount() { - return 0; - } - - private final LongStats _longStats = new LongStats() { - @Override - public long getLongCount() { - return 0; - } - - @Override - public double getAverage() { - return 0; - } - - @Override - public double getStandardDeviation() { - return Double.NaN; - } - - @Override - public Long getMinimum() { - return null; - } - - @Override - public Long getMaximum() { - return null; - } - - @Override - public Long get50Pct() { - return null; - } - - @Override - public Long get90Pct() { - return null; - } - - @Override - public Long get95Pct() { - return null; - } - - @Override - public Long get99Pct() { - return null; - } - - @Override - public Long get99_9Pct() { - return null; - } - }; - - @Override - public LongStats getCallTimeStats() { - return _longStats; - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/impl/RateLimitedCreateLifeCycle.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/impl/RateLimitedCreateLifeCycle.java deleted file mode 100644 index d4f5416ccec..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/impl/RateLimitedCreateLifeCycle.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.linkedin.alpini.base.pool.impl; - -import com.linkedin.alpini.base.misc.Time; -import com.linkedin.alpini.base.pool.AsyncPool; -import java.util.Objects; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; -import javax.annotation.Nonnull; - - -/** - * @author Antony T Curtis {@literal } - */ -public class RateLimitedCreateLifeCycle extends LifeCycleFilter { - private final ScheduledExecutorService _executor; - private final AtomicLong _lastCreateTime; - private final long _minimumTimeDelay; - private final long _maximumTimeDelay; - private final long _timeIncrement; - private long _timeDelay; - - public RateLimitedCreateLifeCycle( - @Nonnull AsyncPool.LifeCycle lifeCycle, - @Nonnull ScheduledExecutorService executor, - long minimumTimeDelay, - long maximumTimeDelay, - long timeIncrement, - @Nonnull TimeUnit unit) { - super(Objects.requireNonNull(lifeCycle, "lifeCycle")); - _executor = Objects.requireNonNull(executor, "executor"); - Objects.requireNonNull(unit, "unit"); - _minimumTimeDelay = unit.toNanos(positive(minimumTimeDelay)); - _maximumTimeDelay = unit.toNanos(positive(maximumTimeDelay)); - if (_maximumTimeDelay <= _minimumTimeDelay) { - throw new IllegalArgumentException("maximum time must exceed minimum time"); - } - _timeIncrement = unit.toNanos(positive(timeIncrement)); - _lastCreateTime = new AtomicLong(Time.nanoTime()); - } - - private static long positive(long number) { - if (number < 1) { - throw new IllegalArgumentException("time values must be positive"); - } - return number; - } - - @Override - public CompletableFuture create() { - long now = Time.nanoTime(); - - long lastCreateTime = _lastCreateTime.get(); - if (lastCreateTime + Math.max(_timeDelay, _minimumTimeDelay) < now - && _lastCreateTime.compareAndSet(lastCreateTime, now)) { - return super.create(); - } - CompletableFuture future = new CompletableFuture<>(); - while (true) { - long timeDelay = Math.max(_timeDelay, _minimumTimeDelay); - long delta = lastCreateTime + timeDelay - now; - if (_lastCreateTime.compareAndSet(lastCreateTime, lastCreateTime + timeDelay)) { - _executor.schedule(() -> super.create().whenComplete((t, ex) -> { - if (ex != null) { - _timeDelay = Math.min(_maximumTimeDelay, _timeDelay + _timeIncrement); - future.completeExceptionally(ex); - } else { - _timeDelay = 0; - if (!future.complete(t)) { - destroy(t); - } - } - }), delta, TimeUnit.NANOSECONDS); - return future; - } - } - } - - @Override - public CompletableFuture testOnRelease(T entity) { - return super.testOnRelease(entity); - } - - @Override - public CompletableFuture testAfterIdle(T entity) { - return super.testAfterIdle(entity); - } - - @Override - public CompletableFuture destroy(T entity) { - return super.destroy(entity); - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/package-info.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/package-info.java deleted file mode 100644 index 4d2b39c4a31..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/pool/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * @author Antony T Curtis {@literal } - */ -package com.linkedin.alpini.base.pool; diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/AbstractQOS.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/AbstractQOS.java deleted file mode 100644 index c945c806128..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/AbstractQOS.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.linkedin.alpini.base.queuing; - -import com.linkedin.alpini.base.misc.CollectionUtil; -import com.linkedin.alpini.consts.QOS; -import java.util.Arrays; -import java.util.Collections; -import java.util.EnumMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ThreadLocalRandom; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** - * Created by acurtis on 7/27/17. - */ -public abstract class AbstractQOS { - /** QOS order starting from LOW */ - static final List LOW_FIRST = Collections.unmodifiableList(Arrays.asList(QOS.LOW, QOS.HIGH, QOS.NORMAL)); - /** QOS order starting from NORMAL */ - static final List NORMAL_FIRST = Collections.unmodifiableList(Arrays.asList(QOS.NORMAL, QOS.HIGH, QOS.LOW)); - /** QOS order starting from HIGH */ - static final List HIGH_FIRST = Collections.unmodifiableList(Arrays.asList(QOS.HIGH, QOS.NORMAL, QOS.LOW)); - - protected final Logger _log = LogManager.getLogger(getClass()); - - protected final Map _qosBasedAllocations; - protected final int _allocationTotal; - - protected AbstractQOS(Map qosBasedAllocations) { - _qosBasedAllocations = Collections.unmodifiableMap(new EnumMap<>(qosBasedAllocations)); - _allocationTotal = _qosBasedAllocations.values().stream().mapToInt(Integer::intValue).sum(); - - for (QOS qos: QOS.values()) { - if (!_qosBasedAllocations.containsKey(qos)) { - throw new IllegalArgumentException( - "The QOSAllocations must have an entry for all QOS levels. LOW, NORMAL and HIGH. " + "Missing entry for : " - + qos); - } - } - } - - /** - * Computes and returns the order in which the Queues are to be polled/peeked for this request - * @return queue order - */ - protected List getQueuePollOrder() { - int nextInt = ThreadLocalRandom.current().nextInt(_allocationTotal); - - if ((nextInt -= _qosBasedAllocations.get(QOS.LOW)) < 0) { // SUPPRESS CHECKSTYLE InnerAssignment - return LOW_FIRST; - } else if (nextInt < _qosBasedAllocations.get(QOS.NORMAL)) { - return NORMAL_FIRST; - } else { - return HIGH_FIRST; - } - } - - public static Map getDefaultQOSAllocation() { - return CollectionUtil.mapOf(QOS.LOW, 5, QOS.NORMAL, 15, QOS.HIGH, 80); - } - -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/AbstractQOSBasedQueue.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/AbstractQOSBasedQueue.java deleted file mode 100644 index bf451d9be5a..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/AbstractQOSBasedQueue.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.linkedin.alpini.base.queuing; - -import com.linkedin.alpini.consts.QOS; -import java.util.List; -import java.util.Map; - - -/** - * Abstract base class for QOS priority queues. - * - * @author acurtis - */ -public abstract class AbstractQOSBasedQueue extends AbstractQOS - implements SimpleQueue { - public AbstractQOSBasedQueue(Map qosBasedAllocations) { - super(qosBasedAllocations); - - _log.debug("QOS Based Allocations are : {}", _qosBasedAllocations); - } - - protected String getQueueName(T e) { - return e._queueName != null ? e._queueName : ""; - } - - protected QOS getQOS(T e) { - return e._qos != null ? e._qos : QOS.NORMAL; - } - - @Override - public T poll() { - final List order = getQueuePollOrder(); - T next = getElement(order); - - if (next != null) { - _log.trace("Polled {} QOS element from queue {}", next._qos, next._queueName); - } - - return next; - } - - /** - * Returns or removes an element from one of the specified queues. - * @param viewOrder order to check the queues in - * @return the next element; null if queue is empty - */ - abstract T getElement(List viewOrder); - -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/QOSBasedMultiQueue.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/QOSBasedMultiQueue.java deleted file mode 100644 index 9c11d4f759c..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/QOSBasedMultiQueue.java +++ /dev/null @@ -1,183 +0,0 @@ -package com.linkedin.alpini.base.queuing; - -import com.linkedin.alpini.consts.QOS; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Semaphore; -import java.util.concurrent.atomic.AtomicReference; -import javax.annotation.Nonnull; - - -/** - * A fair multi-queue based upon a ring topology. - * For each queue name, a separate queue exists and is inserted into the ring. - * Reading items from this queue involves examining each queue in order around the ring. - * - * The ring only grows in size but that is okay since the number of possible queues is - * a finite low number. - * - * @author acurtis - */ -public class QOSBasedMultiQueue extends AbstractQOSBasedQueue { - /** Map which translate a {@code queueName} to its entry in the ring */ - private final ConcurrentHashMap _queues; - /** Tail of the ring. {@code _ringTail->next} is the first entry in the ring */ - private final AtomicReference _ringTail; - /** Semaphore keeps track of the number of entries added to this queue */ - private final Semaphore _active; - /** Constants determining the maximum number of entries permitted per {@code queueName} */ - private final int _maxPerQueue; - private final int _hardMaxPerQueue; - - public QOSBasedMultiQueue() { - this(0, getDefaultQOSAllocation()); - } - - public QOSBasedMultiQueue(int maxPerQueue, Map qosBasedAllocations) { - this(maxPerQueue, (int) Math.min((long) (maxPerQueue * 1.10), Integer.MAX_VALUE), qosBasedAllocations); - } - - public QOSBasedMultiQueue(int maxPerQueue, int hardMaxPerQueue, Map qosBasedAllocations) { - super(qosBasedAllocations); - _queues = new ConcurrentHashMap<>(); - // By creating a Ring entry, we don't have to handle the special case where there is no entries in the ring. - RingEntry init = new RingEntry(""); - _ringTail = new AtomicReference<>(init); - _queues.put(init._name, init); - _maxPerQueue = maxPerQueue < 1 ? Integer.MAX_VALUE : maxPerQueue; - _hardMaxPerQueue = Math.max(_maxPerQueue, hardMaxPerQueue); - _active = new Semaphore(0); - } - - /** - * Returns a queue limit for a specified {@link QOS}. - * @param qos QOS. - * @return limit. - */ - protected int getMaxPerQueue(QOS qos) { - return qos != QOS.HIGH ? _maxPerQueue : _hardMaxPerQueue; - } - - /** - * Creates a QOS based queue for a ring element. One of these is used per named queue. - * By default, this instantiates an instance of {@link QOSBasedQueue}. - * @return {@link AbstractQOSBasedQueue} instance. - */ - protected AbstractQOSBasedQueue newQOSBasedQueue() { - return new QOSBasedQueue<>(); - } - - /** - * Returns the ring entry for {@code queueName} or creates a new ring entry as required. - * @param queueName name of ring entry - * @return ring entry. - */ - protected RingEntry getRingEntry(String queueName) { - RingEntry entry = _queues.get(queueName); - if (entry == null) { - RingEntry newEntry = new RingEntry(queueName); - entry = _queues.putIfAbsent(queueName, newEntry); - if (entry == null) { - entry = newEntry; - - // Insert the new ring element into the ring. - RingEntry tail; - do { - tail = _ringTail.get(); - entry._next = tail._next; - } while (!_ringTail.compareAndSet(tail, entry)); - tail._next = entry; - } - } - return entry; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean add(@Nonnull T e) { - String queueName = getQueueName(e); - QOS qos = getQOS(e); - RingEntry entry = getRingEntry(queueName); - - int queueSize = entry._queue.size(); - int maxPerQueue = getMaxPerQueue(qos); - if (queueSize >= maxPerQueue) { - _log.trace( - "Unable to add {} QOS element to queue {}" + " : queueSize {} >= {}", - qos, - e._queueName, - queueSize, - maxPerQueue); - return false; - } - - if (entry._queue.add(e)) { - _active.release(); - return true; - } - return false; - } - - /** - * {@inheritDoc} - */ - @Override - public int size() { - return _active.availablePermits(); - } - - @Override - /** - * {@inheritDoc} - */ - T getElement(List viewOrder) { - RingEntry tail; - RingEntry pos; - - if (!_active.tryAcquire()) { - return null; - } - - // Get the next ring entry and advance the ring position. - do { - tail = _ringTail.get(); - pos = tail._next; - } while (!_ringTail.compareAndSet(tail, pos)); - - final RingEntry first = pos; - for (;; pos = pos._next) { - T elem = pos._queue.getElement(viewOrder); - - if (elem != null) { - // if the ring tail hasn't moved, then set it to our current position - if (first != pos) { - _ringTail.compareAndSet(first, pos); - } - return elem; - } - } - } - - @Override - public boolean isEmpty() { - return _active.availablePermits() == 0; - } - - /** - * An element of the ring, encapsulates a QOSBasedQueue. - */ - private final class RingEntry { - final String _name; - final AbstractQOSBasedQueue _queue; - volatile RingEntry _next; - - private RingEntry(String name) { - _name = name; - _queue = newQOSBasedQueue(); - _next = this; - } - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/QOSBasedQueue.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/QOSBasedQueue.java deleted file mode 100644 index 88ff01da9ba..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/QOSBasedQueue.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.linkedin.alpini.base.queuing; - -import com.linkedin.alpini.consts.QOS; -import java.util.Collections; -import java.util.EnumMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.Semaphore; -import javax.annotation.Nonnull; - - -/** - * Implementation of {@link SimpleQueue}. - * Internally, it maintains separate queues for each QOS level and responds to poll() or peek() requests from any one of the queues - * (probabilistically). - * Addition to this queue, causes the element to be queued together with elements of the same QOS type. - * - * Each sub-queue can be configured with a "percentage-slice" i.e. the fraction of poll()/peek() requests that must delegate to it. - * For e.g. the default slices are "HIGH-80%, NORMAL-15%, LOW-5%". - * This means that LOW QOS requests will be dequeued at most 5% of the time. Thus a large volume of LOW QOS requests cannot affect higher - * QOS level, and it also means that higher QOS requests cannot starve lower QOS requests. - * - * @author aauradka - * - * @param - */ -public class QOSBasedQueue extends AbstractQOSBasedQueue { - final Map> _queue; - /** Tracks the number of entries in the queue. If we are able to acquire the semaphore then the queue is non-empty. */ - private final Semaphore _active = new Semaphore(0); - - public QOSBasedQueue() { - this(getDefaultQOSAllocation()); - } - - public QOSBasedQueue(Map qosBasedAllocations) { - super(qosBasedAllocations); - - final EnumMap> tmpQueue = new EnumMap<>(QOS.class); - for (QOS qos: QOS.values()) { - ConcurrentLinkedQueue baseQueue = new ConcurrentLinkedQueue<>(); - tmpQueue.put(qos, baseQueue); - } - _queue = Collections.unmodifiableMap(tmpQueue); - } - - @Override - public boolean add(@Nonnull T e) { - QOS qos = getQOS(e); - boolean wasAdded = _queue.get(qos).add(e); - if (wasAdded) { - // Release the semaphore to indicate there is something in the queue. - _active.release(); - _log.trace("Added {} QOS element to queue {}", qos, e._queueName); - } - return wasAdded; - } - - @Override - /** - * Returns or removes an element from one of the specified queues. - * @param viewOrder order to check the queues in - * @param remove if true then remove else only view - * @return - */ - T getElement(List viewOrder) { - // Check the semaphore to see if there is an item in the queue for us. If not, return null. - if (!_active.tryAcquire()) { - return null; - } - - // Loop around the queue until we find an entry. We are guaranteed to find something eventually because - // _active.tryAcquire was successful, but it may take multiple trips around the ring if multiple threads - // are contending on the queue. - for (;;) { - for (QOS q: viewOrder) { - T e = _queue.get(q).poll(); - if (e != null) { - return e; - } - } - } - } - - @Override - public int size() { - return _active.availablePermits(); - } - - @Override - public boolean isEmpty() { - return _active.availablePermits() == 0; - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/QOSBasedRequestRunnable.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/QOSBasedRequestRunnable.java deleted file mode 100644 index 1fad6f2450f..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/QOSBasedRequestRunnable.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.linkedin.alpini.base.queuing; - -import com.linkedin.alpini.base.misc.Time; -import com.linkedin.alpini.consts.QOS; - - -/** - * Wrapper class for "runnables" i.e. a request that must be executed. - * Also tags a request with a QOS level. - * @author aauradka - * - */ -public class QOSBasedRequestRunnable { - final long _time; - final Runnable _command; - final QOS _qos; - final String _queueName; - - public QOSBasedRequestRunnable(String queueName, QOS qos, Runnable command) { - _time = Time.nanoTime(); - _queueName = queueName; - _qos = qos; - _command = command; - } - - public final QOS getQOS() { - return _qos; - } - - public final Runnable getCommand() { - return _command; - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/QOSFCFSQueue.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/QOSFCFSQueue.java deleted file mode 100644 index d2a36d76f0c..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/QOSFCFSQueue.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.linkedin.alpini.base.queuing; - -import java.util.concurrent.ConcurrentLinkedQueue; -import javax.annotation.Nonnull; - - -/** - * Simple wrapper over a ConcurrentLinkedQueue to expose FCFS Queue operations. - * - * @author aauradka - * - * @param - */ -public class QOSFCFSQueue implements SimpleQueue { - private final ConcurrentLinkedQueue _queue = new ConcurrentLinkedQueue<>(); - - @Override - public boolean add(@Nonnull T e) { - return _queue.add(e); - } - - @Override - public T poll() { - return _queue.poll(); - } - - @Override - public int size() { - return _queue.size(); - } - - @Override - public boolean isEmpty() { - return _queue.isEmpty(); - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/QOSPolicy.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/QOSPolicy.java deleted file mode 100644 index 375c02fa145..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/QOSPolicy.java +++ /dev/null @@ -1,131 +0,0 @@ -package com.linkedin.alpini.base.queuing; - -import com.linkedin.alpini.consts.QOS; -import com.linkedin.alpini.consts.config.ConfigBuilder; -import java.util.EnumMap; -import java.util.Map; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** - * Enumerates all the QOS Policies supported. - * @author aauradka - * - */ -public enum QOSPolicy { - HIGHEST_PRIORITY_W_FAIR_ALLOCATION { - @Override - protected SimpleQueue buildQueue(StaticConfig qosPolicyConfig) { - return new QOSBasedQueue<>(qosPolicyConfig.getFairRatio()); - } - }, - HIGHEST_PRIORITY_W_FAIR_ALLOCATION_MULTI_QUEUE { - @Override - protected SimpleQueue buildQueue(StaticConfig qosPolicyConfig) { - return new QOSBasedMultiQueue<>(qosPolicyConfig.getMaxQueueLength(), qosPolicyConfig.getFairRatio()); - } - }, - FCFS { - @Override - protected SimpleQueue buildQueue(StaticConfig qosPolicyConfig) { - return new QOSFCFSQueue<>(); - } - }; - - private static final Logger LOG = LogManager.getLogger(QOSPolicy.class); - - protected abstract SimpleQueue buildQueue( - QOSPolicy.StaticConfig qosPolicyConfig); - - public static SimpleQueue getQOSPolicy( - QOSPolicy.StaticConfig qosPolicyConfig) { - final QOSPolicy qosPolicy; - final String policy = qosPolicyConfig.getQosPolicy(); - - try { - qosPolicy = QOSPolicy.valueOf(policy); - LOG.debug("QOS policy selected is {}", qosPolicy); - } catch (Exception ex) { - throw new IllegalArgumentException("Invalid qos policy " + ((policy != null) ? policy : "null"), ex); - } - - return qosPolicy.buildQueue(qosPolicyConfig); - } - - public static class StaticConfig { - private final String _qosPolicy; - private final Map _fairRatio; - private final int _maxQueueLength; - - public StaticConfig(String qosPolicy, String fairRatio, int maxQueueLength) { - _qosPolicy = qosPolicy; - String[] fairRatioArr = fairRatio.split(":"); - if (fairRatioArr.length != 3) { - throw new IllegalArgumentException( - "Fair Ratio " + fairRatio + " is incorrectly specified." - + " It should be of the form LOW:NORMAL:HIGH e.g. 5:15:80"); - } - - _fairRatio = new EnumMap<>(QOS.class); - _fairRatio.put(QOS.LOW, Integer.valueOf(fairRatioArr[0])); - _fairRatio.put(QOS.NORMAL, Integer.valueOf(fairRatioArr[1])); - _fairRatio.put(QOS.HIGH, Integer.valueOf(fairRatioArr[2])); - - _maxQueueLength = maxQueueLength; - } - - public String getQosPolicy() { - return _qosPolicy; - } - - public Map getFairRatio() { - return _fairRatio; - } - - public int getMaxQueueLength() { - return _maxQueueLength; - } - } - - public static class Config implements ConfigBuilder { - private String _qosPolicy = QOSPolicy.HIGHEST_PRIORITY_W_FAIR_ALLOCATION.name(); - private String _fairRatio = "5:15:80"; - private int _maxQueueLength = 0; - - @Override - public StaticConfig build() { - return new StaticConfig(getQosPolicy(), getFairAllocationRatio(), getMaxQueueLength()); - } - - public int getMaxQueueLength() { - return _maxQueueLength; - } - - public void setMaxQueueLength(int maxQueueLength) { - this._maxQueueLength = maxQueueLength; - } - - public String getQosPolicy() { - return _qosPolicy; - } - - public void setQosPolicy(String qosPolicy) { - _qosPolicy = qosPolicy; - } - - public void setFairAllocationRatio(String fairAllocationRatio) { - _fairRatio = fairAllocationRatio; - } - - public String getFairAllocationRatio() { - return _fairRatio; - } - - @Override - public String toString() { - return "{policy=" + getQosPolicy() + ",fairAllocationRatio=" + getFairAllocationRatio() + ",maxQueueLength=" - + getMaxQueueLength() + '}'; - } - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/SimpleQueue.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/SimpleQueue.java deleted file mode 100644 index 9083d9b2663..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/SimpleQueue.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.linkedin.alpini.base.queuing; - -import javax.annotation.Nonnull; - - -/** - * Simplified Queue Interface that supports basic operations like add(), poll() etc akin to the operations on - * {@linkplain java.util.Queue}. - * - * @author aauradka - * - * @param - */ -public interface SimpleQueue { - /** - * @see java.util.Queue#add(Object) - */ - boolean add(@Nonnull T e); - - /** - * @see java.util.Queue#poll() - */ - T poll(); - - /** - * @see java.util.Queue#size() - */ - int size(); - - /** - * Checks if queue is empty. - * - * @return {@code true} if Queue contains no elements, {@code false} otherwise. - */ - boolean isEmpty(); -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/package-info.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/package-info.java deleted file mode 100644 index ed53f3effce..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/queuing/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * @author Antony T Curtis {@literal } - */ -package com.linkedin.alpini.base.queuing; diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/AbstractQuantileEstimation.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/AbstractQuantileEstimation.java deleted file mode 100644 index 5ed0122b6f4..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/AbstractQuantileEstimation.java +++ /dev/null @@ -1,401 +0,0 @@ -package com.linkedin.alpini.base.statistics; - -import com.linkedin.alpini.base.concurrency.ConcurrentAccumulator; -import com.linkedin.alpini.base.misc.CollectionUtil; -import com.linkedin.alpini.base.misc.Msg; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Objects; -import java.util.SortedSet; -import java.util.concurrent.ConcurrentSkipListSet; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.stream.Collector; -import javax.annotation.Nonnull; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.util.StringBuilderFormattable; - - -/** - * A memory efficient abstract implementation for calculating quantile summaries. - * - * @author Antony T Curtis {@literal } - * @see "Greenwald and Khanna, 'Space-efficient online computation of quantile summaries' SIGMOD 2001" - */ -public abstract class AbstractQuantileEstimation> { - protected final Logger _log = LogManager.getLogger(getClass()); - - private final double _epsilon; - private final int _compactSize; - private final Collector _collector; - private final Data _nullData; - - private final ConcurrentAccumulator _accumulator; - - protected AbstractQuantileEstimation(double epsilon, int compactSize) { - this(epsilon, compactSize, ConcurrentAccumulator.defaultMode); - } - - protected AbstractQuantileEstimation(double epsilon, int compactSize, ConcurrentAccumulator.Mode accumulatorMode) { - _epsilon = epsilon; - _compactSize = compactSize; - _collector = collector(); - _accumulator = new ConcurrentAccumulator<>(accumulatorMode, _collector); - _nullData = newData(); - } - - protected int getCompactSize() { - return _compactSize; - } - - protected abstract int compare(SAMPLE o1, SAMPLE o2); - - private final Comparator _comparator = (o1, o2) -> -compare(o1, o2); - - protected Collector collector() { - return Collector.of( - AbstractQuantileEstimation.this::newData, - Data::accumulate, - Data::combine, - Function.identity(), - Collector.Characteristics.UNORDERED, - Collector.Characteristics.IDENTITY_FINISH); - } - - protected @Nonnull Data newData() { - return new Data(); - } - - private SortedSet newSortedSet() { - return newSortedSet(_comparator); - } - - protected SortedSet newSortedSet(Comparator comparator) { - return new ConcurrentSkipListSet<>(comparator); - } - - protected SortedSet cloneSortedSet(SortedSet samples) { - return ((ConcurrentSkipListSet) samples).clone(); - } - - protected SAMPLE floor(SortedSet samples, SAMPLE v) { - /* if (false) { - // If there was no floor function - for (SortedSet tailSet = samples.tailSet(v); !tailSet.isEmpty(); ) { - SAMPLE test = tailSet.first(); - if (_comparator.compare(test, v) == 0) { - return test; - } - break; - } - for (SortedSet headSet = samples.headSet(v); !headSet.isEmpty(); ) { - return headSet.last(); - } - return null; - }*/ - return ((ConcurrentSkipListSet) samples).floor(v); - } - - protected class Data { - private SortedSet _samples = newSortedSet(); - - /** number of samples received, long to avoid integer overflow */ - private long _count; - - public final @Nonnull List query(@Nonnull Quantiles quantile) { - if (_samples.isEmpty()) { - return Collections.emptyList(); - } - - // Create a list of samples in reverse order. - LinkedList samples = new LinkedList<>(); - _samples.forEach(samples::addFirst); - - final int quantileCount = quantile.size(); - - CollectionUtil.ListBuilder builder = CollectionUtil.listBuilder(); - - int index = 0; - long count = _count; - double rankMin = 0; - double[] desired = new double[quantileCount]; - - for (int i = 0; i < quantileCount; i++) { - desired[i] = ((quantile.get(i) + _epsilon * 2.0) * count); - } - - final Iterator it = samples.iterator(); - SAMPLE prev; - SAMPLE cur = it.next(); - - out: while (index < quantileCount && it.hasNext()) { - prev = cur; - cur = it.next(); - rankMin += prev.g(); - - while (rankMin + cur.error() > desired[index]) { - builder.add(prev); - if (++index == quantileCount) { - break out; - } - } - } - while (index++ < quantileCount) { - builder.add(cur); - } - return builder.build(); - } - - public Quantile computeQuantile(@Nonnull SAMPLE v) { - if (_samples.isEmpty()) { - return null; - } - - // Create a list of samples in reverse order. - LinkedList samples = new LinkedList<>(); - _samples.forEach(samples::addFirst); - - Iterator it = samples.iterator(); - if (it.hasNext()) { - SAMPLE prev; - SAMPLE cur = it.next(); - double rankMin = 0; - while (it.hasNext()) { - prev = cur; - cur = it.next(); - rankMin += prev.g(); - if (_comparator.compare(v, cur) > 0) { - double scale = 1.0 / _count; - double quartile = (rankMin + cur.g() / 2) * scale - _epsilon * 2.0; - double error = cur.error() * scale * 0.5; - return new Quantile(Math.max(0.0, Math.min(quartile + error, 1.0)), error); - } - } - } - return new Quantile(1.0, 0.0); - } - - void accumulate(SAMPLE v) { - SAMPLE floor = floor(_samples, v); - int delta = (int) Math.floor(2 * _epsilon * (_count + 1)); - if (floor == null || _comparator.compare(v, _samples.last()) > 0) { - v.init(1, 0); - } else { - v.init(1, delta); - } - - // As per §3, simplify tuple initialization and attempt to remove a tuple for every insert. - // This is achieved by obtaining a lock on the the n+1 element (our set is reversed) and performing - // the merge operation, removing the old element if it is to be replaced. - if (floor == null || AbstractSample.error(v, floor) > delta) { - _samples.add(v); - } else { - floor.merge(v, floor == _samples.first(), floor == _samples.last()); - } - _count++; - } - - Data combine(Data other) { - if (_samples.isEmpty()) { - _samples = cloneSortedSet(other._samples); - _count = other._count; - return this; - } - - other._samples.forEach(v -> { - SAMPLE floor = floor(_samples, v); - int delta = (int) Math.floor(2 * _epsilon * (_count + v.count())); - if (floor == null || AbstractSample.error(v, floor) > delta) { - _samples.add(v.clone()); - } else { - floor.merge(v, floor == _samples.first(), floor == _samples.last()); - } - _count += v.count(); - }); - return this; - } - } - - protected final List querySample(@Nonnull Quantiles quantiles) { - return data().query(Objects.requireNonNull(quantiles)); - } - - public void reset() { - _accumulator.reset(); - } - - protected final @Nonnull Data data() { - Data data = _accumulator.get(); - if (data == null) { - data = _nullData; - } - return data; - } - - protected @Nonnull List queryAndReset(@Nonnull Quantiles quantiles, Consumer consumer) { - Data data = _accumulator.getThenReset(); - if (data != null) { - consumer.accept(data); - return data.query(Objects.requireNonNull(quantiles)); - } - return Collections.emptyList(); - } - - protected @Nonnull List queryAndReset(@Nonnull Quantiles quantiles) { - return queryAndReset(quantiles, data -> {}); - } - - /** - * Computes the quantile which the given sample {@literal v} is a member. - * @param v sample - * @return quantile - */ - protected final Quantile computeQuantile(@Nonnull SAMPLE v) { - Data data = _accumulator.get(); - if (data != null) { - return data.computeQuantile(v); - } - return null; - } - - public int getNumberOfSamples() { - return data()._samples.size(); - } - - protected final void accept(SAMPLE v) { - _accumulator.accept(Objects.requireNonNull(v)); - } - - private static double checkQuantile(double quantile) { - if (quantile < 0.0 || quantile > 1.0) { - throw new IllegalArgumentException("Quantile may only be between 0.0 and 1.0 inclusive"); - } - return quantile; - } - - public static final class Quantiles { - private final @Nonnull double[] _quantiles; - - public Quantiles(double quantile) { - _quantiles = new double[] { checkQuantile(quantile) }; - } - - public Quantiles(double first, double... quantiles) { - if (quantiles.length > 0) { - double current = checkQuantile(first); - for (double quantile: quantiles) { - if (current >= quantile) { - throw new IllegalArgumentException("Quantiles must be specified in ascending order"); - } - current = checkQuantile(quantile); - } - } - _quantiles = new double[quantiles.length + 1]; - _quantiles[0] = first; - System.arraycopy(quantiles, 0, _quantiles, 1, quantiles.length); - } - - public int size() { - return _quantiles.length; - } - - public double get(int i) { - return _quantiles[i]; - } - } - - public static final class Quantile implements StringBuilderFormattable { - private final double _quantile; - private final double _error; - - public Quantile(double quantile, double error) { - _quantile = quantile; - _error = error; - } - - public double getQuantile() { - return _quantile; - } - - public double getError() { - return _error; - } - - @Override - public void formatTo(StringBuilder buffer) { - buffer.append(toPct(getQuantile())).append("%ile ±").append(toPct(getError())); - } - - private static double toPct(double value) { - return Math.floor(value * 1000000.0) / 10000.0; - } - - @Override - public String toString() { - StringBuilder builder = Msg.stringBuilder(); - formatTo(builder); - return builder.toString(); - } - } - - protected static abstract class AbstractSample> implements Cloneable { - private double _g; - private int _delta; - private int _count; - - public SAMPLE clone() { - try { - return (SAMPLE) super.clone(); - } catch (CloneNotSupportedException e) { - throw new IllegalStateException(e); // should not occur. - } - } - - @SuppressWarnings("unchecked") - final SAMPLE self() { - return (SAMPLE) this; - } - - final SAMPLE init(double g, int delta) { - _g = g; - _delta = delta; - _count = 1; - return self(); - } - - final SAMPLE merge0(@Nonnull SAMPLE other, boolean max, boolean min) { - return merge(other, max, min); - } - - @SuppressWarnings("unchecked") - protected SAMPLE merge(@Nonnull SAMPLE other, boolean max, boolean min) { - _g += other.g(); - _count += other.count(); - return self(); - } - - protected final double g() { - return _g; - } - - final int count() { - return _count; - } - - final int delta() { - return _delta; - } - - final double error() { - return g() + delta(); - } - - static double error(@Nonnull AbstractSample cur, @Nonnull AbstractSample prev) { - return cur.g() + prev.error(); - } - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/DoubleQuantileEstimation.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/DoubleQuantileEstimation.java deleted file mode 100644 index fe6c7978405..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/DoubleQuantileEstimation.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.linkedin.alpini.base.statistics; - -import java.util.List; -import java.util.function.DoubleConsumer; -import javax.annotation.Nonnull; - - -/** - * @author Antony T Curtis {@literal } - */ -public class DoubleQuantileEstimation extends AbstractQuantileEstimation - implements DoubleConsumer { - public DoubleQuantileEstimation(double epsilon, int compactSize) { - super(epsilon, compactSize); - } - - @Override - protected int compare(Sample o1, Sample o2) { - return Double.compare(o1._value, o2._value); - } - - public Quantile computeQuantile(double v) { - return super.computeQuantile(new Sample(v)); - } - - public double query(double quantile) { - List sample = querySample(new Quantiles(quantile)); - return !sample.isEmpty() ? sample.iterator().next()._value : Double.NaN; - } - - public final double[] query(@Nonnull Quantiles quantiles) { - return querySample(quantiles).stream().mapToDouble(Sample::value).toArray(); - } - - @Override - public void accept(double v) { - if (Double.isFinite(v)) { - accept(new Sample(v)); - } - } - - protected static final class Sample extends AbstractQuantileEstimation.AbstractSample { - protected final double _value; - - private Sample(double value) { - _value = value; - } - - public double value() { - return _value; - } - - @Override - public String toString() { - return String.valueOf(value()); - } - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/GenericQuantileEstimation.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/GenericQuantileEstimation.java deleted file mode 100644 index e777c024a3d..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/GenericQuantileEstimation.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.linkedin.alpini.base.statistics; - -import java.util.Comparator; -import java.util.List; -import java.util.Objects; -import java.util.function.Consumer; -import javax.annotation.Nonnull; - - -/** - * @author Antony T Curtis {@literal } - */ -public class GenericQuantileEstimation extends AbstractQuantileEstimation> - implements Consumer { - private final Comparator _comparator; - - public GenericQuantileEstimation(double epsilon, int compactSize, Comparator comparator) { - super(epsilon, compactSize); - _comparator = Objects.requireNonNull(comparator); - } - - @Override - protected final int compare(Sample o1, Sample o2) { - return _comparator.compare(o1.value(), o2.value()); - } - - public Quantile computeQuantile(@Nonnull T v) { - return super.computeQuantile(new Sample<>(v)); - } - - public T query(double quantile) { - List> sample = querySample(new Quantiles(quantile)); - return !sample.isEmpty() ? sample.iterator().next().value() : null; - } - - @Override - public void accept(T v) { - accept(newSample(v)); - } - - protected Sample newSample(T value) { - return new Sample<>(value); - } - - protected static class Sample extends AbstractQuantileEstimation.AbstractSample> { - public @Nonnull T _value; - - public Sample(@Nonnull T value) { - _value = Objects.requireNonNull(value); - } - - public final T value() { - return _value; - } - - @Override - public String toString() { - return String.valueOf(value()); - } - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongQuantileArrayEstimation.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongQuantileArrayEstimation.java deleted file mode 100644 index 59c62bacb00..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongQuantileArrayEstimation.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.linkedin.alpini.base.statistics; - -import com.linkedin.alpini.base.concurrency.ArraySortedSet; -import java.util.Comparator; -import java.util.SortedSet; - - -/** - * @author Antony T Curtis {@literal } - */ -public class LongQuantileArrayEstimation extends LongQuantileEstimation { - public LongQuantileArrayEstimation(double epsilon, int compactSize) { - super(epsilon, compactSize); - } - - @Override - protected SortedSet newSortedSet(Comparator comparator) { - return new ArraySortedSet<>(comparator, 2 * getCompactSize()); - } - - @Override - protected SortedSet cloneSortedSet(SortedSet samples) { - return ((ArraySortedSet) samples).clone(); - } - - @Override - protected Sample floor(SortedSet samples, Sample v) { - return ((ArraySortedSet) samples).floor(v); - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongQuantileEstimation.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongQuantileEstimation.java deleted file mode 100644 index 7db1662f37f..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongQuantileEstimation.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.linkedin.alpini.base.statistics; - -import java.util.List; -import java.util.function.LongConsumer; -import javax.annotation.Nonnull; - - -/** - * @author Antony T Curtis {@literal } - */ -public class LongQuantileEstimation extends AbstractQuantileEstimation - implements LongConsumer { - public LongQuantileEstimation(double epsilon, int compactSize) { - super(epsilon, compactSize); - } - - @Override - protected final int compare(Sample o1, Sample o2) { - return Long.compare(o1.value(), o2.value()); - } - - public Quantile computeQuantile(long v) { - return super.computeQuantile(new Sample(v)); - } - - public final Long query(double quantile) { - List sample = querySample(new Quantiles(quantile)); - return !sample.isEmpty() ? sample.iterator().next()._value : null; - } - - public final long[] query(@Nonnull Quantiles quantiles) { - return querySample(quantiles).stream().mapToLong(Sample::value).toArray(); - } - - @Override - public void accept(long v) { - accept(new Sample(v)); - } - - protected static final class Sample extends AbstractQuantileEstimation.AbstractSample { - protected final long _value; - - private Sample(long value) { - _value = value; - } - - public final long value() { - return _value; - } - - @Override - public String toString() { - return String.valueOf(value()); - } - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongStats.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongStats.java deleted file mode 100644 index c562bf65ea9..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongStats.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.linkedin.alpini.base.statistics; - -/** - * @author Antony T Curtis {@literal } - */ -public interface LongStats { - /** - * Returns the count. - * @return the count. - */ - default int getCount() { - return Math.toIntExact(getLongCount()); - } - - long getLongCount(); - - /** - * Returns the average. - * @return the average or {@code NaN} if there is no data. - */ - double getAverage(); - - /** - * Returns the standard deviation. - * @return the standard deviation or {@code NaN} if there is no data. - */ - double getStandardDeviation(); - - /** - * Returns the minimum. - * @return the minimum or {@code null} if there is no data. - */ - Long getMinimum(); - - /** - * Returns the maximum value. - * @return the maximum value or {@code null} if there is no data. - */ - Long getMaximum(); - - /** - * Returns the 50th percentile value. - * @return the 50th percentile value or {@code null} if there is no data. - */ - Long get50Pct(); - - /** - * Returns the 90th percentile value. - * @return the 90th percentile value or {@code null} if there is no data. - */ - Long get90Pct(); - - /** - * Returns the 95th percentile value. - * @return the 95th percentile value or {@code null} if there is no data. - */ - Long get95Pct(); - - /** - * Returns the 99th percentile value. - * @return the 99th percentile value or {@code null} if there is no data. - */ - Long get99Pct(); - - /** - * Returns the 99.9th percentile value. - * @return the 99.9th percentile value or {@code null} if there is no data. - */ - Long get99_9Pct(); // SUPPRESS CHECKSTYLE MethodName -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongStatsAggregator.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongStatsAggregator.java deleted file mode 100644 index 0b8cd0bdaf9..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongStatsAggregator.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.linkedin.alpini.base.statistics; - -import java.util.Iterator; -import java.util.List; -import javax.annotation.Nonnull; - - -/** - * Extend the {@link LongQuantileEstimation} class and add computation for the mean and standard deviation of - * the supplied values. The statistics are summarised in a {@link LongStats} object and the statistics are reset. - * - * @author Antony T Curtis {@literal } - */ -public class LongStatsAggregator extends LongQuantileEstimation { - private static final Quantiles QUANTILES = new Quantiles(0.00, 0.50, 0.90, 0.95, 0.99, 0.999, 1.00); - - public LongStatsAggregator(double epsilon, int compactSize) { - super(epsilon, compactSize); - } - - @Override - protected @Nonnull LongData newData() { - return new LongData(); - } - - protected final class LongData extends Data { - protected final Welfords.LongWelford _stddev = new Welfords.LongWelford(); - - @Override - public void accumulate(Sample v) { - _stddev.accept(v._value); - super.accumulate(v); - } - - @Override - public Data combine(Data other) { - _stddev.merge(((LongData) other)._stddev); - return super.combine(other); - } - } - - public LongStats getLongStats() { - Welfords.Result[] stddev = new Welfords.Result[1]; - List samples = queryAndReset(QUANTILES, d -> stddev[0] = ((LongData) d)._stddev.getResult()); - - Long minimum; - Long maximum; - Long pct50; - Long pct90; - Long pct95; - Long pct99; - Long pct999; - - if (samples.isEmpty()) { - minimum = null; - maximum = null; - pct50 = null; - pct90 = null; - pct95 = null; - pct99 = null; - pct999 = null; - } else { - Iterator it = samples.iterator(); - minimum = it.next()._value; - pct50 = it.next()._value; - pct90 = it.next()._value; - pct95 = it.next()._value; - pct99 = it.next()._value; - pct999 = it.next()._value; - maximum = it.next()._value; - } - - return new LongStatsImpl(stddev[0], minimum, maximum, pct50, pct90, pct95, pct99, pct999); - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongStatsAggregatorLowQuantile.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongStatsAggregatorLowQuantile.java deleted file mode 100644 index 0521d15ce22..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongStatsAggregatorLowQuantile.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.linkedin.alpini.base.statistics; - -import java.util.Iterator; -import java.util.List; - - -/** - * Extend the {@link LongStatsAggregator} class to only track low quantile points. - * The statistics are summarised in a {@link LongStatsLowQuantile} object and the statistics are reset. - * - * @author Guanlin Lu {@literal } - */ -public class LongStatsAggregatorLowQuantile extends LongStatsAggregator { - private static final AbstractQuantileEstimation.Quantiles LOW_QUANTILES = - new AbstractQuantileEstimation.Quantiles(0.00, 0.001, 0.01, 0.05, 0.1, 0.5, 1.0); - - public LongStatsAggregatorLowQuantile(double epsilon, int compactSize) { - super(epsilon, compactSize); - } - - public LongStatsLowQuantile getLongStatsLowQuantile() { - Welfords.Result[] stddev = new Welfords.Result[1]; - List samples = queryAndReset(LOW_QUANTILES, d -> stddev[0] = ((LongData) d)._stddev.getResult()); - - Long minimum; - Long maximum; - Long pct50; - Long pct10; - Long pct5; - Long pct1; - Long pct01; - - if (samples.isEmpty()) { - minimum = null; - maximum = null; - pct01 = null; - pct1 = null; - pct5 = null; - pct10 = null; - pct50 = null; - } else { - Iterator it = samples.iterator(); - minimum = it.next()._value; - pct01 = it.next()._value; - pct1 = it.next()._value; - pct5 = it.next()._value; - pct10 = it.next()._value; - pct50 = it.next()._value; - maximum = it.next()._value; - } - - return new LongStatsLowQuantileImpl(stddev[0], minimum, maximum, pct01, pct1, pct5, pct10, pct50); - } - -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongStatsArrayAggregator.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongStatsArrayAggregator.java deleted file mode 100644 index 45151fa6fd5..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongStatsArrayAggregator.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.linkedin.alpini.base.statistics; - -import com.linkedin.alpini.base.concurrency.ArraySortedSet; -import java.util.Comparator; -import java.util.SortedSet; - - -/** - * Extend the {@link LongQuantileEstimation} class and add computation for the mean and standard deviation of - * the supplied values. The statistics are summarised in a {@link LongStats} object and the statistics are reset. - * - * @author Antony T Curtis {@literal } - */ -public class LongStatsArrayAggregator extends LongStatsAggregator { - public LongStatsArrayAggregator(double epsilon, int compactSize) { - super(epsilon, compactSize); - } - - @Override - protected SortedSet newSortedSet( - Comparator comparator) { - return new ArraySortedSet<>(comparator, 2 * getCompactSize()); - } - - @Override - protected SortedSet cloneSortedSet( - SortedSet samples) { - return ((ArraySortedSet) samples).clone(); - } - - @Override - protected LongQuantileArrayEstimation.Sample floor( - SortedSet samples, - LongQuantileArrayEstimation.Sample v) { - return ((ArraySortedSet) samples).floor(v); - } - -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongStatsImpl.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongStatsImpl.java deleted file mode 100644 index 25d53202434..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongStatsImpl.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.linkedin.alpini.base.statistics; - -import com.linkedin.alpini.base.misc.Msg; -import java.util.Formatter; -import org.apache.logging.log4j.util.StringBuilderFormattable; - - -final class LongStatsImpl implements LongStats, StringBuilderFormattable { - private final Welfords.Result _stddev; - private final Long _minimum; - private final Long _maximum; - private final Long _pct50; - private final Long _pct90; - private final Long _pct95; - private final Long _pct99; - private final Long _pct99_9; // SUPPRESS CHECKSTYLE MemberName - - LongStatsImpl( - Welfords.Result stddev, - Long minimum, - Long maximum, - Long pct50, - Long pct90, - Long pct95, - Long pct99, - Long pct99_9) { // SUPPRESS CHECKSTYLE ParameterName - _stddev = stddev; - _minimum = minimum; - _maximum = maximum; - _pct50 = pct50; - _pct90 = pct90; - _pct95 = pct95; - _pct99 = pct99; - _pct99_9 = pct99_9; - } - - @Override - public long getLongCount() { - return _stddev != null ? _stddev.getCount() : 0L; - } - - @Override - public double getAverage() { - return _stddev != null ? _stddev.getAverage() : 0.0; - } - - @Override - public double getStandardDeviation() { - return _stddev != null ? _stddev.getStandardDeviation() : 0.0; - } - - @Override - public Long getMinimum() { - return _minimum; - } - - @Override - public Long getMaximum() { - return _maximum; - } - - @Override - public Long get50Pct() { - return _pct50; - } - - @Override - public Long get90Pct() { - return _pct90; - } - - @Override - public Long get95Pct() { - return _pct95; - } - - @Override - public Long get99Pct() { - return _pct99; - } - - @Override - public Long get99_9Pct() { // SUPPRESS CHECKSTYLE MethodName - return _pct99_9; - } - - @Override - public void formatTo(StringBuilder buffer) { - new Formatter(buffer).format( - "count=%d average=%.1f stddev=%.1f minimum=%d maximum=%d" + " pct50=%d pct90=%d pct95=%d pct99=%d pct99.9=%d", - getCount(), - getAverage(), - getStandardDeviation(), - getMinimum(), - getMaximum(), - get50Pct(), - get90Pct(), - get95Pct(), - get99Pct(), - get99_9Pct()); - } - - @Override - public String toString() { - StringBuilder builder = Msg.stringBuilder(); - formatTo(builder); - return builder.toString(); - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongStatsLowQuantile.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongStatsLowQuantile.java deleted file mode 100644 index 02230055ca8..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongStatsLowQuantile.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.linkedin.alpini.base.statistics; - -public interface LongStatsLowQuantile { - /** - * Returns the count. - * @return the count. - */ - default int getCount() { - return Math.toIntExact(getLongCount()); - } - - long getLongCount(); - - /** - * Returns the average. - * @return the average or {@code NaN} if there is no data. - */ - double getAverage(); - - /** - * Returns the standard deviation. - * @return the standard deviation or {@code NaN} if there is no data. - */ - double getStandardDeviation(); - - /** - * Returns the minimum. - * @return the minimum or {@code null} if there is no data. - */ - Long getMinimum(); - - /** - * Returns the maximum value. - * @return the maximum value or {@code null} if there is no data. - */ - Long getMaximum(); - - /** - * Returns the 0.1th percentile value. - * @return the 0.1th percentile value or {@code null} if there is no data. - */ - Long get01Pct(); - - /** - * Returns the 1th percentile value. - * @return the 1th percentile value or {@code null} if there is no data. - */ - Long get1Pct(); - - /** - * Returns the 5th percentile value. - * @return the 5th percentile value or {@code null} if there is no data. - */ - Long get5Pct(); - - /** - * Returns the 10th percentile value. - * @return the 10th percentile value or {@code null} if there is no data. - */ - Long get10Pct(); - - /** - * Returns the 50th percentile value. - * @return the 50th percentile value or {@code null} if there is no data. - */ - Long get50Pct(); // SUPPRESS CHECKSTYLE MethodName -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongStatsLowQuantileImpl.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongStatsLowQuantileImpl.java deleted file mode 100644 index aa784e0e0e9..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/LongStatsLowQuantileImpl.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.linkedin.alpini.base.statistics; - -import com.linkedin.alpini.base.misc.Msg; -import java.util.Formatter; -import org.apache.logging.log4j.util.StringBuilderFormattable; - - -public class LongStatsLowQuantileImpl implements LongStatsLowQuantile, StringBuilderFormattable { - private final Welfords.Result _stddev; - private final Long _minimum; - private final Long _maximum; - private final Long _pct01; - private final Long _pct1; - private final Long _pct5; - private final Long _pct10; - private final Long _pct50; // SUPPRESS CHECKSTYLE MemberName - - LongStatsLowQuantileImpl( - Welfords.Result stddev, - Long minimum, - Long maximum, - Long pct01, - Long pct1, - Long pct5, - Long pct10, - Long pct50) { // SUPPRESS CHECKSTYLE ParameterName - _stddev = stddev; - _minimum = minimum; - _maximum = maximum; - _pct01 = pct01; - _pct1 = pct1; - _pct5 = pct5; - _pct10 = pct10; - _pct50 = pct50; - } - - @Override - public long getLongCount() { - return _stddev != null ? _stddev.getCount() : 0L; - } - - @Override - public double getAverage() { - return _stddev != null ? _stddev.getAverage() : 0.0; - } - - @Override - public double getStandardDeviation() { - return _stddev != null ? _stddev.getStandardDeviation() : 0.0; - } - - @Override - public Long getMinimum() { - return _minimum; - } - - @Override - public Long getMaximum() { - return _maximum; - } - - @Override - public Long get50Pct() { - return _pct50; - } - - @Override - public Long get01Pct() { - return _pct01; - } - - @Override - public Long get1Pct() { - return _pct1; - } - - @Override - public Long get5Pct() { - return _pct5; - } - - @Override - public Long get10Pct() { // SUPPRESS CHECKSTYLE MethodName - return _pct10; - } - - @Override - public void formatTo(StringBuilder buffer) { - new Formatter(buffer).format( - "count=%d average=%.1f stddev=%.1f minimum=%d maximum=%d" + " pct0.1=%d pct1=%d pct5=%d pct10=%d pct50=%d", - getCount(), - getAverage(), - getStandardDeviation(), - getMinimum(), - getMaximum(), - get01Pct(), - get1Pct(), - get5Pct(), - get10Pct(), - get50Pct()); - } - - @Override - public String toString() { - StringBuilder builder = Msg.stringBuilder(); - formatTo(builder); - return builder.toString(); - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/Welfords.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/Welfords.java deleted file mode 100644 index 9157ad16389..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/Welfords.java +++ /dev/null @@ -1,269 +0,0 @@ -package com.linkedin.alpini.base.statistics; - -import com.linkedin.alpini.base.misc.Msg; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; -import java.util.function.DoubleConsumer; -import java.util.function.LongConsumer; -import java.util.function.UnaryOperator; -import java.util.stream.Collector; -import javax.annotation.Nonnull; -import org.apache.logging.log4j.util.StringBuilderFormattable; - - -/** - * Welford's algorithm for calculating variance. - * - * @author Antony T Curtis {@literal } - * @see "B.P.Welford (1962)" - */ -public abstract class Welfords { - private static final AtomicReferenceFieldUpdater STATE = - AtomicReferenceFieldUpdater.newUpdater(Welfords.class, Result.class, "_state"); - - private volatile Result _state; - - private static final ThreadLocal LOCAL = ThreadLocal.withInitial(LocalState::new); - - protected Welfords() { - reset(); - } - - protected Welfords(Welfords previous) { - _state = previous._state; - } - - public final void reset() { - _state = new Result(0, 0.0, 0.0, Double.MAX_VALUE, Double.MIN_VALUE); - } - - public final void accept(double value) { - if (Double.isFinite(value)) { - LocalState local = LOCAL.get(); - local.value = value; - STATE.updateAndGet(this, local.acceptFunction); - local.done(); - } - } - - public void merge(Welfords other) { - Result result = other.getResult(); - if (result._count == 0) { - return; - } - LocalState local = LOCAL.get(); - local.other = result; - STATE.updateAndGet(this, local.mergeFunction); - local.done(); - } - - public @Nonnull Result getResult() { - LocalState local = LOCAL.get(); - STATE.updateAndGet(this, local.getFunction); - return local.getLast(); - } - - public static class LongWelford extends Welfords implements LongConsumer { - public static final Collector COLLECTOR = Collector.of( - LongWelford::new, - LongWelford::accept, - LongWelford::combine, - Welfords::getResult, - Collector.Characteristics.UNORDERED); - - public LongWelford() { - super(); - } - - protected LongWelford(LongWelford longWelford) { - super(longWelford); - } - - @Override - public final void accept(long value) { - super.accept(value); - } - - private LongWelford combine(LongWelford other) { - LongWelford merged = new LongWelford(this); - merged.merge(other); - return merged; - } - } - - public static class DoubleWelford extends Welfords implements DoubleConsumer { - public static final Collector COLLECTOR = Collector.of( - DoubleWelford::new, - DoubleWelford::accept, - DoubleWelford::combine, - Welfords::getResult, - Collector.Characteristics.UNORDERED); - - public DoubleWelford() { - super(); - } - - protected DoubleWelford(DoubleWelford longWelford) { - super(longWelford); - } - - private DoubleWelford combine(DoubleWelford other) { - DoubleWelford merged = new DoubleWelford(this); - merged.merge(other); - return merged; - } - } - - private static final class LocalState { - private double value; - private Result other; - private Result result; - private Result idle; - private Result last; - - final UnaryOperator acceptFunction = this::accept; - final UnaryOperator mergeFunction = this::merge; - final UnaryOperator getFunction = this::get; - - private Result get(Result state) { - return result(state).recycle(state._count, state._mean, state._m2, state._min, state._max); - } - - private Result accept(Result state) { - long count = state._count + 1; - double mean = state._mean; - double m2 = state._m2; - double delta = value - mean; - m2 += delta * (value - (mean += delta / count)); // SUPPRESS CHECKSTYLE InnerAssignment - return result(state).recycle(count, mean, m2, Math.min(state._min, value), Math.max(state._max, value)); - } - - private Result merge(Result state) { - if (state._count == 0) { - if (idle == null) { - idle = result; - } - return other; - } else { - double delta = other._mean - state._mean; - double ma = state._m2 * (state._count - 1); - double mb = other._m2 * (other._count - 1); - long count = state._count + other._count; - return result(last).recycle( - count, - ((state._mean * state._count) + (other._mean * other._count)) / count, - (ma + mb + delta * delta * state._count * other._count) / count, - Math.min(state._min, other._min), - Math.max(state._max, other._max)); - } - } - - private Result result(Result state) { - last = state; - if (result == null) { - if (idle == null) { - result = new Result(); - } else { - result = idle; - idle = null; - } - } - return result; - } - - private Result getLast() { - result = null; - Result last = this.last; - this.last = null; - return last; - } - - private void done() { - result = null; - if (idle == null) { - idle = last; - last = null; - } - } - } - - public static final class Result implements StringBuilderFormattable { - private long _count; - private double _mean; - private double _m2; - private double _min; - private double _max; - - private Result() { - } - - private Result(long count, double mean, double m2, double min, double max) { - _count = count; - _mean = mean; - _m2 = m2; - _min = min; - _max = max; - } - - private Result recycle(long count, double mean, double m2, double min, double max) { - _count = count; - _mean = mean; - _m2 = m2; - _min = min; - _max = max; - return this; - } - - public long getCount() { - return _count; - } - - public double getAverage() { - return _count > 0 ? _mean : Double.NaN; - } - - private double variance() { - return _m2 / (_count - 1); - } - - public double getVariance() { - return _count > 1 ? variance() : Double.NaN; - } - - public double getStandardDeviation() { - return _count > 1 ? Math.sqrt(variance()) : Double.NaN; - } - - public double getMin() { - return _min != Double.MAX_VALUE ? _min : 0.0; - } - - public double getMax() { - return _max != Double.MIN_VALUE ? _max : 0.0; - } - - @Override - public void formatTo(StringBuilder buffer) { - buffer.append("count=") - .append(getCount()) - .append(" average=") - .append(formatDouble(getAverage())) - .append(" stddev=") - .append(formatDouble(getStandardDeviation())) - .append(" min=") - .append(formatDouble(getMin())) - .append(" max=") - .append(formatDouble(getMax())); - } - - private long formatDouble(double value) { - return Double.isNaN(value) ? 0 : (long) value; - } - - @Override - public String toString() { - StringBuilder builder = Msg.stringBuilder(); - formatTo(builder); - return builder.toString(); - } - } -} diff --git a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/package-info.java b/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/package-info.java deleted file mode 100644 index a1c9cb81dee..00000000000 --- a/internal/alpini/common/alpini-common-base/src/main/java/com/linkedin/alpini/base/statistics/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * @author Antony T Curtis {@literal } - */ -package com.linkedin.alpini.base.statistics; diff --git a/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/concurrency/TestConcurrentAccumulator.java b/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/concurrency/TestConcurrentAccumulator.java deleted file mode 100644 index 52b35ba0a78..00000000000 --- a/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/concurrency/TestConcurrentAccumulator.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.linkedin.alpini.base.concurrency; - -import com.linkedin.alpini.base.misc.Time; -import com.linkedin.alpini.base.statistics.Welfords; -import java.util.concurrent.ForkJoinPool; -import java.util.concurrent.ThreadLocalRandom; -import java.util.concurrent.TimeUnit; -import java.util.stream.IntStream; -import org.testng.Assert; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - - -@Test(groups = "unit") -public class TestConcurrentAccumulator { - private static final Object[][] ACCUMULATOR_MODES = - { { ConcurrentAccumulator.Mode.COMPLEX }, { ConcurrentAccumulator.Mode.THREADED }, }; - - @DataProvider - public Object[][] accumulatorModes() { - return ACCUMULATOR_MODES; - } - - private void assertThreadMap(ConcurrentAccumulator accumulator, int expect) { - ThreadedAccumulator threaded = accumulator.unwrap(ThreadedAccumulator.class); - if (threaded != null) { - Assert.assertEquals(threaded.threadMapSize(), expect); - } - } - - @Test(dataProvider = "accumulatorModes") - public void basicTest(ConcurrentAccumulator.Mode mode) throws InterruptedException { - ConcurrentAccumulator accumulator = - new ConcurrentAccumulator<>(mode, Welfords.DoubleWelford.COLLECTOR); - - for (int j = 0; j < 2; j++) { - ForkJoinPool pool = new ForkJoinPool(8); - - try { - assertThreadMap(accumulator, 1); - - accumulator.reset(); - - pool.submit(() -> { - IntStream.range(1, 5000000).parallel().forEach(i -> { - accumulator.accept(ThreadLocalRandom.current().nextDouble(100)); - }); - }).join(); - - assertThreadMap(accumulator, 9); - System.out.println(accumulator.getThenReset()); - pool.submit(accumulator::pack).join(); - - pool.submit(() -> { - IntStream.range(1, 5000000).parallel().forEach(i -> { - accumulator.accept(ThreadLocalRandom.current().nextDouble(100)); - }); - }).join(); - - assertThreadMap(accumulator, 9); - System.out.println(accumulator); - } finally { - pool.shutdownNow(); - Assert.assertTrue(pool.awaitTermination(5, TimeUnit.SECONDS)); - } - - System.gc(); - Time.sleepUninterruptably(1000); - System.gc(); - - System.out.println(accumulator); - assertThreadMap(accumulator, 1); - } - } -} diff --git a/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/misc/TestCollectionUtil.java b/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/misc/TestCollectionUtil.java deleted file mode 100644 index 3961bc7b803..00000000000 --- a/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/misc/TestCollectionUtil.java +++ /dev/null @@ -1,262 +0,0 @@ -package com.linkedin.alpini.base.misc; - -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import org.testng.Assert; -import org.testng.annotations.Test; - - -/** - * @author Antony T Curtis {@literal } - */ -public class TestCollectionUtil { - @Test(groups = "unit") - public void testSetBuilder() { - Set set = CollectionUtil.setBuilder().build(); - Assert.assertEquals(set.size(), 0); - - set = CollectionUtil.setBuilder().add("TEST").build(); - Assert.assertEquals(set.size(), 1); - Assert.assertTrue(set.contains("TEST")); - - set = CollectionUtil.setBuilder().add(new String[] { "TEST", "FOO" }).build(); - Assert.assertEquals(set.size(), 2); - Assert.assertTrue(set.contains("TEST")); - Assert.assertTrue(set.contains("FOO")); - - Set set2 = CollectionUtil.setBuilder().addAll(set).build(); - Assert.assertEquals(set2, set); - Assert.assertNotSame(set2, set); - - set2 = CollectionUtil.setBuilder().addAll(set.iterator()).build(); - Assert.assertEquals(set2, set); - Assert.assertNotSame(set2, set); - } - - @Test(groups = "unit") - public void testMapBuilder() { - Map map = CollectionUtil.mapBuilder().build(); - Assert.assertEquals(map.size(), 0); - - map = CollectionUtil.mapBuilder().add(ImmutableMapEntry.make("TEST", 1)).build(); - Assert.assertEquals(map.size(), 1); - Assert.assertSame(map.get("TEST"), 1); - - map = CollectionUtil.mapBuilder() - .add(ImmutableMapEntry.make("TEST", 1)) - .add(ImmutableMapEntry.make("FOO", 2)) - .build(); - Assert.assertEquals(map.size(), 2); - Assert.assertSame(map.get("TEST"), 1); - Assert.assertSame(map.get("FOO"), 2); - } - - @Test(groups = "unit") - public void testSetOf0() { - Set set = CollectionUtil.setOf(Collections.emptyList()); - Assert.assertEquals(set.size(), 0); - - set = CollectionUtil.setOf(new String[0]); - Assert.assertEquals(set.size(), 0); - } - - @Test(groups = "unit") - public void testSetOf1() { - Set set = CollectionUtil.setOf("TEST"); - Assert.assertEquals(set.size(), 1); - Assert.assertTrue(set.contains("TEST")); - } - - @Test(groups = "unit") - public void testListOf0() { - List list = CollectionUtil.listOf(); - Assert.assertEquals(list.size(), 0); - } - - @Test(groups = "unit") - public void testListOf1() { - List list = CollectionUtil.listOf("TEST"); - Assert.assertEquals(list.size(), 1); - Assert.assertTrue(list.contains("TEST")); - - list = CollectionUtil.listOf(new String[] { "TEST" }); - Assert.assertEquals(list.size(), 1); - Assert.assertTrue(list.contains("TEST")); - } - - @Test(groups = "unit") - public void testListOf2() { - List list = CollectionUtil.listOf("TEST", "FOO"); - Assert.assertEquals(list.size(), 2); - Assert.assertTrue(list.contains("TEST")); - Assert.assertTrue(list.contains("FOO")); - } - - @Test(groups = "unit") - public void testMapOf0() { - @SuppressWarnings("unchecked") - ImmutableMapEntry[] empty = new ImmutableMapEntry[0]; - Map map = CollectionUtil.mapOfEntries(empty); - - Assert.assertEquals(map.size(), 0); - } - - @Test(groups = "unit") - public void testMapOf1() { - Map map = CollectionUtil.mapOfEntries(ImmutableMapEntry.make("ONE", 1)); - - Assert.assertEquals(map.size(), 1); - Assert.assertSame(map.get("ONE"), 1); - } - - @Test(groups = "unit") - public void testMapOf2() { - Map map = CollectionUtil.mapOf("ONE", 1, "TWO", 2); - - Assert.assertEquals(map.size(), 2); - Assert.assertSame(map.get("ONE"), 1); - Assert.assertSame(map.get("TWO"), 2); - } - - @Test(groups = "unit") - public void testMapOf3() { - Map map = CollectionUtil.mapOf("ONE", 1, "TWO", 2, "THREE", 3); - - Assert.assertEquals(map.size(), 3); - Assert.assertSame(map.get("ONE"), 1); - Assert.assertSame(map.get("TWO"), 2); - Assert.assertSame(map.get("THREE"), 3); - } - - @Test(groups = "unit") - public void testMapOf4() { - Map map = CollectionUtil.mapOf("ONE", 1, "TWO", 2, "THREE", 3, "FOUR", 4); - - Assert.assertEquals(map.size(), 4); - Assert.assertSame(map.get("ONE"), 1); - Assert.assertSame(map.get("TWO"), 2); - Assert.assertSame(map.get("THREE"), 3); - Assert.assertSame(map.get("FOUR"), 4); - } - - @Test(groups = "unit") - public void testConcat() { - List list1 = CollectionUtil.listOf(1, 2, 3); - List list2 = CollectionUtil.listOf(4, 5, 6); - - Iterator it = CollectionUtil.concat(list1.iterator(), list2.iterator()); - - Assert.assertTrue(it.hasNext()); - Assert.assertSame(it.next(), (Integer) 1); - Assert.assertTrue(it.hasNext()); - Assert.assertSame(it.next(), (Integer) 2); - Assert.assertTrue(it.hasNext()); - Assert.assertSame(it.next(), (Integer) 3); - Assert.assertTrue(it.hasNext()); - Assert.assertSame(it.next(), (Integer) 4); - Assert.assertTrue(it.hasNext()); - Assert.assertSame(it.next(), (Integer) 5); - Assert.assertTrue(it.hasNext()); - Assert.assertSame(it.next(), (Integer) 6); - Assert.assertFalse(it.hasNext()); - } - - @Test(groups = "unit") - public void testBatchOf() { - List original = IntStream.range(1, 101).mapToObj(Integer::valueOf).collect(Collectors.toList()); - Assert.assertEquals(original.size(), 100); - - List> batches = original.stream().collect(CollectionUtil.batchOf(10)); - - Assert.assertEquals(batches.size(), 10); - - int value = 1; - for (List batch: batches) { - Assert.assertEquals(batch.size(), 10); - for (Integer element: batch) { - Assert.assertSame(element, value++); - } - } - Assert.assertEquals(value, 101); - } - - @Test(groups = "unit") - public void testComputeIfAbsent() { - ConcurrentHashMap map = new ConcurrentHashMap<>(); - - CollectionUtil.computeIfAbsent(map, "Hello", k -> "World"); - Assert.assertTrue(map.containsKey("Hello")); - Assert.assertEquals(map.get("Hello"), "World"); - - CollectionUtil.computeIfAbsent(map, "Hello", k -> "World"); - Assert.assertTrue(map.containsKey("Hello")); - Assert.assertEquals(map.get("Hello"), "World"); - - CollectionUtil.computeIfAbsent(map, "Hello1", k -> "World1"); - Assert.assertTrue(map.containsKey("Hello1")); - Assert.assertEquals(map.get("Hello1"), "World1"); - } - - @Test(groups = "unit") - public void testDeepCloneArray() { - - String[] test1 = {}; - String[] test2 = { "a" }; - String[] test3 = { "a", "b" }; - - String[] result1 = CollectionUtil.deepCloneArray(test1); - Assert.assertNotSame(result1, test1); - Assert.assertEquals(result1, test1); - String[] result2 = CollectionUtil.deepCloneArray(test2); - Assert.assertNotSame(result2, test2); - Assert.assertEquals(result2, test2); - String[] result3 = CollectionUtil.deepCloneArray(test3); - Assert.assertNotSame(result3, test3); - Assert.assertEquals(result3, test3); - - String[][] test4 = { { "a" }, { "b", null } }; - String[][] result4 = CollectionUtil.deepCloneArray(test4); - Assert.assertNotSame(result4, test4); - Assert.assertEquals(result4.length, test4.length); - Assert.assertNotSame(result4[0], test4[0]); - Assert.assertEquals(result4[0], test4[0]); - Assert.assertNotSame(result4[1], test4[1]); - Assert.assertEquals(result4[1], test4[1]); - - // check that we can't trick it into an infinite loop and that - // the structure will be identical - Object[] test5 = { "foo", new String[] { "bar " }, new Object[] { null }, new int[] { 1, 2 } }; - ((Object[]) test5[2])[0] = test5; - Object[] result5 = CollectionUtil.deepCloneArray(test5); - Assert.assertNotSame(result5, test5); - Assert.assertEquals(result5.length, test5.length); - Assert.assertSame(result5[0], test5[0]); - Assert.assertNotSame(result5[1], test5[1]); - Assert.assertEquals(result5[1], test5[1]); - Assert.assertNotSame(result5[2], test5[2]); - Assert.assertEquals(((Object[]) result5[2]).length, 1); - Assert.assertSame(((Object[]) result5[2])[0], result5); - Assert.assertNotSame(result5[3], test5[3]); - Assert.assertEquals(result5[3], test5[3]); - - Object[] test6 = { new boolean[] { true }, new byte[] { 1 }, new short[] { 2 }, new char[] { 'C' }, new int[] { 5 }, - new float[] { 6.0f }, new long[] { 7L }, new double[] { 8.0 }, null, null }; - test6[9] = test6[2]; - Object[] result6 = CollectionUtil.deepCloneArray(test6); - Assert.assertNotSame(result6, test6); - Assert.assertEquals(result6.length, test6.length); - Assert.assertSame(result6[9], result6[2]); - Assert.assertNull(result6[8]); - for (int i = 0; i < 8; i++) { - Assert.assertNotSame(result6[i], test6[i]); - Assert.assertEquals(result6[i], test6[i]); - } - - } -} diff --git a/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/misc/TestExceptionUtil.java b/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/misc/TestExceptionUtil.java index 030ddc5858b..975129a39c3 100644 --- a/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/misc/TestExceptionUtil.java +++ b/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/misc/TestExceptionUtil.java @@ -114,9 +114,4 @@ public void testCheckException() { throw new IOException(); }, "Used")); } - - @Test(expectedExceptions = IOException.class, expectedExceptionsMessageRegExp = "Test Successful") - public void simpleThrowTest() { - ExceptionUtil.throwException(new IOException("Test Successful")); - } } diff --git a/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/misc/TestJoiner.java b/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/misc/TestJoiner.java deleted file mode 100644 index 4a02fee3df7..00000000000 --- a/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/misc/TestJoiner.java +++ /dev/null @@ -1,248 +0,0 @@ -package com.linkedin.alpini.base.misc; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Collections; -import javax.annotation.Nonnull; -import org.testng.Assert; -import org.testng.annotations.Test; - - -/** - * Implementation of tests based upon Google Collections JoinerTest - */ -public class TestJoiner { - private static final Joiner J = Joiner.on("-"); - - // needed to prevent warning :( - private static final Iterable ITERABLE_ = Collections.emptyList(); - private static final Iterable ITERABLE_1 = Collections.singletonList(1); - private static final Iterable ITERABLE_12 = Arrays.asList(1, 2); - private static final Iterable ITERABLE_123 = Arrays.asList(1, 2, 3); - private static final Iterable ITERABLE_NULL = Collections.singletonList(null); - private static final Iterable ITERABLE_NULL_NULL = Arrays.asList((Integer) null, null); - private static final Iterable ITERABLE_NULL_1 = Arrays.asList(null, 1); - private static final Iterable ITERABLE_1_NULL = Arrays.asList(1, null); - private static final Iterable ITERABLE_1_NULL_2 = Arrays.asList(1, null, 2); - private static final Iterable ITERABLE_FOUR_NULLS = Arrays.asList((Integer) null, null, null, null); - - @Test(groups = "unit") - public void testNoSpecialNullBehavior() { - checkNoOutput(J, ITERABLE_); - checkResult(J, ITERABLE_1, "1"); - checkResult(J, ITERABLE_12, "1-2"); - checkResult(J, ITERABLE_123, "1-2-3"); - - try { - J.join(ITERABLE_NULL); - Assert.fail(); - } catch (NullPointerException expected) { - } - try { - J.join(ITERABLE_1_NULL_2); - Assert.fail(); - } catch (NullPointerException expected) { - } - - try { - J.join(ITERABLE_NULL.iterator()); - Assert.fail(); - } catch (NullPointerException expected) { - } - try { - J.join(ITERABLE_1_NULL_2.iterator()); - Assert.fail(); - } catch (NullPointerException expected) { - } - } - - @Test(groups = "unit") - public void testOnCharOverride() { - Joiner onChar = Joiner.on('-'); - checkNoOutput(onChar, ITERABLE_); - checkResult(onChar, ITERABLE_1, "1"); - checkResult(onChar, ITERABLE_12, "1-2"); - checkResult(onChar, ITERABLE_123, "1-2-3"); - } - - @Test(groups = "unit") - public void testSkipNulls() { - Joiner skipNulls = J.skipNulls(); - checkNoOutput(skipNulls, ITERABLE_); - checkNoOutput(skipNulls, ITERABLE_NULL); - checkNoOutput(skipNulls, ITERABLE_NULL_NULL); - checkNoOutput(skipNulls, ITERABLE_FOUR_NULLS); - checkResult(skipNulls, ITERABLE_1, "1"); - checkResult(skipNulls, ITERABLE_12, "1-2"); - checkResult(skipNulls, ITERABLE_123, "1-2-3"); - checkResult(skipNulls, ITERABLE_NULL_1, "1"); - checkResult(skipNulls, ITERABLE_1_NULL, "1"); - checkResult(skipNulls, ITERABLE_1_NULL_2, "1-2"); - } - - @Test(groups = "unit") - public void testUseForNull() { - Joiner zeroForNull = J.useForNull("0"); - checkNoOutput(zeroForNull, ITERABLE_); - checkResult(zeroForNull, ITERABLE_1, "1"); - checkResult(zeroForNull, ITERABLE_12, "1-2"); - checkResult(zeroForNull, ITERABLE_123, "1-2-3"); - checkResult(zeroForNull, ITERABLE_NULL, "0"); - checkResult(zeroForNull, ITERABLE_NULL_NULL, "0-0"); - checkResult(zeroForNull, ITERABLE_NULL_1, "0-1"); - checkResult(zeroForNull, ITERABLE_1_NULL, "1-0"); - checkResult(zeroForNull, ITERABLE_1_NULL_2, "1-0-2"); - checkResult(zeroForNull, ITERABLE_FOUR_NULLS, "0-0-0-0"); - } - - private static void checkNoOutput(Joiner joiner, Iterable set) { - Assert.assertEquals(joiner.join(set), ""); - Assert.assertEquals(joiner.join(set.iterator()), ""); - - Object[] array = CollectionUtil.stream(set).toArray(Integer[]::new); - Assert.assertEquals(joiner.join(array), ""); - - StringBuilder sb1FromIterable = new StringBuilder(); - Assert.assertSame(joiner.appendTo(sb1FromIterable, set), sb1FromIterable); - Assert.assertEquals(sb1FromIterable.length(), 0); - - StringBuilder sb1FromIterator = new StringBuilder(); - Assert.assertSame(joiner.appendTo(sb1FromIterator, set), sb1FromIterator); - Assert.assertEquals(sb1FromIterator.length(), 0); - - StringBuilder sb2 = new StringBuilder(); - Assert.assertSame(joiner.appendTo(sb2, array), sb2); - Assert.assertEquals(sb2.length(), 0); - - try { - joiner.appendTo(NASTY_APPENDABLE, set); - } catch (IOException e) { - throw new AssertionError(e); - } - - try { - joiner.appendTo(NASTY_APPENDABLE, set.iterator()); - } catch (IOException e) { - throw new AssertionError(e); - } - - try { - joiner.appendTo(NASTY_APPENDABLE, array); - } catch (IOException e) { - throw new AssertionError(e); - } - } - - private static final Appendable NASTY_APPENDABLE = new Appendable() { - @Override - public Appendable append(CharSequence csq) throws IOException { - throw new IOException(); - } - - @Override - public Appendable append(CharSequence csq, int start, int end) throws IOException { - throw new IOException(); - } - - @Override - public Appendable append(char c) throws IOException { - throw new IOException(); - } - }; - - private static void checkResult(Joiner joiner, Iterable parts, String expected) { - Assert.assertEquals(joiner.join(parts), expected); - Assert.assertEquals(joiner.join(parts.iterator()), expected); - - StringBuilder sb1FromIterable = new StringBuilder().append('x'); - joiner.appendTo(sb1FromIterable, parts); - Assert.assertEquals(sb1FromIterable.toString(), "x" + expected); - - StringBuilder sb1FromIterator = new StringBuilder().append('x'); - joiner.appendTo(sb1FromIterator, parts.iterator()); - Assert.assertEquals(sb1FromIterator.toString(), "x" + expected); - - Integer[] partsArray = CollectionUtil.stream(parts).toArray(Integer[]::new); - Assert.assertEquals(joiner.join(partsArray), expected); - - StringBuilder sb2 = new StringBuilder().append('x'); - joiner.appendTo(sb2, partsArray); - Assert.assertEquals(sb2.toString(), "x" + expected); - - int num = partsArray.length - 2; - if (num >= 0) { - Object[] rest = new Integer[num]; - for (int i = 0; i < num; i++) { - rest[i] = partsArray[i + 2]; - } - - Assert.assertEquals(joiner.join(partsArray[0], partsArray[1], rest), expected); - - StringBuilder sb3 = new StringBuilder().append('x'); - joiner.appendTo(sb3, partsArray[0], partsArray[1], rest); - Assert.assertEquals(sb3.toString(), "x" + expected); - } - } - - @Test(groups = "unit") - public void test_useForNull_skipNulls() { - Joiner j = Joiner.on("x").useForNull("y"); - try { - j = j.skipNulls(); - Assert.fail(); - } catch (UnsupportedOperationException expected) { - } - } - - @Test(groups = "unit") - public void test_skipNulls_useForNull() { - Joiner j = Joiner.on("x").skipNulls(); - try { - j = j.useForNull("y"); - Assert.fail(); - } catch (UnsupportedOperationException expected) { - } - } - - @Test(groups = "unit") - public void test_useForNull_twice() { - Joiner j = Joiner.on("x").useForNull("y"); - try { - j = j.useForNull("y"); - Assert.fail(); - } catch (UnsupportedOperationException expected) { - } - } - - private static class DontStringMeBro implements CharSequence { - @Override - public int length() { - return 3; - } - - @Override - public char charAt(int index) { - return "foo".charAt(index); - } - - @Override - public CharSequence subSequence(int start, int end) { - return "foo".subSequence(start, end); - } - - @Override - @Nonnull - public String toString() { - Assert.fail("shouldn't be invoked"); - return "Never gets here"; - } - } - - @Test(groups = "unit") // StringBuilder.append in GWT invokes Object.toString(), unlike the JRE version. - public void testDontConvertCharSequenceToString() { - Assert.assertEquals(Joiner.on(",").join(new DontStringMeBro(), new DontStringMeBro()), "foo,foo"); - Assert.assertEquals( - Joiner.on(",").useForNull("bar").join(new DontStringMeBro(), null, new DontStringMeBro()), - "foo,bar,foo"); - } -} diff --git a/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/misc/TestRetryCountSlidingWindow.java b/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/misc/TestRetryCountSlidingWindow.java deleted file mode 100644 index 7488dff611a..00000000000 --- a/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/misc/TestRetryCountSlidingWindow.java +++ /dev/null @@ -1,184 +0,0 @@ -package com.linkedin.alpini.base.misc; - -import com.linkedin.alpini.base.concurrency.Executors; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - - -/** - * @author solu - * Date: 4/27/21 - */ -@Test(groups = "unit") -public class TestRetryCountSlidingWindow { - static final Logger LOG = LogManager.getLogger(TestRetryCountSlidingWindow.class); - private final int _ioWorkersCount = 64; - private final double _error = 0.005; - private final int _ioWorkerUpdateIntervalMs = 20; - // Each ioWorker would put 1000 requests in every 20 ms == 100 * (1000/20) = 5K/s for one ioWorker. - // The total QPS would be 5 K * 64 = 320,000 /s. - final int _totalCount = 100; - final int _initRetryCut = 20; - final int _secondRetryCut = 40; - - int _windowLen = 5; - int _runningSeconds = 20; - ScheduledExecutorService _shutdown; - - @BeforeClass - public void beforeClass() { - _shutdown = Executors.newSingleThreadScheduledExecutor(); - } - - @AfterClass - public void afterClass() { - _shutdown.shutdownNow(); - } - - public void testAtSteadyRate() throws InterruptedException { - ScheduledExecutorService updater = Executors.newScheduledThreadPool(1); - RetryCountSlidingWindow w = new RetryCountSlidingWindow(1000, _windowLen, updater); - updater.shutdown(); - - ScheduledExecutorService ioWorkers = Executors.newScheduledThreadPool(_ioWorkersCount); - ScheduledExecutorService resultCollector = Executors.newScheduledThreadPool(1); - AtomicInteger cut = new AtomicInteger(_initRetryCut); - - for (int i = 0; i < _ioWorkersCount; i++) { - ioWorkers.scheduleAtFixedRate(() -> { - // every time putting 10 request with 2 being retried - // so the retryRatio should be 20% - CounterQueue q = w.getQueue(); - // LOG.error("Fill the queue by {}", Thread.currentThread().getName()); - for (int j = 0; j < _totalCount; j++) { - q.increaseCount(j < cut.get()); - } - }, 0, _ioWorkerUpdateIntervalMs, TimeUnit.MILLISECONDS); - } - - List results = new LinkedList<>(); - retrieveRatioDuringRun(w, cut, _totalCount, resultCollector, results); - scheduleShutdown(ioWorkers, resultCollector, _runningSeconds); - - for (Result r: results) { - Assert.assertEquals( - r.actual, - r.expected, - _error, - String.format("ActualRatio is %f is too much away from the expected %f", r.actual, r.expected)); - } - - updater.shutdownNow(); - } - - public void testAtVariantRate() throws InterruptedException { - ScheduledExecutorService updater = Executors.newScheduledThreadPool(1); - RetryCountSlidingWindow w = new RetryCountSlidingWindow(1000, _windowLen, updater); - - ScheduledExecutorService ioWorkers = Executors.newScheduledThreadPool(_ioWorkersCount); - ScheduledExecutorService resultCollector = Executors.newScheduledThreadPool(1); - AtomicInteger cut = new AtomicInteger(_initRetryCut); - - final long startSecond = RetryCounter.getCurrentSecond(); - - for (int i = 0; i < _ioWorkersCount; i++) { - ioWorkers.scheduleAtFixedRate(() -> { - // every time putting 10 request with 2 being retried - // so the retryRatio should be 20% - CounterQueue q = w.getQueue(); - if (RetryCounter.getCurrentSecond() - startSecond >= _runningSeconds / 2) { - // change the cut in the half way - cut.set(_secondRetryCut); - } - // LOG.error("Fill the queue by {}", Thread.currentThread().getName()); - for (int j = 0; j < _totalCount; j++) { - q.increaseCount(j < cut.get()); - } - }, 0, _ioWorkerUpdateIntervalMs, TimeUnit.MILLISECONDS); - } - - List results = new LinkedList<>(); - retrieveRatioDuringRun(w, cut, _totalCount, resultCollector, results); - scheduleShutdown(ioWorkers, resultCollector, _runningSeconds); - - for (Result r: results) { - double initExpectedRatio = (double) _initRetryCut / _totalCount; - if (Math.abs(r.expected - initExpectedRatio) < _error) { - Assert.assertEquals( - r.actual, - r.expected, - _error, - String.format("ActualRatio is %f is too much away from the expected %f", r.actual, r.expected)); - } else { - // now the ratio should be different and gradually increased from 0.2 to 0.4 or less. - Assert.assertTrue( - r.actual >= initExpectedRatio - _error && r.actual <= r.expected + _error, - String.format( - "ActualRatio is %f is not between expected range: %f --> %f", - r.actual, - initExpectedRatio, - r.expected)); - } - } - updater.shutdownNow(); - } - - private void scheduleShutdown( - ScheduledExecutorService ioWorkers, - ScheduledExecutorService collector, - int runningSeconds) throws InterruptedException { - _shutdown.schedule(() -> { - ioWorkers.shutdownNow(); - collector.shutdownNow(); - - }, runningSeconds, TimeUnit.SECONDS); - - ioWorkers.awaitTermination(runningSeconds, TimeUnit.SECONDS); - collector.awaitTermination(runningSeconds, TimeUnit.SECONDS); - - } - - private void retrieveRatioDuringRun( - RetryCountSlidingWindow w, - AtomicInteger cut, - int totalCount, - ScheduledExecutorService collector, - List results) { - collector.scheduleWithFixedDelay(() -> { - double expected = (double) cut.get() / (double) totalCount; - String s = String.format( - "Expected retry ratio: %f and actual %f, retryCount: %d, total: %d", - expected, - w.getRetryRatio(), - w.getRetryCount(), - w.getTotalCount()); - // LOG.error(s); - if (w.getTotalCount() > 0) { - results.add(new Result(s, expected, w.getRetryRatio())); - } - - }, 100, 1000, TimeUnit.MILLISECONDS); - } - - private static class Result { - String s; - double expected; - double actual; - - public Result(String s, double expected, double actual) { - this.s = s; - this.expected = expected; - this.actual = actual; - } - } - -} diff --git a/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/misc/TestTouchTimer.java b/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/misc/TestTouchTimer.java deleted file mode 100644 index 37135a01e7b..00000000000 --- a/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/misc/TestTouchTimer.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * $Id$ - */ -package com.linkedin.alpini.base.misc; - -import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.regex.Pattern; -import org.mockito.Mockito; -import org.testng.Assert; -import org.testng.annotations.Test; - - -/** - * @author Jemiah Westerman <jwesterman@linkedin.com> - * - * @version $Revision$ - */ -public class TestTouchTimer { - @Test(groups = "unit") - public void test1() throws Exception { - synchronized (Time.class) { - try { - Time.freeze(); - test0(new TouchTimer(), Pattern.compile("Total Time: 0ms Trace: ")); - } finally { - Time.restore(); - } - } - } - - @Test(groups = "unit") - public void test2() throws Exception { - synchronized (Time.class) { - try { - Time.freeze(); - long millis = Time.currentTimeMillis(); - long nanos = Time.nanoTime(); - Thread.sleep(2); - test0(new TouchTimer(millis, nanos, 5), Pattern.compile("Total Time: \\dms Trace: \\[[^]]+ start [^]]+]")); - } finally { - Time.restore(); - } - } - } - - private void test0(final TouchTimer timer, Pattern emptyRegexp) throws Exception { - - // Test functions on an empty timer - Assert.assertEquals(timer.getElapsedTimeMillis(), 0); - Assert.assertTrue(emptyRegexp.matcher(timer.toString()).matches(), timer.toString()); - - // Add a few touches and test functions again - timer.touch(getClass(), "first"); - Time.advance(2, TimeUnit.MILLISECONDS); - timer.touch(getClass(), "second(%s)", "string"); - Time.advance(2, TimeUnit.MILLISECONDS); - timer.touch(getClass(), "third"); - - Assert.assertTrue( - timer.getElapsedTimeMillis() >= 4, - "Expected total delta >= 4. Was: " + timer.getElapsedTimeMillis()); - - Time.restore(); - - // Touch from another thread to make sure we get the thread name in the final output - Thread t = new Thread("Test Thread") { - @Override - public void run() { - timer.touch("from another thread"); - } - }; - t.start(); - t.join(); - - // Make sure the final output has all the important bits of info - String s = timer.toString(); - Assert.assertTrue(s.contains("first"), "toString was missing \"first\" touch."); - Assert.assertTrue(s.contains("second(string)"), "toString was missing \"second\" touch."); - Assert.assertTrue(s.contains("third"), "toString was missing \"third\" touch."); - Assert.assertTrue(s.contains("from another thread"), "toString was missing \"from another thread\" touch."); - Assert.assertTrue(s.contains("Test Thread"), "toString was missing thread name \"Test Thread\"."); - Assert.assertTrue(s.contains("TestTouchTimer"), "toString was missing the class name \"TestTouchTimer\"."); - } - - @Test(groups = "unit") - public void testStringDedup() { - // Make sure thread names are deduped - Assert.assertSame( - TouchTimer.getDedupedThreadName(), - TouchTimer.getDedupedThreadName(), - "Thread name was not de-duped."); - - // Create a timer and add a couple touches. Then check that they are properly deduped. - final TouchTimer timer = new TouchTimer(); - String s = "This is a String"; - timer.touch(s); - timer.touch(s); - - // Make sure that the actual message is not duplicated. Since we touched with the same String instance twice, this - // should - // be the case. - List messages = timer.getMessages(); - Assert.assertEquals(messages.size(), 2); - Assert.assertSame(messages.get(0)._name, s); - Assert.assertSame(messages.get(1)._name, s); - - // Make sure the thread name is not duplicated - Assert.assertSame( - messages.get(0)._threadName, - messages.get(1)._threadName, - "_threadName for two messages should reference the same String instance. It is not sufficiet that they have the same name."); - } - - @Test(groups = "unit") - public void testMessageCutoff() { - final TouchTimer timer = new TouchTimer(); - for (int i = 1; i < TouchTimer.DEFAULT_MAX_MESSAGES + 50; i++) - timer.touch(String.valueOf(i)); - - // We expect DEFAULT_MAX_MESSAGES from the application, plus one additional message at the end saying we're not - // adding any more messages - // Total expected is DEFAULT_MAX_MESSAGES + 1 - List messages = timer.getMessages(); - Assert.assertEquals(messages.size(), TouchTimer.DEFAULT_MAX_MESSAGES + 1); - // Make sure the last message is the error message - Assert.assertTrue( - messages.get(messages.size() - 1)._name - .contains("TouchTimer Warning: Exceeded the maximum number of messages allowed")); - // Make sure the last message is the one we expect. - Assert.assertEquals(messages.get(messages.size() - 2)._name, String.valueOf(TouchTimer.DEFAULT_MAX_MESSAGES)); - - TouchTimer.Visitor visitor = Mockito.mock(TouchTimer.Visitor.class); - timer.forEachMessage(visitor); - - Mockito.verify(visitor, Mockito.times(TouchTimer.DEFAULT_MAX_MESSAGES + 1)) - .visit(Mockito.anyLong(), Mockito.anyString(), Mockito.any(), Mockito.anyString(), Mockito.any()); - Mockito.verifyNoMoreInteractions(visitor); - } - - @Test(groups = "unit") - public void testEmptyTimer() { - final TouchTimer timer = new TouchTimer(); - // Make sure these methods behave as expected on a timer with no messages. - Assert.assertEquals(timer.getMessages().size(), 0); - Assert.assertEquals(timer.getElapsedTimeMillis(), 0); - - TouchTimer.Visitor visitor = Mockito.mock(TouchTimer.Visitor.class); - timer.forEachMessage(visitor); - Mockito.verifyNoMoreInteractions(visitor); - } - -} diff --git a/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/monitoring/TestCallTracker.java b/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/monitoring/TestCallTracker.java deleted file mode 100644 index 4543a940f36..00000000000 --- a/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/monitoring/TestCallTracker.java +++ /dev/null @@ -1,325 +0,0 @@ -package com.linkedin.alpini.base.monitoring; - -import com.linkedin.alpini.base.concurrency.ConcurrentAccumulator; -import com.linkedin.alpini.base.misc.Time; -import com.linkedin.alpini.base.statistics.Welfords; -import java.util.Arrays; -import java.util.concurrent.ForkJoinPool; -import java.util.concurrent.RecursiveAction; -import java.util.concurrent.ThreadLocalRandom; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.LongAdder; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.testng.Assert; -import org.testng.annotations.AfterTest; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - - -/** - * @author Antony T Curtis {@literal } - */ -public class TestCallTracker { - private static final Logger LOG = LogManager.getLogger(TestCallTracker.class); - static final ConcurrentAccumulator.Mode DEFAULT_MODE = ConcurrentAccumulator.defaultMode; - - @AfterTest(groups = { "unit", "functional" }) - public void resetMode() { - ConcurrentAccumulator.defaultMode = DEFAULT_MODE; - CallTrackerImpl.defaultMode = CallTrackerImpl.Mode.SKIP_LIST; - } - - private static final Object[][] ACCUMULATOR_MODES = - { { ConcurrentAccumulator.Mode.COMPLEX, CallTrackerImpl.Mode.SKIP_LIST }, - { ConcurrentAccumulator.Mode.THREADED, CallTrackerImpl.Mode.SKIP_LIST }, - { ConcurrentAccumulator.Mode.COMPLEX, CallTrackerImpl.Mode.ARRAY_LIST }, - { ConcurrentAccumulator.Mode.THREADED, CallTrackerImpl.Mode.ARRAY_LIST }, }; - - @DataProvider - public Object[][] accumulatorModes() { - return ACCUMULATOR_MODES; - } - - @Test(groups = { "unit", "NoCoverage" }, dataProvider = "accumulatorModes") - public void testBasic(ConcurrentAccumulator.Mode mode, CallTrackerImpl.Mode stats) { - testBasic(mode, stats, 30); - } - - @Test(groups = { "unit", "Coverage" }, dataProvider = "accumulatorModes") - public void testBasicCoverage(ConcurrentAccumulator.Mode mode, CallTrackerImpl.Mode stats) { - testBasic(mode, stats, 3); - } - - private void testBasic(ConcurrentAccumulator.Mode mode, CallTrackerImpl.Mode statsMode, int testDuration) { - ConcurrentAccumulator.defaultMode = mode; - CallTrackerImpl.defaultMode = statsMode; - - CallTracker tracker = CallTracker.create(); - Assert.assertEquals(tracker.getTimeSinceLastStartCall(), 0); - - long endTime = Time.nanoTime() + TimeUnit.SECONDS.toNanos(testDuration); - - do { - - for (int i = 0; i < 100000; i++) { - try (CallCompletion cc = tracker.startCall()) { - if (i % 97 == 42) { - cc.closeWithError(); - } - } - } - - CallTracker.CallStats stats = tracker.getCallStats(); - - System.out.println(stats); - - } while (Time.nanoTime() < endTime); - } - - @Test(groups = { "unit", "NoCoverage" }, dataProvider = "accumulatorModes") - public void testBasicDelay(ConcurrentAccumulator.Mode mode, CallTrackerImpl.Mode stats) throws InterruptedException { - testBasicDelay(mode, stats, 30); - } - - @Test(groups = { "unit", "Coverage" }, dataProvider = "accumulatorModes") - public void testBasicDelayCoverage(ConcurrentAccumulator.Mode mode, CallTrackerImpl.Mode stats) - throws InterruptedException { - testBasicDelay(mode, stats, 3); - } - - private void testBasicDelay(ConcurrentAccumulator.Mode mode, CallTrackerImpl.Mode statsMode, int testDuration) - throws InterruptedException { - ConcurrentAccumulator.defaultMode = mode; - CallTrackerImpl.defaultMode = statsMode; - - CallTracker tracker = CallTracker.create(); - - long endTime = Time.nanoTime() + TimeUnit.SECONDS.toNanos(testDuration); - - do { - - for (int i = 0; i < 1000; i++) { - try (CallCompletion cc = tracker.startCall()) { - Thread.sleep(1); - if (i % 97 == 42) { - cc.closeWithError(); - } - } - } - - CallTracker.CallStats stats = tracker.getCallStats(); - - System.out.println(stats); - - } while (Time.nanoTime() < endTime); - } - - /*static class MinMax { - final long min; - final long max; - - MinMax(long min, long max) { - this.min = min; - this.max = max; - } - - MinMax apply(long value) { - return new MinMax(Math.min(min, value), Math.max(max, value)); - } - }*/ - - @Test(groups = "unit", singleThreaded = true, dataProvider = "accumulatorModes") - public void testConcurrency(ConcurrentAccumulator.Mode mode, CallTrackerImpl.Mode statsMode) { - ConcurrentAccumulator.defaultMode = mode; - CallTrackerImpl.defaultMode = statsMode; - - CallTracker tracker = CallTracker.create(); - - try { - Time.freeze(); - tracker.reset(); - - Assert.assertEquals(tracker.getMaxConcurrency()[0], 0); - Assert.assertEquals(tracker.getCurrentStartCountTotal(), 0); - - CallCompletion cc = tracker.startCall(); - - Assert.assertEquals(tracker.getCurrentConcurrency(), 1); - Assert.assertEquals(tracker.getCurrentStartCountTotal(), 1); - Assert.assertEquals(tracker.getCurrentCallCountTotal(), 0); - Assert.assertEquals(tracker.getLastResetTime(), Time.currentTimeMillis()); - - Time.advance(1, TimeUnit.SECONDS); - Assert.assertEquals(tracker.getStartFrequency()[0], 1); - Assert.assertEquals(tracker.getStartCount()[0], 1); - - Time.advance(58, TimeUnit.SECONDS); - - Assert.assertEquals(tracker.getCurrentConcurrency(), 1); - Assert.assertEquals(tracker.getMaxConcurrency()[0], 1); - - Assert.assertEquals(tracker.getCallStats().getAverageConcurrency1min(), 1.0, 0.1); - - cc.closeCompletion(null, null); - - Assert.assertEquals(tracker.getCurrentConcurrency(), 0); - Assert.assertEquals(tracker.getCurrentStartCountTotal(), 1); - Assert.assertEquals(tracker.getCurrentCallCountTotal(), 1); - Assert.assertEquals(tracker.getCurrentErrorCountTotal(), 0); - Assert.assertEquals(tracker.getAverageConcurrency()[0], 1.0, 0.1); - - Time.advance(1, TimeUnit.MINUTES); - - Assert.assertEquals(tracker.getAverageConcurrency()[0], 0.0, 0.1); - Assert.assertEquals(tracker.getAverageConcurrency()[1], 0.2, 0.01); - Assert.assertEquals(tracker.getStartFrequency()[0], 0); - Assert.assertEquals(tracker.getStartCount()[0], 0); - Assert.assertEquals(tracker.getErrorFrequency()[0], 0); - Assert.assertEquals(tracker.getErrorCount()[0], 0); - - Time.advance(13, TimeUnit.MINUTES); - - Assert.assertEquals(tracker.getMaxConcurrency()[2], 1); // Max concurrency during past 15 minutes - - Time.advance(1, TimeUnit.MINUTES); - - Assert.assertEquals(tracker.getCallStats().getAverageConcurrency5min(), 0.0, 0.001); - Assert.assertEquals(tracker.getCallStats().getAverageConcurrency15min(), 0.0, 0.001); - Assert.assertEquals(tracker.getMaxConcurrency()[2], 0); - - } finally { - Time.restore(); - } - } - - @Test(groups = "functional", dataProvider = "accumulatorModes") - public void testHighConcurrency(ConcurrentAccumulator.Mode mode, CallTrackerImpl.Mode statsMode) - throws InterruptedException { - ConcurrentAccumulator.defaultMode = mode; - CallTrackerImpl.defaultMode = statsMode; - - LongAdder count = new LongAdder(); - CallTracker[] callTracker = new CallTracker[] { CallTracker.create(), CallTracker.create(), CallTracker.create(), - CallTracker.create(), CallTracker.create(), CallTracker.create(), CallTracker.create(), CallTracker.create() }; - - ForkJoinPool executorService = new ForkJoinPool(); - // AtomicReference closeTime = new AtomicReference<>(new MinMax(Long.MAX_VALUE, 0)); - ConcurrentAccumulator closeWelfords = - new ConcurrentAccumulator<>(Welfords.LongWelford.COLLECTOR); - - // AtomicReference startTime = new AtomicReference<>(new MinMax(Long.MAX_VALUE, 0)); - ConcurrentAccumulator startWelfords = - new ConcurrentAccumulator<>(Welfords.LongWelford.COLLECTOR); - try { - - // We have to use ForkJoinPool/RecursiveAction because using simpler ThreadPool/Runnable - // is unable to max out all the cores due to overhead in the ThreadPoolExecutorService. - - class CloseTask extends RecursiveAction { - private final CallCompletion _cc; - private final RecursiveAction _nextStart; - - CloseTask(CallCompletion cc, RecursiveAction nextStart) { - _cc = cc; - _nextStart = nextStart; - } - - @Override - protected void compute() { - long time = Time.nanoTime(); - int rnd = ThreadLocalRandom.current().nextInt(97); - - if (rnd == 42) { - _cc.closeWithError(); - } else { - _cc.close(); - } - long closeDelta = Time.nanoTime() - time; - count.increment(); - - // MinMax test = closeTime.get(); - // if (test.max < closeDelta || test.min > closeDelta) { - // closeTime.updateAndGet(minMax -> minMax.apply(closeDelta)); - // } - closeWelfords.accept(closeDelta); - - executorService.submit(_nextStart); - } - } - - class StartTask extends RecursiveAction { - @Override - protected void compute() { - long time = Time.nanoTime(); - CallCompletion cc = callTracker[ThreadLocalRandom.current().nextInt(callTracker.length)].startCall(); - long startDelta = Time.nanoTime() - time; - - // MinMax test = startTime.get(); - // if (test.max < startDelta || test.min > startDelta) { - // startTime.updateAndGet(minMax -> minMax.apply(startDelta)); - // } - startWelfords.accept(startDelta); - - RecursiveAction nextStart = new StartTask(); - - executorService.submit(new CloseTask(cc, nextStart)); - } - } - - final int NUMBER_OF_TASKS = 4800; - - for (int i = NUMBER_OF_TASKS; i > 0; i--) { - executorService.submit(new StartTask()); - } - - long lastCount = 0; - int foo = 0; - for (long endTime = Time.currentTimeMillis() + TimeUnit.MINUTES.toMillis(5); endTime > Time - .currentTimeMillis(); Time.sleep(10000)) { - LOG.error("gather"); - long thisCount = count.longValue(); - // MinMax close = closeTime.getAndSet(new MinMax(Long.MAX_VALUE, 0)); - // MinMax start = startTime.getAndSet(new MinMax(Long.MAX_VALUE, 0)); - // long closeMax = close.max; - // long closeMin = close.min; - // long startMax = start.max; - // long startMin = start.min; - Welfords.LongWelford.Result std = closeWelfords.getThenReset(); - Welfords.LongWelford.Result std2 = startWelfords.getThenReset(); - LOG.error( - "calls: {}, delta: {}, \r\n" + "close {}\r\n" + "start {}", - thisCount, - thisCount - lastCount, - std, - std2); - - for (CallTracker ct: callTracker) { - CallTracker.CallStats stats = ct.getCallStats(); - LOG.error("Stats: {}", stats); - } - if ((++foo) % 60 == 0) { - for (CallTracker ct: callTracker) { - ct.reset(); - } - } - lastCount = thisCount; - - Assert.assertTrue( - Arrays.stream(callTracker).mapToInt(CallTracker::getCurrentConcurrency).sum() < NUMBER_OF_TASKS); - - } - - } finally { - executorService.shutdownNow(); - } - - LOG.error("calls: {}", count); - - for (CallTracker ct: callTracker) { - CallTracker.CallStats stats = ct.getCallStats(); - LOG.error("Stats: {}", stats); - } - } - -} diff --git a/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/monitoring/TestNullCallTracker.java b/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/monitoring/TestNullCallTracker.java deleted file mode 100644 index 168bb8bf6ce..00000000000 --- a/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/monitoring/TestNullCallTracker.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.linkedin.alpini.base.monitoring; - -import com.linkedin.alpini.base.statistics.LongStats; -import org.testng.Assert; -import org.testng.annotations.Test; - - -@Test(groups = "unit") -public class TestNullCallTracker { - private final CallTracker _callTracker = CallTracker.nullTracker(); - - @Test - public void invokeEveryMethod() { - - CallCompletion completion = _callTracker.startCall(); - - _callTracker.reset(); - - _callTracker.trackCall(1L); - - _callTracker.trackCallWithError(1L); - _callTracker.trackCallWithError(1L, new NullPointerException()); - - Assert.assertEquals(_callTracker.getCurrentStartCountTotal(), 0); - Assert.assertEquals(_callTracker.getCurrentCallCountTotal(), 0); - Assert.assertEquals(_callTracker.getCurrentErrorCountTotal(), 0); - Assert.assertEquals(_callTracker.getCurrentConcurrency(), 0); - Assert.assertEquals(_callTracker.getAverageConcurrency(), new double[0]); - Assert.assertEquals(_callTracker.getMaxConcurrency(), new int[0]); - Assert.assertEquals(_callTracker.getStartFrequency(), new int[0]); - Assert.assertEquals(_callTracker.getStartCount(), new long[0]); - Assert.assertEquals(_callTracker.getErrorFrequency(), new int[0]); - Assert.assertEquals(_callTracker.getErrorCount(), new long[0]); - - CallTracker.CallStats stats = _callTracker.getCallStats(); - - Assert.assertEquals(_callTracker.getLastResetTime(), 0); - Assert.assertEquals(_callTracker.getTimeSinceLastStartCall(), 0); - - completion.close(); - completion.closeWithError(); - completion.closeWithError(new NullPointerException()); - completion.closeCompletion(null, new NullPointerException()); - completion.closeCompletion(true, null); - - CallCompletion.combine(completion).close(); - CallCompletion.combine(completion).closeWithError(); - - Assert.assertEquals(stats.getCallCountTotal(), 0); - Assert.assertEquals(stats.getCallStartCountTotal(), 0); - Assert.assertEquals(stats.getErrorCountTotal(), 0); - Assert.assertEquals(stats.getConcurrency(), 0); - Assert.assertEquals(stats.getAverageConcurrency1min(), 0.0); - Assert.assertEquals(stats.getAverageConcurrency5min(), 0.0); - Assert.assertEquals(stats.getAverageConcurrency15min(), 0.0); - Assert.assertEquals(stats.getMaxConcurrency1min(), 0); - Assert.assertEquals(stats.getMaxConcurrency5min(), 0); - Assert.assertEquals(stats.getMaxConcurrency15min(), 0); - Assert.assertEquals(stats.getStartFrequency1min(), 0); - Assert.assertEquals(stats.getStartFrequency5min(), 0); - Assert.assertEquals(stats.getStartFrequency15min(), 0); - Assert.assertEquals(stats.getErrorFrequency1min(), 0); - Assert.assertEquals(stats.getErrorFrequency5min(), 0); - Assert.assertEquals(stats.getErrorFrequency15min(), 0); - Assert.assertEquals(stats.getOutstandingStartTimeAvg(), 0); - Assert.assertEquals(stats.getOutstandingCount(), 0); - - LongStats longStats = stats.getCallTimeStats(); - - Assert.assertEquals(longStats.getLongCount(), 0); - Assert.assertEquals(longStats.getAverage(), 0.0); - Assert.assertEquals(longStats.getStandardDeviation(), 0.0); - Assert.assertNull(longStats.getMinimum()); - Assert.assertNull(longStats.getMaximum()); - Assert.assertNull(longStats.get50Pct()); - Assert.assertNull(longStats.get90Pct()); - Assert.assertNull(longStats.get95Pct()); - Assert.assertNull(longStats.get99Pct()); - Assert.assertNull(longStats.get99_9Pct()); - - } - -} diff --git a/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/pool/TestAsyncPool.java b/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/pool/TestAsyncPool.java deleted file mode 100644 index 80de661ede3..00000000000 --- a/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/pool/TestAsyncPool.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.linkedin.alpini.base.pool; - -import com.linkedin.alpini.base.concurrency.ExecutorService; -import com.linkedin.alpini.base.concurrency.Executors; -import com.linkedin.alpini.base.registry.ResourceRegistry; -import com.linkedin.alpini.base.registry.Shutdownable; -import com.linkedin.alpini.base.registry.ShutdownableResource; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; -import org.mockito.Mockito; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - - -/** - * @author Antony T Curtis {@literal } - */ -@Test(groups = "unit") -public class TestAsyncPool { - private ExecutorService _executor; - - @BeforeClass(groups = "unit") - public void beforeClass() { - _executor = Executors.newSingleThreadExecutor(); - } - - class Element { - - } - - interface LifeCycle extends AsyncPool.LifeCycle { - } - - public void testBasicPool() throws InterruptedException { - - ResourceRegistry registry = new ResourceRegistry(); - - LifeCycle lifeCycle = Mockito.mock(LifeCycle.class); - - Mockito.when(lifeCycle.create()).thenAnswer(invoke -> CompletableFuture.supplyAsync(Element::new)); - Mockito.when(lifeCycle.testOnRelease(Mockito.any(Element.class))) - .thenAnswer(invoke -> CompletableFuture.supplyAsync(() -> true)); - Mockito.when(lifeCycle.testAfterIdle(Mockito.any(Element.class))) - .thenAnswer(invoke -> CompletableFuture.supplyAsync(() -> true)); - Mockito.when(lifeCycle.destroy(Mockito.any(Element.class))) - .thenAnswer(invoke -> CompletableFuture.supplyAsync(() -> null)); - - AsyncPool pool = AsyncPool.create(lifeCycle, _executor, 1, 10, 10, 100, 30000, TimeUnit.MILLISECONDS); - - registry.register((ShutdownableResource) pool); - - Mockito.verifyNoMoreInteractions(lifeCycle); - - pool.start(); - Thread.sleep(100); - - registry.shutdown(); - registry.waitForShutdown(); - - Mockito.verify(lifeCycle, Mockito.times(10)).create(); - Mockito.verify(lifeCycle, Mockito.times(10)).destroy(Mockito.any(Element.class)); - Mockito.verify(lifeCycle).shutdown(); - - Mockito.verifyNoMoreInteractions(lifeCycle); - } - - public void testDefaultShutdown() throws Exception { - abstract class AbstractPool implements AsyncPool, Shutdownable { - } - - AsyncPool pool = - Mockito.mock(AbstractPool.class, Mockito.withSettings().defaultAnswer(Mockito.CALLS_REAL_METHODS)); - - CompletableFuture shutdownFuture = pool.shutdownPool(); - - shutdownFuture.get(1, TimeUnit.SECONDS); - - ((Shutdownable) Mockito.verify(pool)).shutdown(); - ((Shutdownable) Mockito.verify(pool)).waitForShutdown(); - - } - - public void testNoOpShutdown() throws Exception { - abstract class AbstractPool implements AsyncPool { - } - - AsyncPool pool = - Mockito.mock(AbstractPool.class, Mockito.withSettings().defaultAnswer(Mockito.CALLS_REAL_METHODS)); - - CompletableFuture shutdownFuture = pool.shutdownPool(); - - shutdownFuture.get(0, TimeUnit.SECONDS); - - } -} diff --git a/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/queuing/TestQOSPolicy.java b/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/queuing/TestQOSPolicy.java deleted file mode 100644 index 31978980a1e..00000000000 --- a/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/queuing/TestQOSPolicy.java +++ /dev/null @@ -1,513 +0,0 @@ -package com.linkedin.alpini.base.queuing; - -import com.linkedin.alpini.consts.QOS; -import java.util.Arrays; -import java.util.EnumMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Semaphore; -import java.util.concurrent.ThreadLocalRandom; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.testng.Assert; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - - -public class TestQOSPolicy { - final Logger _log = LogManager.getLogger(getClass()); - - @Test(groups = { "unit" }) - public void testQueueFactory() { - QOSPolicy.Config conf = new QOSPolicy.Config(); - conf.setQosPolicy(QOSPolicy.HIGHEST_PRIORITY_W_FAIR_ALLOCATION.name()); - SimpleQueue queue = QOSPolicy.getQOSPolicy(conf.build()); - Assert.assertTrue( - queue instanceof QOSBasedQueue, - "HIGHEST_PRIORITY_W_FAIR_ALLOCATION policy must return a QOSBasedQueue"); - - conf.setQosPolicy(QOSPolicy.FCFS.name()); - queue = QOSPolicy.getQOSPolicy(conf.build()); - Assert.assertTrue(queue instanceof QOSFCFSQueue, "FCFS policy must return a QOSFCFSQueue"); - - conf.setQosPolicy(QOSPolicy.HIGHEST_PRIORITY_W_FAIR_ALLOCATION_MULTI_QUEUE.name()); - queue = QOSPolicy.getQOSPolicy(conf.build()); - Assert.assertTrue( - queue instanceof QOSBasedMultiQueue, - "HIGHEST_PRIORITY_W_FAIR_ALLOCATION_MULTI_QUEUE policy must return a QOSBasedMultiQueue"); - } - - @Test(groups = { "unit" }) - public void testStaticConfig() { - // Set correct fair allocation - QOSPolicy.Config conf = new QOSPolicy.Config(); - conf.setQosPolicy(QOSPolicy.HIGHEST_PRIORITY_W_FAIR_ALLOCATION.name()); - conf.setFairAllocationRatio("5:15:80"); - SimpleQueue queue = QOSPolicy.getQOSPolicy(conf.build()); - Assert.assertTrue( - queue instanceof QOSBasedQueue, - "HIGHEST_PRIORITY_W_FAIR_ALLOCATION policy must return a QOSBasedQueue"); - - // Set non-numeric fair allocation. - conf.setFairAllocationRatio("5:15:ADKJ"); - try { - queue = QOSPolicy.getQOSPolicy(conf.build()); - Assert.fail("Cannot reach here. Must throw a NumberFormatException while building config"); - } catch (NumberFormatException ex) { - } - - conf.setFairAllocationRatio("5:80"); - try { - queue = QOSPolicy.getQOSPolicy(conf.build()); - Assert.fail("Cannot reach here. Must throw an IllegalArgumentException while building config"); - } catch (IllegalArgumentException ex) { - } - } - - @DataProvider - public Object[][] getQOSPolicies() { - Object[][] values = { { QOSPolicy.HIGHEST_PRIORITY_W_FAIR_ALLOCATION }, - { QOSPolicy.HIGHEST_PRIORITY_W_FAIR_ALLOCATION_MULTI_QUEUE }, { QOSPolicy.FCFS } }; - return values; - } - - @Test(groups = { "unit" }, dataProvider = "getQOSPolicies") - public void testQosBasedQueueBasic(QOSPolicy policy) { - QOSPolicy.Config conf = new QOSPolicy.Config(); - conf.setQosPolicy(policy.name()); - SimpleQueue queue = QOSPolicy.getQOSPolicy(conf.build()); - - QOSBasedRequestRunnable r1 = new QOSBasedRequestRunnable("queue1", QOS.HIGH, null); - QOSBasedRequestRunnable r2 = new QOSBasedRequestRunnable("queue1", QOS.LOW, null); - QOSBasedRequestRunnable r3 = new QOSBasedRequestRunnable("queue1", QOS.NORMAL, null); - QOSBasedRequestRunnable r4 = new QOSBasedRequestRunnable("queue1", QOS.LOW, null); - QOSBasedRequestRunnable r5 = new QOSBasedRequestRunnable("queue1", QOS.HIGH, null); - queue.add(r1); - queue.add(r2); - queue.add(r3); - queue.add(r4); - queue.add(r5); - - Assert.assertEquals(queue.size(), 5); - - for (int i = 0; i < 5; i++) - queue.poll(); - - Assert.assertNull(queue.poll()); - Assert.assertEquals(queue.size(), 0); - } - - @Test(groups = { "unit" }, dataProvider = "getQOSPolicies") - public void testQosBasedQueueBasic2(QOSPolicy policy) { - QOSPolicy.Config conf = new QOSPolicy.Config(); - conf.setQosPolicy(policy.name()); - SimpleQueue queue = QOSPolicy.getQOSPolicy(conf.build()); - - QOSBasedRequestRunnable r1 = new QOSBasedRequestRunnable("queue1", QOS.HIGH, null); - QOSBasedRequestRunnable r2 = new QOSBasedRequestRunnable("queue2", QOS.LOW, null); - QOSBasedRequestRunnable r3 = new QOSBasedRequestRunnable("queue3", QOS.NORMAL, null); - QOSBasedRequestRunnable r4 = new QOSBasedRequestRunnable("queue1", QOS.LOW, null); - QOSBasedRequestRunnable r5 = new QOSBasedRequestRunnable("queue2", QOS.HIGH, null); - QOSBasedRequestRunnable r6 = new QOSBasedRequestRunnable("queue3", QOS.HIGH, null); - QOSBasedRequestRunnable r7 = new QOSBasedRequestRunnable("queue1", QOS.LOW, null); - QOSBasedRequestRunnable r8 = new QOSBasedRequestRunnable("queue2", QOS.NORMAL, null); - QOSBasedRequestRunnable r9 = new QOSBasedRequestRunnable("queue3", QOS.LOW, null); - queue.add(r1); - queue.add(r2); - queue.add(r3); - queue.add(r4); - queue.add(r5); - queue.add(r6); - queue.add(r7); - queue.add(r8); - queue.add(r9); - - Assert.assertEquals(queue.size(), 9); - - for (int i = 0; i < 9; i++) - queue.poll(); - - Assert.assertNull(queue.poll()); - Assert.assertEquals(queue.size(), 0); - } - - @Test(groups = { "unit" }, dataProvider = "getQOSPolicies") - public void testQosBasedQueuePolling(QOSPolicy policy) { - QOSPolicy.Config conf = new QOSPolicy.Config(); - conf.setQosPolicy(policy.name()); - SimpleQueue queue = QOSPolicy.getQOSPolicy(conf.build()); - - QOSBasedRequestRunnable r1 = new QOSBasedRequestRunnable("queue1", QOS.HIGH, null); - QOSBasedRequestRunnable r2 = new QOSBasedRequestRunnable("queue1", QOS.LOW, null); - QOSBasedRequestRunnable r3 = new QOSBasedRequestRunnable("queue1", QOS.NORMAL, null); - QOSBasedRequestRunnable r4 = new QOSBasedRequestRunnable("queue1", QOS.LOW, null); - QOSBasedRequestRunnable r5 = new QOSBasedRequestRunnable("queue1", QOS.HIGH, null); - QOSBasedRequestRunnable r6 = new QOSBasedRequestRunnable("queue1", QOS.HIGH, null); - QOSBasedRequestRunnable r7 = new QOSBasedRequestRunnable("queue1", QOS.NORMAL, null); - - queue.add(r1); - queue.add(r2); - queue.add(r3); - queue.add(r4); - queue.add(r5); - queue.add(r6); - queue.add(r7); - Assert.assertEquals(queue.size(), 7); - - if (QOSPolicy.FCFS.name().equals(policy.name())) { - Assert.assertSame(queue.poll(), r1); - Assert.assertSame(queue.poll(), r2); - Assert.assertSame(queue.poll(), r3); - Assert.assertSame(queue.poll(), r4); - Assert.assertSame(queue.poll(), r5); - Assert.assertSame(queue.poll(), r6); - Assert.assertSame(queue.poll(), r7); - return; - } else { - AbstractQOSBasedQueue q = (AbstractQOSBasedQueue) queue; - // Test the above configuration for all Sort orders - // Sort Order 1: {HIGH, NORMAL, LOW} - List sortOrder = Arrays.asList(QOS.HIGH, QOS.NORMAL, QOS.LOW); - Assert.assertSame(q.getElement(sortOrder), r1); - Assert.assertSame(q.getElement(sortOrder), r5); - - // Sort Order 2: {NORMAL, HIGH, LOW} - sortOrder = Arrays.asList(QOS.NORMAL, QOS.HIGH, QOS.LOW); - Assert.assertSame(q.getElement(sortOrder), r3); - - // Sort Order 3: {LOW, HIGH, NORMAL} - sortOrder = Arrays.asList(QOS.LOW, QOS.HIGH, QOS.NORMAL); - Assert.assertSame(q.getElement(sortOrder), r2); - Assert.assertSame(q.getElement(sortOrder), r4); - Assert.assertSame(q.getElement(sortOrder), r6); - Assert.assertSame(q.getElement(sortOrder), r7); - } - - // Empty queue - Assert.assertNull(queue.poll()); - Assert.assertEquals(queue.size(), 0); - - } - - @Test(groups = { "unit" }) - public void testQosBasedMultiQueuePolling() { - AbstractQOSBasedQueue queue = new QOSBasedMultiQueue(); - - QOSBasedRequestRunnable r1 = new QOSBasedRequestRunnable("queue1", QOS.HIGH, null); - QOSBasedRequestRunnable r2 = new QOSBasedRequestRunnable("queue1", QOS.LOW, null); - QOSBasedRequestRunnable r3 = new QOSBasedRequestRunnable("queue2", QOS.NORMAL, null); - QOSBasedRequestRunnable r4 = new QOSBasedRequestRunnable("queue2", QOS.LOW, null); - QOSBasedRequestRunnable r5 = new QOSBasedRequestRunnable("queue2", QOS.HIGH, null); - QOSBasedRequestRunnable r6 = new QOSBasedRequestRunnable("queue3", QOS.HIGH, null); - QOSBasedRequestRunnable r7 = new QOSBasedRequestRunnable("queue3", QOS.NORMAL, null); - - queue.add(r1); - queue.add(r2); - queue.add(r3); - queue.add(r4); - queue.add(r5); - queue.add(r6); - queue.add(r7); - Assert.assertEquals(queue.size(), 7); - - // Test the above configuration for all Sort orders - // Sort Order 1: {HIGH, NORMAL, LOW} - List sortOrder = Arrays.asList(QOS.HIGH, QOS.NORMAL, QOS.LOW); - - // queue1 - Assert.assertSame(queue.getElement(sortOrder), r1); - - // queue2 - Assert.assertSame(queue.getElement(sortOrder), r5); - - // Sort Order 2: {NORMAL, HIGH, LOW} - sortOrder = Arrays.asList(QOS.NORMAL, QOS.HIGH, QOS.LOW); - - // queue3 - Assert.assertSame(queue.getElement(sortOrder), r7); - - // Sort Order 3: {LOW, HIGH, NORMAL} - sortOrder = Arrays.asList(QOS.LOW, QOS.HIGH, QOS.NORMAL); - - // queue1 - Assert.assertSame(queue.getElement(sortOrder), r2); - - // queue2 - Assert.assertSame(queue.getElement(sortOrder), r4); - - // queue3 - Assert.assertSame(queue.getElement(sortOrder), r6); - - // queue2 - Assert.assertSame(queue.getElement(sortOrder), r3); - - // Empty queue - Assert.assertNull(queue.poll()); - Assert.assertEquals(queue.size(), 0); - } - - @Test(groups = { "unit", "NoCoverage" }, dataProvider = "getQOSPolicies") - public void testQosBasedQueueStress(QOSPolicy policy) throws InterruptedException { - QOSPolicy.Config conf = new QOSPolicy.Config(); - conf.setQosPolicy(policy.name()); - - final int runSize = 100000; // each enque thread generates this many items. - final CountDownLatch doneLatch = new CountDownLatch(10); // this many enque threads - // runSize = 100000, doneLatch = 10 results in around a 10 second test. - - // The use of sun.misc.Unsafe to enforce load/store barriers shaves nearly 10% off the time - // without having a missed entry. ie, the new code, even though it introduces a semaphore, - // is as fast or faster than the code before this change without unexpected nulls. - - final AtomicBoolean running = new AtomicBoolean(true); - final Semaphore wakeup = new Semaphore(0); - final SimpleQueue queue = QOSPolicy.getQOSPolicy(conf.build()); - final Map dequeCount = new EnumMap<>(QOS.class); - final Map enqueCount = new EnumMap<>(QOS.class); - final ConcurrentHashMap enqueQueueCount = new ConcurrentHashMap(); - final ConcurrentHashMap dequeQueueCount = new ConcurrentHashMap(); - - final CountDownLatch startLatch = new CountDownLatch(1); - final CountDownLatch readyLatch = new CountDownLatch((int) doneLatch.getCount()); - - final AtomicInteger missCount = new AtomicInteger(); - - dequeCount.put(QOS.HIGH, new AtomicInteger()); - dequeCount.put(QOS.NORMAL, new AtomicInteger()); - dequeCount.put(QOS.LOW, new AtomicInteger()); - - enqueCount.put(QOS.HIGH, new AtomicInteger()); - enqueCount.put(QOS.NORMAL, new AtomicInteger()); - enqueCount.put(QOS.LOW, new AtomicInteger()); - - Runnable deque = new Runnable() { - @Override - public void run() { - int miss = 0; - try { - while (running.get()) { - if (!wakeup.tryAcquire(10, TimeUnit.MILLISECONDS)) { - _log.debug("Sleep"); - Thread.sleep(10); - continue; - } - QOSBasedRequestRunnable item = queue.poll(); - - if (item == null) { - missCount.incrementAndGet(); - - _log.info("Didn't catch after wakeup, {} {}", miss++, Thread.currentThread()); - - wakeup.release(); - continue; - } - - miss = 0; - - dequeCount.get(item._qos).incrementAndGet(); - - AtomicInteger q = dequeQueueCount.get(item._queueName); - if (q == null) { - AtomicInteger nq = new AtomicInteger(); - q = dequeQueueCount.putIfAbsent(item._queueName, nq); - if (q == null) { - q = nq; - } - } - q.incrementAndGet(); - _log.debug("Dequeued {} entry for {}", item._qos, item._queueName); - } - - } catch (Exception ex) { - ex.printStackTrace(); - } finally { - _log.debug("Deque thread finished: {}", Thread.currentThread()); - } - } - }; - - Runnable enque = new Runnable() { - private final String syllables = "..lexegezacebisousesarmaindirea.eratenberalavetiedorquanteisrion"; - - private String makeQueueName(int[] seed) { - StringBuilder name = new StringBuilder(); - for (;;) { - boolean longName = 0 != (seed[0] & 0x40); - - for (int n = 0; n < 4; n++) { - int d = ((seed[2] >>> 8) & 0x1f) << 1; - int t = (seed[0] + seed[1] + seed[2]) & 0xffff; - seed[0] = seed[1]; - seed[1] = seed[2]; - seed[2] = t; - if (longName || n < 3) { - name.append(syllables.subSequence(d, d + 2)); - for (int i = name.length() - 1; i >= Math.max(0, name.length() - 2); i--) { - if (name.charAt(i) == '.') { - name.deleteCharAt(i); - } - } - } - } - if (ThreadLocalRandom.current().nextInt(3) == 1) { - name.insert(1, Character.toUpperCase(name.charAt(0))); - return name.substring(1); - } - name.setLength(0); - } - } - - @Override - public void run() { - int[] seed = { 0x5a4a, 0x0248, 0xb753 }; - String[] queueNames = new String[50]; - for (int i = 0; i < queueNames.length; i++) { - queueNames[i] = makeQueueName(seed); - enqueQueueCount.put(queueNames[i], new AtomicInteger()); - } - - QOS[] qosList = { QOS.HIGH, QOS.NORMAL, QOS.NORMAL, QOS.NORMAL, QOS.NORMAL, QOS.NORMAL, QOS.NORMAL, QOS.NORMAL, - QOS.LOW, QOS.LOW }; - - try { - readyLatch.countDown(); - startLatch.await(); - ThreadLocalRandom rnd = ThreadLocalRandom.current(); - - for (int i = runSize; i > 0; i--) { - int name = rnd.nextInt(queueNames.length); - if (name == 42) - continue; - String queueName = queueNames[name]; - QOS qos = qosList[rnd.nextInt(qosList.length)]; - - enqueQueueCount.get(queueName).incrementAndGet(); - enqueCount.get(qos).incrementAndGet(); - - if (queue.add(new QOSBasedRequestRunnable(queueName, qos, null))) { - _log.debug("Added {} entry for {}", qos, queueName); - wakeup.release(); - } else { - _log.warn("Failed to enque {} entry for {}", qos, queueName); - } - - if (rnd.nextInt(10) == 0) { - Thread.yield(); - } else if (rnd.nextInt(100) == 0) { - Thread.sleep(10); - } - - } - } catch (Exception ex) { - ex.printStackTrace(); - } finally { - _log.debug("Enque thread finished: {}", Thread.currentThread()); - doneLatch.countDown(); - } - } - }; - - Thread dequeThread[] = { new Thread(deque), new Thread(deque), new Thread(deque), new Thread(deque) }; - - for (Thread aDequeThread: dequeThread) { - aDequeThread.start(); - } - - Thread enqueThread[] = new Thread[(int) doneLatch.getCount()]; - for (int i = 0; i < enqueThread.length; i++) { - enqueThread[i] = new Thread(enque); - enqueThread[i].start(); - } - - _log.info("Waiting for enqueue threads to be ready"); - readyLatch.await(); - Thread.sleep(100); - _log.info("Starting test..."); - startLatch.countDown(); - - doneLatch.await(); - _log.info("Enqueue threads are done."); - - while (queue.size() > 0) { - Thread.yield(); - } - _log.info("Dequeue threads are done."); - - // wait a second so that if there are some lost queue entries, we have - // gathered a lot of missing posted events, which will fail the assert - // at the end of this test. - Thread.sleep(1000); - running.set(false); - - for (Thread aEnqueThread: enqueThread) { - aEnqueThread.join(); - } - - for (Thread aDequeThread: dequeThread) { - aDequeThread.join(); - } - - _log.info("Checking results."); - - for (Map.Entry entry: enqueCount.entrySet()) { - Assert - .assertEquals(entry.getValue().get(), dequeCount.get(entry.getKey()).get(), "Mismatch for " + entry.getKey()); - } - - for (Map.Entry entry: enqueQueueCount.entrySet()) { - int hashCode = entry.getKey().hashCode() & 0xff; - if (hashCode == 0x04 || hashCode == 0xbc || hashCode == 0x48) { - // Print a few values - _log.info("Testing for {} expect {}", entry.getKey(), entry.getValue()); - } - - if (entry.getValue().get() == 0) { - Assert.assertNull(dequeQueueCount.get(entry.getKey()), "Expected null for " + entry.getKey()); - } else { - Assert.assertEquals( - dequeQueueCount.get(entry.getKey()).get(), - entry.getValue().get(), - "Mismatch for " + entry.getKey()); - } - } - - Assert.assertEquals( - missCount.get(), - 0, - "Non-zero miss counts means something was dropped by queue: " + missCount.get()); - } - - @Test(groups = { "unit" }) - public void testQosBasedQueueSortOrder() { - // Case 1: Only HIGH is set - Map qosAllocation = new EnumMap<>(QOSBasedQueue.getDefaultQOSAllocation()); - qosAllocation.put(QOS.LOW, 0); - qosAllocation.put(QOS.NORMAL, 0); - QOSBasedQueue q = new QOSBasedQueue<>(qosAllocation); - List sortOrder = q.getQueuePollOrder(); - Assert.assertEquals(sortOrder, Arrays.asList(QOS.HIGH, QOS.NORMAL, QOS.LOW)); - - // Case 1: Only NORMAL is set - qosAllocation = new EnumMap<>(QOSBasedQueue.getDefaultQOSAllocation()); - qosAllocation.put(QOS.LOW, 0); - qosAllocation.put(QOS.HIGH, 0); - q = new QOSBasedQueue<>(qosAllocation); - sortOrder = q.getQueuePollOrder(); - Assert.assertEquals(sortOrder, Arrays.asList(QOS.NORMAL, QOS.HIGH, QOS.LOW)); - - // Case 1: Only LOW is set - qosAllocation = new EnumMap<>(QOSBasedQueue.getDefaultQOSAllocation()); - qosAllocation.put(QOS.NORMAL, 0); - qosAllocation.put(QOS.HIGH, 0); - q = new QOSBasedQueue<>(qosAllocation); - sortOrder = q.getQueuePollOrder(); - Assert.assertEquals(sortOrder, Arrays.asList(QOS.LOW, QOS.HIGH, QOS.NORMAL)); - - } - -} diff --git a/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/registry/TestResourceRegistry.java b/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/registry/TestResourceRegistry.java index e2ce27fe6f4..bfac41ead2b 100644 --- a/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/registry/TestResourceRegistry.java +++ b/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/registry/TestResourceRegistry.java @@ -1,8 +1,6 @@ package com.linkedin.alpini.base.registry; -import com.linkedin.alpini.base.misc.ExceptionUtil; import com.linkedin.alpini.base.misc.Time; -import java.sql.SQLException; import java.util.EmptyStackException; import java.util.LinkedList; import java.util.Queue; @@ -50,23 +48,6 @@ public static interface BadFactory extends ResourceRegistry.Factory, Comparable< public static class BadClass implements ResourceRegistry.Factory { } - public static interface FactoryStaticOtherException extends ResourceRegistry.Factory { - MockResource fooFactory(); - - static final ResourceRegistry.Factory BAD_FACTORY = - ResourceRegistry.registerFactory(FactoryStaticOtherException.class, new FactoryStaticOtherException() { - { - ExceptionUtil.throwException(new SQLException("Some checked exception")); - } - - @Override - public MockResource fooFactory() { - Assert.fail("Never gets here"); - return null; - } - }); - } - public static interface FactoryStaticError extends ResourceRegistry.Factory { MockResource fooFactory(); @@ -259,13 +240,6 @@ public void testFactoryStaticRuntimeException() { Assert.fail("Should not get here: " + factory); } - @Test(groups = "unit", expectedExceptions = ExceptionInInitializerError.class) - public void testFactoryStaticOtherException() { - ResourceRegistry reg = new ResourceRegistry(); - FactoryStaticOtherException factory = reg.factory(FactoryStaticOtherException.class); - Assert.fail("Should not get here: " + factory); - } - @Test(groups = "unit", expectedExceptions = NullPointerException.class) public void testFactoryNull() { ResourceRegistry reg = new ResourceRegistry(); diff --git a/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/statistics/TestQuantileEstimation.java b/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/statistics/TestQuantileEstimation.java deleted file mode 100644 index 8db594312a6..00000000000 --- a/internal/alpini/common/alpini-common-base/src/test/java/com/linkedin/alpini/base/statistics/TestQuantileEstimation.java +++ /dev/null @@ -1,467 +0,0 @@ -package com.linkedin.alpini.base.statistics; - -import com.linkedin.alpini.base.concurrency.ConcurrentAccumulator; -import com.linkedin.alpini.base.misc.Msg; -import com.linkedin.alpini.base.misc.Time; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.Random; -import java.util.concurrent.ForkJoinPool; -import java.util.concurrent.RecursiveAction; -import java.util.concurrent.ThreadLocalRandom; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; -import java.util.concurrent.atomic.LongAdder; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.testng.Assert; -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - - -/** - * @author Antony T Curtis {@literal } - */ -public class TestQuantileEstimation { - private static final Logger LOG = LogManager.getLogger(TestQuantileEstimation.class); - - final int windowSize = 100000; - final double epsilon = 0.001; - - final Long[] values = new Long[windowSize]; - - static final ConcurrentAccumulator.Mode DEFAULT_MODE = ConcurrentAccumulator.defaultMode; - - @BeforeClass(groups = "unit") - public void setupLog4j() { - // if (!org.apache.log4j.Logger.getRootLogger().getAllAppenders().hasMoreElements()) { - // org.apache.log4j.BasicConfigurator.configure(); - // } - - Arrays.setAll(values, Long::valueOf); - - Random rand = new Random(0xDEADBEEF); - Collections.shuffle(Arrays.asList(values), rand); - } - - @AfterTest(groups = { "unit", "functional" }) - public void resetMode() { - ConcurrentAccumulator.defaultMode = DEFAULT_MODE; - } - - private static final Object[][] ACCUMULATOR_MODES = - { { ConcurrentAccumulator.Mode.COMPLEX }, { ConcurrentAccumulator.Mode.THREADED }, }; - - @DataProvider - public Object[][] accumulatorModes() { - return ACCUMULATOR_MODES; - } - - @Test(groups = "unit", dataProvider = "accumulatorModes") - public void testGenericSinpleQuantileEstimation(ConcurrentAccumulator.Mode mode) { - ConcurrentAccumulator.defaultMode = mode; - - GenericQuantileEstimation estimator = - new GenericQuantileEstimation<>(epsilon, 1000, Comparator.naturalOrder()); - - for (int i = 10; i > 0; i--) { - Long value = ThreadLocalRandom.current().nextLong(0, Integer.MAX_VALUE); - long startNanos = Time.nanoTime(); - estimator.accept(value); - long endNanos = Time.nanoTime(); - LOG.warn( - "accepted {} samples in {} nanoseconds ({} samples per second)", - 1, - (endNanos - startNanos), - TimeUnit.SECONDS.toNanos(1) / (endNanos - startNanos)); - } - } - - @Test(groups = "unit", dataProvider = "accumulatorModes") - public void testGenericQuantileEstimation(ConcurrentAccumulator.Mode mode) { - ConcurrentAccumulator.defaultMode = mode; - - GenericQuantileEstimation estimator = - new GenericQuantileEstimation<>(epsilon, 1000, Comparator.naturalOrder()); - - long startNanos = Time.nanoTime(); - Arrays.asList(values).forEach(estimator); - long endNanos = Time.nanoTime(); - LOG.error( - "accepted {} samples in {} nanoseconds ({} samples per second)", - windowSize, - (endNanos - startNanos), - windowSize * TimeUnit.SECONDS.toNanos(1) / (endNanos - startNanos)); - - double[] quantiles = { 0.5, 0.9, 0.95, 0.99, 1.0 }; - - for (double q: quantiles) { - Long estimate = estimator.query(q); - long actual = (long) ((q) * (windowSize - 1)); - - LOG.error("Estimated {} quantile as {} (actually {})", q, estimate, actual); - } - - for (Long v: Arrays.asList(1000L, 20000L, 75000L, 99995L, 1000000L)) { - LOG.error("computed quantile for {} = {}", v, estimator.computeQuantile(v)); - } - - LOG.error("# of samples: {}", estimator.getNumberOfSamples()); - } - - @Test(groups = "unit", dataProvider = "accumulatorModes") - public void testDoubleQuantileEstimation(ConcurrentAccumulator.Mode mode) { - ConcurrentAccumulator.defaultMode = mode; - - DoubleQuantileEstimation estimator = new DoubleQuantileEstimation(epsilon, 1000); - - long startNanos = Time.nanoTime(); - Arrays.asList(values).forEach(estimator::accept); - long endNanos = Time.nanoTime(); - LOG.error( - "accepted {} samples in {} nanoseconds ({} samples per second)", - windowSize, - (endNanos - startNanos), - windowSize * TimeUnit.SECONDS.toNanos(1) / (endNanos - startNanos)); - - double[] quantiles = { 0.5, 0.9, 0.95, 0.99, 1.0 }; - - for (double q: quantiles) { - double estimate = estimator.query(q); - long actual = (long) ((q) * (windowSize - 1)); - - LOG.error("Estimated {} quantile as {} (actually {})", q, estimate, actual); - } - LOG.error("# of samples: {}", estimator.getNumberOfSamples()); - } - - @Test(groups = "unit", dataProvider = "accumulatorModes") - public void testLongQuantileEstimation(ConcurrentAccumulator.Mode mode) { - ConcurrentAccumulator.defaultMode = mode; - - LongQuantileEstimation estimator = new LongQuantileEstimation(epsilon, 1000); - - long startNanos = Time.nanoTime(); - Arrays.asList(values).forEach(estimator::accept); - long endNanos = Time.nanoTime(); - LOG.error( - "accepted {} samples in {} nanoseconds ({} samples per second)", - windowSize, - (endNanos - startNanos), - windowSize * TimeUnit.SECONDS.toNanos(1) / (endNanos - startNanos)); - - double[] quantiles = { 0.5, 0.9, 0.95, 0.99, 1.0 }; - - for (double q: quantiles) { - long estimate = estimator.query(q); - long actual = (long) ((q) * (windowSize - 1)); - - LOG.error("Estimated {} quantile as {} (actually {})", q, estimate, actual); - } - LOG.error("# of samples: {}", estimator.getNumberOfSamples()); - } - - @Test(groups = "unit", dataProvider = "accumulatorModes") - public void testLongQuantileArrayEstimation(ConcurrentAccumulator.Mode mode) { - ConcurrentAccumulator.defaultMode = mode; - - LongQuantileArrayEstimation estimator = new LongQuantileArrayEstimation(epsilon, 1000); - - long startNanos = Time.nanoTime(); - Arrays.asList(values).forEach(estimator::accept); - long endNanos = Time.nanoTime(); - LOG.error( - "accepted {} samples in {} nanoseconds ({} samples per second)", - windowSize, - (endNanos - startNanos), - windowSize * TimeUnit.SECONDS.toNanos(1) / (endNanos - startNanos)); - - double[] quantiles = { 0.5, 0.9, 0.95, 0.99, 1.0 }; - - for (double q: quantiles) { - long estimate = estimator.query(q); - long actual = (long) ((q) * (windowSize - 1)); - - LOG.error("Estimated {} quantile as {} (actually {})", q, estimate, actual); - } - LOG.error("# of samples: {}", estimator.getNumberOfSamples()); - } - - @Test(groups = "unit", dataProvider = "accumulatorModes") - public void testRealQuantileEstimation(ConcurrentAccumulator.Mode mode) { - ConcurrentAccumulator.defaultMode = mode; - - DoubleQuantileEstimation estimator = new DoubleQuantileEstimation(epsilon, 1000); - - long startNanos = Time.nanoTime(); - Arrays.asList(values).forEach(estimator::accept); - long endNanos = Time.nanoTime(); - LOG.error( - "accepted {} samples in {} nanoseconds ({} samples per second)", - windowSize, - (endNanos - startNanos), - windowSize * TimeUnit.SECONDS.toNanos(1) / (endNanos - startNanos)); - - double[] quantiles = { 0.5, 0.9, 0.95, 0.99, 1.0 }; - - for (double q: quantiles) { - double estimate = estimator.query(q); - long actual = (long) ((q) * (windowSize - 1)); - - LOG.error("Estimated {} quantile as {} (actually {})", q, estimate, actual); - } - LOG.error("# of samples: {}", estimator.getNumberOfSamples()); - } - - @Test(groups = "unit", dataProvider = "accumulatorModes") - public void testStatsQuantileEstimation(ConcurrentAccumulator.Mode mode) { - ConcurrentAccumulator.defaultMode = mode; - - LongStatsAggregator estimator = new LongStatsAggregator(epsilon / 2, 2000); - - long startNanos = Time.nanoTime(); - Arrays.asList(values).forEach(estimator::accept); - long endNanos = Time.nanoTime(); - LOG.error( - "accepted {} samples in {} nanoseconds ({} samples per second)", - windowSize, - (endNanos - startNanos), - windowSize * TimeUnit.SECONDS.toNanos(1) / (endNanos - startNanos)); - - LOG.error("# of samples: {}", estimator.getNumberOfSamples()); - - LongStats stats = estimator.getLongStats(); - - LOG.error("Stats: {}", stats.toString()); - } - - @Test(groups = "unit", dataProvider = "accumulatorModes") - public void testStatsLowQuantileEstimation(ConcurrentAccumulator.Mode mode) { - ConcurrentAccumulator.defaultMode = mode; - - LongStatsAggregatorLowQuantile estimator = new LongStatsAggregatorLowQuantile(epsilon / 2, 2000); - - long startNanos = Time.nanoTime(); - Arrays.asList(values).forEach(estimator::accept); - long endNanos = Time.nanoTime(); - LOG.error( - "accepted {} samples in {} nanoseconds ({} samples per second)", - windowSize, - (endNanos - startNanos), - windowSize * TimeUnit.SECONDS.toNanos(1) / (endNanos - startNanos)); - - LOG.error("# of samples: {}", estimator.getNumberOfSamples()); - - LongStatsLowQuantile stats = estimator.getLongStatsLowQuantile(); - - LOG.error("Stats: {}", stats.toString()); - } - - static class MinMax { - final long min; - final long max; - - MinMax(long min, long max) { - this.min = min; - this.max = max; - } - - MinMax apply(long value) { - return new MinMax(Math.min(min, value), Math.max(max, value)); - } - } - - @Test(groups = "functional", dataProvider = "accumulatorModes") - public void testQuantileEstimationMemoryLeak(ConcurrentAccumulator.Mode mode) throws InterruptedException { - ConcurrentAccumulator.defaultMode = mode; - - final int compactSize = 2000; - - LongAdder count = new LongAdder(); - LongStatsAggregator estimator = new LongStatsAggregator(epsilon / 2, compactSize); - - ForkJoinPool executorService = new ForkJoinPool(); - AtomicReference time = new AtomicReference<>(new MinMax(Long.MAX_VALUE, 0)); - ConcurrentAccumulator welfords = - new ConcurrentAccumulator<>(Welfords.LongWelford.COLLECTOR); - try { - - // We have to use ForkJoinPool/RecursiveAction because using simpler ThreadPool/Runnable - // is unable to max out all the cores due to overhead in the ThreadPoolExecutorService. - - class Task extends RecursiveAction { - private final ThreadLocalRandom rnd = ThreadLocalRandom.current(); - - @Override - protected void compute() { - run(); - executorService.submit(new Task()); - } - - public void run() { - long value = rnd.nextLong(100000000); - long startTime = Time.nanoTime(); - estimator.accept(value); - long delta = Time.nanoTime() - startTime; - count.increment(); - - MinMax prev = time.get(); - if (prev.max < delta || prev.min > delta) { - time.updateAndGet(old -> old.apply(delta)); - } - - welfords.accept(delta); - } - } - - for (int i = 96; i >= 0; i--) { - executorService.submit(new Task()); - } - - long lastCount = 0; - int foo = 0; - for (long endTime = Time.currentTimeMillis() + TimeUnit.MINUTES.toMillis(5); endTime > Time - .currentTimeMillis(); Time.sleep(1000)) { - LOG.error("gather"); - long thisCount = count.longValue(); - MinMax minMax = time.getAndSet(new MinMax(Long.MAX_VALUE, 0)); - long max = minMax.max; - long min = minMax.min; - Welfords.LongWelford.Result std = welfords.getThenReset(); - LOG.error( - "# of samples: {}, calls: {}, delta: {}, max: {}ns, min: {}ns, (count: {}, avg: {}ns, std: {}ns)", - estimator.getNumberOfSamples(), - thisCount, - thisCount - lastCount, - max, - min, - Msg.makeNullable(std, Welfords.Result::getCount), - Msg.makeNullable(std, s -> (long) s.getAverage()), - Msg.makeNullable(std, s -> (long) s.getStandardDeviation())); - - LongStats stats = estimator.getLongStats(); - LOG.error("Stats: {}", stats); - if ((++foo) % 60 == 0) { - estimator.reset(); - } - lastCount = thisCount; - } - - } finally { - executorService.shutdownNow(); - } - - int numberOfSamples = estimator.getNumberOfSamples(); - LOG.error("# of samples: {}, calls: {}", numberOfSamples, count); - - Assert.assertTrue(numberOfSamples < (count.longValue() / 100)); - - LongStats stats = estimator.getLongStats(); - - LOG.error("Stats: {}", stats); - } - - @Test(groups = "functional", dataProvider = "accumulatorModes") - public void testQuantileArrayEstimationMemoryLeak(ConcurrentAccumulator.Mode mode) throws InterruptedException { - ConcurrentAccumulator.defaultMode = mode; - - final int compactSize = 2000; - - LongAdder count = new LongAdder(); - LongStatsArrayAggregator estimator = new LongStatsArrayAggregator(epsilon / 2, compactSize); - LongStatsAggregatorLowQuantile estimatorLQ = new LongStatsAggregatorLowQuantile(epsilon / 2, compactSize); - - ForkJoinPool executorService = new ForkJoinPool(); - AtomicReference time = new AtomicReference<>(new MinMax(Long.MAX_VALUE, 0)); - ConcurrentAccumulator welfords = - new ConcurrentAccumulator<>(Welfords.DoubleWelford.COLLECTOR); - try { - - // We have to use ForkJoinPool/RecursiveAction because using simpler ThreadPool/Runnable - // is unable to max out all the cores due to overhead in the ThreadPoolExecutorService. - - class Task extends RecursiveAction { - private final ThreadLocalRandom rnd = ThreadLocalRandom.current(); - - @Override - protected void compute() { - run(); - executorService.submit(new Task()); - } - - public void run() { - long value = rnd.nextLong(100000000); - long startTime = Time.nanoTime(); - estimator.accept(value); - estimatorLQ.accept(value); - long delta = Time.nanoTime() - startTime; - count.increment(); - - MinMax prev = time.get(); - if (prev.max < delta || prev.min > delta) { - time.updateAndGet(old -> old.apply(delta)); - } - - welfords.accept((double) delta); - } - } - - for (int i = 96; i >= 0; i--) { - executorService.submit(new Task()); - } - - long lastCount = 0; - int foo = 0; - for (long endTime = Time.currentTimeMillis() + TimeUnit.MINUTES.toMillis(5); endTime > Time - .currentTimeMillis(); Time.sleep(1000)) { - LOG.error("gather"); - long thisCount = count.longValue(); - MinMax minMax = time.getAndSet(new MinMax(Long.MAX_VALUE, 0)); - long max = minMax.max; - long min = minMax.min; - Welfords.DoubleWelford.Result std = welfords.getThenReset(); - LOG.error( - "# of samples: estimator: {}, estimatorLQ: {}, calls: {}, delta: {}, max: {}ns, min: {}ns, (count: {}, avg: {}ns, std: {}ns)", - estimator.getNumberOfSamples(), - estimatorLQ.getNumberOfSamples(), - thisCount, - thisCount - lastCount, - max, - min, - Msg.makeNullable(std, Welfords.Result::getCount), - Msg.makeNullable(std, s -> (long) s.getAverage()), - Msg.makeNullable(std, s -> (long) s.getStandardDeviation())); - - LongStats stats = estimator.getLongStats(); - LongStatsLowQuantile statsLQ = estimatorLQ.getLongStatsLowQuantile(); - LOG.error("Stats: {}", stats); - LOG.error("StatsLQ: {}", statsLQ); - if ((++foo) % 60 == 0) { - LOG.error("resetting estimators..."); - estimator.reset(); - estimatorLQ.reset(); - } - lastCount = thisCount; - } - - } finally { - executorService.shutdownNow(); - } - - int numberOfSamples = estimator.getNumberOfSamples(); - int numberOfSamples2 = estimatorLQ.getNumberOfSamples(); - LOG.error("# of samples: estimator: {}, estimatorLQ: {}, calls: {}", numberOfSamples, numberOfSamples2, count); - - Assert.assertTrue(numberOfSamples < (count.longValue() / 100)); - Assert.assertTrue(numberOfSamples2 < (count.longValue() / 100)); - - LongStats stats = estimator.getLongStats(); - LongStatsLowQuantile statsLQ = estimatorLQ.getLongStatsLowQuantile(); - - LOG.error("Stats: {}", stats); - LOG.error("StatsLQ: {}", statsLQ); - } -} diff --git a/internal/alpini/common/alpini-common-cli/build.gradle b/internal/alpini/common/alpini-common-cli/build.gradle deleted file mode 100644 index 33d892bedb2..00000000000 --- a/internal/alpini/common/alpini-common-cli/build.gradle +++ /dev/null @@ -1,11 +0,0 @@ -dependencies { - testImplementation libraries.testng - implementation project(':internal:alpini:common:alpini-common-const') - implementation libraries.commonsCli - implementation libraries.log4j2api - compileOnly libraries.jsr305 - //testImplementation spec.external.'mockito-all' - //testImplementation libraries.testng -} - - diff --git a/internal/alpini/common/alpini-common-cli/src/main/java/com/linkedin/alpini/cli/CLIArgument.java b/internal/alpini/common/alpini-common-cli/src/main/java/com/linkedin/alpini/cli/CLIArgument.java deleted file mode 100644 index 34b1c94c23b..00000000000 --- a/internal/alpini/common/alpini-common-cli/src/main/java/com/linkedin/alpini/cli/CLIArgument.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * $Id$ - */ -package com.linkedin.alpini.cli; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - - -/** - * Annotation for a command line option with an argument, like "--file ". - * - * @see CLIArgumentParser - * @author Jemiah Westerman - * @version $Revision$ - */ -@Target(ElementType.FIELD) -@Retention(RetentionPolicy.RUNTIME) -public @interface CLIArgument { - /** A short sentence description of the option. Shown in help / usage screens. */ - String description(); - - /** Argument name. For example, if you want --file , then argumentName is the "filename" part. - * If not provided, one will be auto-generated from the field name. */ - String argumentName() default CLIArgumentParser.NO_DEFAULT_STRING; - - /** Long name for the option. If not provided, one will be auto-generated from the field name. */ - String longOpt() default CLIArgumentParser.NO_DEFAULT_STRING; - - /** Short name for the option. If not provided, the option will not have a short name. */ - char shortOpt() default CLIArgumentParser.NO_DEFAULT_CHAR; - - /** Default value for the option. If no default is provided, the argument is required. */ - String defaultValue() default CLIArgumentParser.NO_DEFAULT_STRING; - - /** Set to true if the default action is inaction. */ - boolean optional() default false; -} diff --git a/internal/alpini/common/alpini-common-cli/src/main/java/com/linkedin/alpini/cli/CLIArgumentParser.java b/internal/alpini/common/alpini-common-cli/src/main/java/com/linkedin/alpini/cli/CLIArgumentParser.java deleted file mode 100644 index cbe76a3701b..00000000000 --- a/internal/alpini/common/alpini-common-cli/src/main/java/com/linkedin/alpini/cli/CLIArgumentParser.java +++ /dev/null @@ -1,531 +0,0 @@ -/* - * $Id$ - */ -package com.linkedin.alpini.cli; - -import java.io.File; -import java.io.PrintWriter; -import java.io.Writer; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.net.URI; -import java.net.URISyntaxException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Date; -import java.util.List; -import java.util.Locale; -import javax.annotation.Nonnull; -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLineParser; -import org.apache.commons.cli.GnuParser; -import org.apache.commons.cli.HelpFormatter; -import org.apache.commons.cli.MissingOptionException; -import org.apache.commons.cli.Option; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** - * Utility class to handle typical command line argument parsing and log initialization. In addition to - * parsing the command line, this class can display help information. All command lines will support the - * "--help" argument, which will be handled automatically by CLIArgumentParser. - * - * To use this class, a command line application should define a public class with a public field for each - * command line option. The options should be annotated as either a CLIArgument or a CLIFlag. CLIArgument is - * used for options that expect some sort of argument, like a path or server hostname. CLIFlag is for boolean - * flags that have no argument. - * - * Both annotations require an argument description which will be used when displaying command line usage. They - * also allow a long option name (like "--server-address") and a short option name (like "-s"). If no long option is - * given, it will be automatically generated from the member variable name. If no short option is given, the option - * will have no short option. - * - * CLIArguments also require an argument name, and allow a default value. The argument name is displayed with - * usage information. In the usage information "--infile ", "filename" is the argument name. Default values - * are used for optional fields. If a field does not have a default value provided, then it is required on the command - * line. Otherwise, the default will be used. - * - * CLIFlags have no default value or argument name. They will be set to "true" if present on the command line; - * false otherwise. - * - * Below is a sample class that shows how to use CLIArgumentParser. It declares an inner Args class with - * one required argument "path" and three optional arguments. -
-
-  public class ExportTopology {
-    public static class Args {
-      @CLIArgument(description="Path to topology files", argumentName="products")
-      public String path;
-      @CLIArgument(description="Comma delimited list of fabrics to export", argumentName="products", defaultValue="all fabrics")
-      public String fabrics;
-      @CLIArgument(description="Comma delimited list of products to export", argumentName="products", defaultValue="all products")
-      public String products;
-      @CLIArgument(description="File to export to, in csv format", argumentName="filename", defaultValue="stdout")
-      public String outfile;
-    }
-
-    public static void main(String[] args) {
-      Args cliArgs = new CLIArgumentParser("ExportTopology", Args.class).startup(args);
-      if (cliArgs == null) {
-        // bad command line, exit.
-        return;
-      }
-      // ...
-    }
-  }
- 
- * - * The usage information generated by this class is: -
-   usage: ExportTopology [--fabrics ] [--help] [--outfile ] --path  [--products ]
-    --fabrics     Comma delimited list of fabrics to export(optional; default=all fabrics)
-    --help                  Show usage information
-    --outfile     File to export to, in csv format(optional; default=stdout)
-    --path        Path to topology files (required)
-    --products    Comma delimited list of products to export(optional; default=all products)
- 
- * - * @author Jemiah Westerman - * @version $Revision$ - */ -public class CLIArgumentParser implements CLIParser { - private static final String[] ACCEPTED_DATE_FORMATS = - { "MM/dd/yyyy hh:mm:ss:SSS", "MM/dd/yyyy", "MM/dd/yyyy hh:mm:ss:SSS zzz" }; - - static final String NO_DEFAULT_STRING = "\0\0\0\0[NO DEFAULT]\0\0\0\0"; - static final char NO_DEFAULT_CHAR = 0x00; - - private static final Logger LOG = LogManager.getLogger(CLIArgumentParser.class); - private final String _applicationName; - - private final Class _class; - private final Options _options; - - private PrintWriter _err = new PrintWriter(System.err, true); - private PrintWriter _out = new PrintWriter(System.out, true); - - private static boolean isNotDefault(String argument) { - return !NO_DEFAULT_STRING.equals(argument); - } - - /** - * Create a new parser for the given application and argument class. The argument class should have one or more - * public fields, annotated with the CLIArgument or CLIOption annotation. - * - * @param applicationName name of the application, used in usage messages - * @param klass class used for arguments - */ - @SuppressWarnings("static-access") - public CLIArgumentParser(String applicationName, Class klass) { - _applicationName = applicationName; - _class = klass; - _options = new Options(); - boolean unknown = false; - StringBuilder desc = new StringBuilder(); - - for (Field field: _class.getDeclaredFields()) { - boolean handled = false; - if (field.isAnnotationPresent(CLIArgument.class)) { - CLIArgument arg = field.getAnnotation(CLIArgument.class); - - boolean noDefault = !isNotDefault(arg.defaultValue()); - desc.setLength(0); - desc.append(arg.description()); - desc.append(arg.optional() ? " (optional" : noDefault ? " (required" : " (optional; default="); - if (!arg.optional() && !noDefault) { - desc.append(arg.defaultValue()); - } - if (field.getType().isEnum()) { - desc.append("; options=").append(Arrays.asList(field.getType().getEnumConstants())); - } - desc.append(")"); - - String shortOpt = getShortOpt(arg.shortOpt()); - String longOpt = getLongOpt(arg.longOpt(), shortOpt, field); - String argName = isNotDefault(arg.argumentName()) ? arg.argumentName() : field.getType().getSimpleName(); - - Option.Builder builder = Option.builder(shortOpt) - .longOpt(longOpt) - .hasArg() - .argName(argName) - .desc(desc.toString()) - .required(!arg.optional() && noDefault); - - Option option = builder.build(); - - _options.addOption(option); - handled = true; - } - if (field.isAnnotationPresent(CLIFlag.class)) { - if (handled) { - throw new IllegalArgumentException("Multiple CLI annotations are not supported."); - } - - // CLIOptions are flags, like "--exit-after-error". They must be boolean type. - if (field.getType() != Boolean.class && field.getType() != boolean.class) { - throw new IllegalArgumentException("CLIOption must be applied to boolean fields only."); - } - - CLIFlag arg = field.getAnnotation(CLIFlag.class); - String shortOpt = getShortOpt(arg.shortOpt()); - String longOpt = getLongOpt(arg.longOpt(), shortOpt, field); - Option.Builder builder = Option.builder(shortOpt).longOpt(longOpt).desc(arg.description()); - - Option option = builder.build(); - - _options.addOption(option); - handled = true; - } - if (field.isAnnotationPresent(CLIUnknown.class)) { - if (handled) { - throw new IllegalArgumentException("Multiple CLI annotations are not supported."); - } - if (unknown) { - throw new IllegalArgumentException("CLIUnknown may only be applied to one field only."); - } - if (!field.getType().isAssignableFrom(String[].class)) { - throw new IllegalArgumentException("CLIUnknown must be applied to String[] fields only."); - } - - unknown = true; - handled = true; - } - LOG.debug("field: {} handled={}", field, handled); - } - - // Add the built in "help" argument - _options.addOption(Option.builder().longOpt("help").desc("Show usage information").build()); - } - - /** - * Parse the given command line. If the command line is legal, the options will - * be printed to the log and returned. If the command line is invalid, it will display command line usage - * and exit. - *

- * In addition, the startup method understands the "--help" argument. If - * "--help" is given, startup will display usage information and return null. - * - * @param args command line arguments - * @return parsed arguments; null if the command line was invalid - */ - public T startup(String[] args) { - T ret = parse(args); - if (ret != null) { - logConfiguredValues(ret); - } - return ret; - } - - /** - * Log the configured values. An application will typically not call this method, since this information is - * logged automatically by the startup() method. - * - * @param args arguments to log - * @see #startup(String[]) - */ - public void logConfiguredValues(T args) { - try { - for (Field field: _class.getDeclaredFields()) { - if (field.isAnnotationPresent(CLIArgument.class)) { - CLIArgument arg = field.getAnnotation(CLIArgument.class); - String longOpt = isNotDefault(arg.longOpt()) ? arg.longOpt() : getLongArgName(field.getName()); - LOG.debug("{}={}", longOpt, field.get(args)); - } else if (field.isAnnotationPresent(CLIFlag.class)) { - CLIFlag arg = field.getAnnotation(CLIFlag.class); - String longOpt = isNotDefault(arg.longOpt()) ? arg.longOpt() : getLongArgName(field.getName()); - LOG.debug("{}={}", longOpt, field.get(args)); - } - } - } catch (IllegalArgumentException | IllegalAccessException ex) { - throw new RuntimeException(ex); - } - } - - /** - * Parse the given command line and return the arguments, or null if the arguments are invalid. An application - * will typically not call this method, but will instead use startup(), which parses the command line and - * logs the configured values. - * - * @param args arguments to parse - * @return parsed arguments; null if the command line is invalid - * @see #startup(String[]) - */ - @Override - public T parse(String[] args) { - try { - T ret = _class.newInstance(); - - // In spite of GnuParser being deprecated, the suggested replacement DefaultParser cannot handle all cases. - CommandLineParser parser = new GnuParser() { - @Override - protected void checkRequiredOptions() throws MissingOptionException { - // When "help" is found on the command line, we do not want to report failure because of missing options. - if (!cmd.hasOption("help")) { - super.checkRequiredOptions(); - } - } - }; - - CommandLine line = parser.parse(_options, args); - - // Handle the built in "help" argument. - if (line.hasOption("help")) { - showUsage(true); - return null; - } - - for (Field field: _class.getDeclaredFields()) { - if (field.isAnnotationPresent(CLIArgument.class)) { - CLIArgument arg = field.getAnnotation(CLIArgument.class); - String shortOpt = getShortOpt(arg.shortOpt()); - String longOpt = getLongOpt(arg.longOpt(), shortOpt, field); - boolean hasDefault = isNotDefault(arg.defaultValue()); - - String argValue = longOpt != null - ? line.getOptionValue(longOpt, hasDefault ? arg.defaultValue() : null) - : line.getOptionValue(arg.shortOpt(), hasDefault ? arg.defaultValue() : null); - - if (argValue == null) { - continue; - } - - if (field.getType() == Integer.class || field.getType() == int.class) { - try { - field.set(ret, Integer.valueOf(argValue)); - } catch (Exception ex) { - showUsage("Bad value for " + field.getName() + ": \"" + argValue + "\". Value must be an integer (int)"); - return null; - } - } else if (field.getType() == Float.class || field.getType() == float.class) { - try { - field.set(ret, Float.valueOf(argValue)); - } catch (Exception ex) { - showUsage( - "Bad value for " + field.getName() + ": \"" + argValue - + "\". Value must be a decimal number (float)"); - return null; - } - } else if (field.getType() == Long.class || field.getType() == long.class) { - try { - field.set(ret, Long.valueOf(argValue)); - } catch (Exception ex) { - showUsage( - "Bad value for " + field.getName() + ": \"" + argValue + "\". Value must be a long integer (long)"); - return null; - } - } else if (field.getType() == Double.class || field.getType() == double.class) { - try { - field.set(ret, Double.valueOf(argValue)); - } catch (Exception ex) { - showUsage( - "Bad value for " + field.getName() + ": \"" + argValue - + "\". Value must be a decimal number (double)"); - return null; - } - } else if (field.getType() == Boolean.class || field.getType() == boolean.class) { - try { - field.set(ret, Boolean.valueOf(argValue)); - } catch (Exception ex) { - showUsage("Bad value for " + field.getName() + ": \"" + argValue + "\". Legal values are [true, false]"); - return null; - } - } else if (field.getType() == Date.class) { - boolean success = false; - for (String fmt: ACCEPTED_DATE_FORMATS) { - try { - Date date = new SimpleDateFormat(fmt, Locale.ENGLISH).parse(argValue); - field.set(ret, date); - success = true; - break; - } catch (java.text.ParseException ex) { - // Attempt next format - } - } - - if (!success) { - try { - Date d = new Date(Long.parseLong(argValue)); - field.set(ret, d); - } catch (NumberFormatException e) { - showUsage( - "Bad value for " + field.getName() + ": \"" + argValue - + "\". Value must be a time in ms or a date string of following forms: " - + Arrays.asList(ACCEPTED_DATE_FORMATS)); - return null; - } - } - } else if (field.getType() == File.class) { - field.set(ret, new File(argValue)); - } else if (field.getType() == URI.class) { - try { - field.set(ret, new URI(argValue)); - } catch (URISyntaxException e) { - showUsage("Bad value for " + field.getName() + ": \"" + argValue + "\". Value must be a valid URI"); - return null; - } - } else if (field.getType() == String.class) { - field.set(ret, argValue); - } else if (field.getType().isEnum()) { - try { - // Handle enums - Class k = field.getType(); - Method m = k.getMethod("valueOf", String.class); - Object value = m.invoke(null, argValue); - field.set(ret, value); - } catch (Throwable ex) { - showUsage( - "Bad value for " + field.getName() + ": \"" + argValue + "\". Legal values are " - + Arrays.asList(field.getType().getEnumConstants()) + "."); - return null; - } - } else { - try { - // Handle ENUMs that were implemented with "public static final ". Specifically, log4j log levels... - Field f = field.getType().getField(argValue); - Object value = f.get(null); - field.set(ret, value); - } catch (Exception ex) { - // Build a list of all "public static final " constants in the class for the usage string. - List legalConstantNames = new ArrayList<>(); - for (Field f: field.getType().getFields()) { - if (f.getType() == field.getType() && Modifier.isPublic(f.getModifiers()) - && Modifier.isStatic(f.getModifiers()) && Modifier.isFinal(f.getModifiers())) { - legalConstantNames.add(f.getName()); - } - } - showUsage( - "Bad value for " + field.getName() + ": \"" + argValue + "\". Legal values are " + legalConstantNames - + "."); - return null; - } - } - } else if (field.isAnnotationPresent(CLIFlag.class)) { - CLIFlag arg = field.getAnnotation(CLIFlag.class); - String shortOpt = getShortOpt(arg.shortOpt()); - String longOpt = getLongOpt(arg.longOpt(), shortOpt, field); - - if (longOpt != null ? line.hasOption(longOpt) : line.hasOption(arg.shortOpt())) { - field.set(ret, Boolean.TRUE); - } else { - field.set(ret, Boolean.FALSE); - } - } else if (field.isAnnotationPresent(CLIUnknown.class)) { - field.set(ret, line.getArgs()); - } - } - - return ret; - } catch (IllegalAccessException | InstantiationException ex) { - throw new RuntimeException(ex); - } catch (ParseException ex) { - // Bad command line. - showUsage("Bad command line: " + ex.getMessage()); - return null; - } - } - - public CLIArgumentParser redirect(@Nonnull PrintWriter out, @Nonnull PrintWriter err) { - _out = out; - _err = err; - return this; - } - - /** - * Display command line usage information. This is invoked automatically by startup() if the --help - * argument is present. - */ - @Override - public void showUsage(boolean verbose) { - String header = ""; - String footer = ""; - if (_class.isAnnotationPresent(CLIHeader.class)) { - CLIHeader annotation = _class.getAnnotation(CLIHeader.class); - header = annotation.value(); - } - if (_class.isAnnotationPresent(CLIFooter.class)) { - CLIFooter annotation = _class.getAnnotation(CLIFooter.class); - footer = annotation.value(); - } - - int columns = HelpFormatter.DEFAULT_WIDTH; - try { - String txt = System.getenv("COLUMNS"); - columns = Math.max(Integer.parseInt(txt, 10), columns); - } catch (Throwable ignored) { - } - - HelpFormatter formatter = new HelpFormatter(); - - if (verbose) { - formatter.printHelp( - _out, - columns, - _applicationName, - header, - _options, - formatter.getLeftPadding(), - formatter.getDescPadding(), - footer, - true); - } else { - formatter.printUsage(new PrintWriter(new Writer() { - @Override - public void write(@Nonnull char[] cbuf, int off, int len) { - _out.print(Arrays.copyOfRange(cbuf, off, len)); - } - - @Override - public void flush() { - _out.flush(); - } - - @Override - public void close() { - // does nothing; - } - }, true), columns, _applicationName, _options); - } - } - - /** - * Display an error message plus command line usage information. This is invoked automatically by startup() - * if the command line is invalid. - */ - public void showUsage(String error) { - _err.println(error); - showUsage(false); - } - - private static String getShortOpt(char shortOpt) { - return shortOpt != NO_DEFAULT_CHAR ? String.valueOf(shortOpt) : null; - } - - private static String getLongOpt(String longOpt, String shortOpt, Field field) { - return isNotDefault(longOpt) ? longOpt : shortOpt == null ? getLongArgName(field.getName()) : null; - } - - private static String getLongArgName(String fieldName) { - StringBuilder sb = new StringBuilder(); - int pos = 0; - // Strip leading _ - if (fieldName.startsWith("_")) { - pos++; - } - sb.append(Character.toLowerCase(fieldName.charAt(pos++))); - for (; pos < fieldName.length(); pos++) { - char ch = fieldName.charAt(pos); - // put a dash wherever case changes. This seems to make the most sense for arguments like - // URIPrefix -> uri-prefix or targetQPS -> target-qps - if (Character.isUpperCase(ch) && !Character.isUpperCase(fieldName.charAt(pos - 1))) { - sb.append('-'); - } - sb.append(Character.toLowerCase(ch)); - } - return sb.toString(); - } -} diff --git a/internal/alpini/common/alpini-common-cli/src/main/java/com/linkedin/alpini/cli/CLIFlag.java b/internal/alpini/common/alpini-common-cli/src/main/java/com/linkedin/alpini/cli/CLIFlag.java deleted file mode 100644 index ccf83d2f454..00000000000 --- a/internal/alpini/common/alpini-common-cli/src/main/java/com/linkedin/alpini/cli/CLIFlag.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * $Id$ - */ -package com.linkedin.alpini.cli; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - - -/** - * Annotation for a boolean command line option without an argument, like "--exit-on-error". - * - * @see CLIArgumentParser - * @author Jemiah Westerman - * @version $Revision$ - */ -@Target(ElementType.FIELD) -@Retention(RetentionPolicy.RUNTIME) -public @interface CLIFlag { - /** A short sentence description of the option. Shown in help / usage screens. */ - String description(); - - /** Long name for the option. If not provided, one will be auto-generated from the field name. */ - String longOpt() default CLIArgumentParser.NO_DEFAULT_STRING; - - /** Short name for the option. If not provided, the option will not have a short name. */ - char shortOpt() default CLIArgumentParser.NO_DEFAULT_CHAR; -} diff --git a/internal/alpini/common/alpini-common-cli/src/main/java/com/linkedin/alpini/cli/CLIFooter.java b/internal/alpini/common/alpini-common-cli/src/main/java/com/linkedin/alpini/cli/CLIFooter.java deleted file mode 100644 index 2d9ff6a2e65..00000000000 --- a/internal/alpini/common/alpini-common-cli/src/main/java/com/linkedin/alpini/cli/CLIFooter.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.linkedin.alpini.cli; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - - -/** - * Annotation for text to display as the footer of the "--help" output. - * - * @see CLIArgumentParser - * @author Antony T Curtis - * @version $Revision$ - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -public @interface CLIFooter { - /** Footer text. Shown in help / usage screens. */ - String value(); - -} diff --git a/internal/alpini/common/alpini-common-cli/src/main/java/com/linkedin/alpini/cli/CLIHeader.java b/internal/alpini/common/alpini-common-cli/src/main/java/com/linkedin/alpini/cli/CLIHeader.java deleted file mode 100644 index 8656b133548..00000000000 --- a/internal/alpini/common/alpini-common-cli/src/main/java/com/linkedin/alpini/cli/CLIHeader.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.linkedin.alpini.cli; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - - -/** - * Annotation for text to display as the header of the "--help" output. - * - * @see CLIArgumentParser - * @author Antony T Curtis - * @version $Revision$ - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -public @interface CLIHeader { - /** Header text. Shown in help / usage screens. */ - String value(); - -} diff --git a/internal/alpini/common/alpini-common-cli/src/main/java/com/linkedin/alpini/cli/CLIParser.java b/internal/alpini/common/alpini-common-cli/src/main/java/com/linkedin/alpini/cli/CLIParser.java deleted file mode 100644 index 577817f5f37..00000000000 --- a/internal/alpini/common/alpini-common-cli/src/main/java/com/linkedin/alpini/cli/CLIParser.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.linkedin.alpini.cli; - -public interface CLIParser { - void logConfiguredValues(T args); - - T parse(String[] args); - - void showUsage(boolean verbose); - - void showUsage(String error); -} diff --git a/internal/alpini/common/alpini-common-cli/src/main/java/com/linkedin/alpini/cli/CLIUnknown.java b/internal/alpini/common/alpini-common-cli/src/main/java/com/linkedin/alpini/cli/CLIUnknown.java deleted file mode 100644 index 6cc10b3d090..00000000000 --- a/internal/alpini/common/alpini-common-cli/src/main/java/com/linkedin/alpini/cli/CLIUnknown.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.linkedin.alpini.cli; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - - -/** - * Annotation for a String[] property which will receive all the command line elements which were not processed - * by the command line parser. - * - * @see CLIArgumentParser - * @author Antony T Curtis - * @version $Revision$ - */ -@Target(ElementType.FIELD) -@Retention(RetentionPolicy.RUNTIME) -public @interface CLIUnknown { -} diff --git a/internal/alpini/common/alpini-common-cli/src/main/java/com/linkedin/alpini/cli/package-info.java b/internal/alpini/common/alpini-common-cli/src/main/java/com/linkedin/alpini/cli/package-info.java deleted file mode 100644 index 3f74b3c32d5..00000000000 --- a/internal/alpini/common/alpini-common-cli/src/main/java/com/linkedin/alpini/cli/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * @author Antony T Curtis {@literal } - */ -package com.linkedin.alpini.cli; diff --git a/internal/alpini/common/alpini-common-cli/src/test/java/com/linkedin/alpini/ExampleCLI.java b/internal/alpini/common/alpini-common-cli/src/test/java/com/linkedin/alpini/ExampleCLI.java deleted file mode 100644 index a90a1f9b842..00000000000 --- a/internal/alpini/common/alpini-common-cli/src/test/java/com/linkedin/alpini/ExampleCLI.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.linkedin.alpini; - -import com.linkedin.alpini.cli.CLIArgument; -import com.linkedin.alpini.cli.CLIArgumentParser; -import com.linkedin.alpini.cli.CLIFlag; -import com.linkedin.alpini.cli.CLIUnknown; -import java.io.PrintWriter; -import java.io.StringWriter; - - -public class ExampleCLI { - private static final String APPLICATION_NAME = "example"; - - public static class Args { - @CLIArgument(description = "Path to topology files", argumentName = "products") - public String path; - @CLIArgument(description = "Comma delimited list of fabrics to export", argumentName = "products", defaultValue = "all fabrics") - public String fabrics; - @CLIArgument(description = "Comma delimited list of products to export", argumentName = "products", defaultValue = "all products") - public String products; - @CLIArgument(description = "File to export to, in csv format", argumentName = "filename", defaultValue = "stdout") - public String outfile; - @CLIArgument(description = "Mode", shortOpt = 'd', optional = true) - public Mode d; - @CLIArgument(description = "integer", shortOpt = 'i', optional = true) - public int i; - @CLIArgument(description = "float", shortOpt = 'r', optional = true) - public Float r; - @CLIArgument(description = "long", shortOpt = 'l', optional = true) - public long l; - @CLIArgument(description = "double", shortOpt = 't', optional = true) - public double t; - @CLIFlag(shortOpt = 'X', description = "the X flag") - public boolean x; - @CLIUnknown - public String[] remain; - } - - public enum Mode { - MODE1, MODE2 - } - - static Args _args; - static StringWriter _out; - static StringWriter _err; - - public static void main(String[] args) { - _out = new StringWriter(); - _err = new StringWriter(); - _args = new CLIArgumentParser<>(APPLICATION_NAME, Args.class).redirect(new PrintWriter(_out), new PrintWriter(_err)) - .startup(args); - } -} diff --git a/internal/alpini/common/alpini-common-cli/src/test/java/com/linkedin/alpini/TestCLI.java b/internal/alpini/common/alpini-common-cli/src/test/java/com/linkedin/alpini/TestCLI.java deleted file mode 100644 index 8939487f12d..00000000000 --- a/internal/alpini/common/alpini-common-cli/src/test/java/com/linkedin/alpini/TestCLI.java +++ /dev/null @@ -1,154 +0,0 @@ -package com.linkedin.alpini; - -import org.testng.Assert; -import org.testng.annotations.Test; - - -public class TestCLI { - @Test(groups = "unit") - public void testNoParse() { - ExampleCLI._args = null; - ExampleCLI.main(new String[0]); - Assert.assertNull(ExampleCLI._args); - Assert.assertEquals(ExampleCLI._err.toString(), "Bad command line: Missing required option: path\n"); - } - - @Test(groups = "unit") - public void testBasic() { - ExampleCLI._args = null; - ExampleCLI.main(new String[] { "--path", "foo", "extra" }); - Assert.assertNotNull(ExampleCLI._args); - Assert.assertEquals(ExampleCLI._args.path, "foo"); - Assert.assertEquals(ExampleCLI._err.toString(), ""); - Assert.assertEquals(ExampleCLI._out.toString(), ""); - Assert.assertEquals(ExampleCLI._args.remain, new String[] { "extra" }); - } - - @Test(groups = "unit") - public void testBasicBoolean() { - ExampleCLI._args = null; - ExampleCLI.main(new String[] { "--path", "foo", "-X" }); - Assert.assertNotNull(ExampleCLI._args); - Assert.assertTrue(ExampleCLI._args.x); - Assert.assertEquals(ExampleCLI._err.toString(), ""); - Assert.assertEquals(ExampleCLI._out.toString(), ""); - } - - @Test(groups = "unit") - public void testBasicEnum1() { - ExampleCLI._args = null; - ExampleCLI.main(new String[] { "--path", "foo", "-d", "MODE1" }); - Assert.assertNotNull(ExampleCLI._args); - Assert.assertSame(ExampleCLI._args.d, ExampleCLI.Mode.MODE1); - Assert.assertEquals(ExampleCLI._err.toString(), ""); - Assert.assertEquals(ExampleCLI._out.toString(), ""); - } - - @Test(groups = "unit") - public void testBasicEnumFail() { - ExampleCLI._args = null; - ExampleCLI.main(new String[] { "--path", "foo", "-d", "MODEX" }); - Assert.assertNull(ExampleCLI._args); - Assert.assertEquals(ExampleCLI._err.toString(), "Bad value for d: \"MODEX\". Legal values are [MODE1, MODE2].\n"); - } - - @Test(groups = "unit") - public void testBasicInteger() { - ExampleCLI._args = null; - ExampleCLI.main(new String[] { "--path", "foo", "-i", "100" }); - Assert.assertNotNull(ExampleCLI._args); - Assert.assertEquals(ExampleCLI._args.i, 100); - Assert.assertEquals(ExampleCLI._err.toString(), ""); - Assert.assertEquals(ExampleCLI._out.toString(), ""); - } - - @Test(groups = "unit") - public void testFailInteger() { - ExampleCLI._args = null; - ExampleCLI.main(new String[] { "--path", "foo", "-i", "foo" }); - Assert.assertNull(ExampleCLI._args); - Assert.assertEquals(ExampleCLI._err.toString(), "Bad value for i: \"foo\". Value must be an integer (int)\n"); - } - - @Test(groups = "unit") - public void testBasicLong() { - ExampleCLI._args = null; - ExampleCLI.main(new String[] { "--path", "foo", "-l", "100" }); - Assert.assertNotNull(ExampleCLI._args); - Assert.assertEquals(ExampleCLI._args.l, 100); - Assert.assertEquals(ExampleCLI._err.toString(), ""); - Assert.assertEquals(ExampleCLI._out.toString(), ""); - } - - @Test(groups = "unit") - public void testFailLong() { - ExampleCLI._args = null; - ExampleCLI.main(new String[] { "--path", "foo", "-l", "foo" }); - Assert.assertNull(ExampleCLI._args); - Assert.assertEquals(ExampleCLI._err.toString(), "Bad value for l: \"foo\". Value must be a long integer (long)\n"); - } - - @Test(groups = "unit") - public void testBasicFloat() { - ExampleCLI._args = null; - ExampleCLI.main(new String[] { "--path", "foo", "-r", "100.001" }); - Assert.assertNotNull(ExampleCLI._args); - Assert.assertEquals(ExampleCLI._args.r, 100.001f); - Assert.assertEquals(ExampleCLI._err.toString(), ""); - Assert.assertEquals(ExampleCLI._out.toString(), ""); - } - - @Test(groups = "unit") - public void testFailFloat() { - ExampleCLI._args = null; - ExampleCLI.main(new String[] { "--path", "foo", "-r", "foo" }); - Assert.assertNull(ExampleCLI._args); - Assert - .assertEquals(ExampleCLI._err.toString(), "Bad value for r: \"foo\". Value must be a decimal number (float)\n"); - } - - @Test(groups = "unit") - public void testBasicDouble() { - ExampleCLI._args = null; - ExampleCLI.main(new String[] { "--path", "foo", "-t", "100.001" }); - Assert.assertNotNull(ExampleCLI._args); - Assert.assertEquals(ExampleCLI._args.t, 100.001); - Assert.assertEquals(ExampleCLI._err.toString(), ""); - Assert.assertEquals(ExampleCLI._out.toString(), ""); - } - - @Test(groups = "unit") - public void testFailDouble() { - ExampleCLI._args = null; - ExampleCLI.main(new String[] { "--path", "foo", "-t", "foo" }); - Assert.assertNull(ExampleCLI._args); - Assert.assertEquals( - ExampleCLI._err.toString(), - "Bad value for t: \"foo\". Value must be a decimal number (double)\n"); - } - - @Test(groups = "unit") - public void testHelp() { - ExampleCLI._args = null; - ExampleCLI.main(new String[] { "--path", "foo", "--help" }); - Assert.assertNull(ExampleCLI._args); - Assert.assertEquals(ExampleCLI._err.toString(), ""); - Assert.assertEquals( - ExampleCLI._out.toString(), - "usage: example [-d ] [--fabrics ] [--help] [-i ] [-l\n" - + " ] [--outfile ] --path [--products\n" - + " ] [-r ] [-t ] [-X]\n" - + " -d Mode (optional; options=[MODE1, MODE2])\n" - + " --fabrics Comma delimited list of fabrics to export\n" - + " (optional; default=all fabrics)\n" - + " --help Show usage information\n" - + " -i integer (optional)\n" + " -l long (optional)\n" - + " --outfile File to export to, in csv format (optional;\n" - + " default=stdout)\n" - + " --path Path to topology files (required)\n" - + " --products Comma delimited list of products to export\n" - + " (optional; default=all products)\n" - + " -r float (optional)\n" + " -t double (optional)\n" - + " -X the X flag\n"); - } -} diff --git a/internal/alpini/common/alpini-common-const/build.gradle b/internal/alpini/common/alpini-common-const/build.gradle deleted file mode 100644 index 24a0d6671cc..00000000000 --- a/internal/alpini/common/alpini-common-const/build.gradle +++ /dev/null @@ -1,8 +0,0 @@ -dependencies { - testImplementation libraries.testng - implementation libraries.log4j2api - //testImplementation spec.external.'mockito-all' - //testImplementation libraries.testng -} - - diff --git a/internal/alpini/common/alpini-common-const/src/main/java/com/linkedin/alpini/consts/Level.java b/internal/alpini/common/alpini-common-const/src/main/java/com/linkedin/alpini/consts/Level.java deleted file mode 100644 index f76a0f2e58d..00000000000 --- a/internal/alpini/common/alpini-common-const/src/main/java/com/linkedin/alpini/consts/Level.java +++ /dev/null @@ -1,162 +0,0 @@ -package com.linkedin.alpini.consts; - -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.function.Predicate; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.spi.LoggerContext; - - -/** - * This is the subset of org.apache.log4j.Level and org.apache.log4j.Priority with version 1.2.17 - * Copied here because slf4j does not have a Level concept - */ -public class Level { - public final static int OFF_INT = Integer.MAX_VALUE; - public final static int ERROR_INT = 40000; - public final static int WARN_INT = 30000; - public final static int INFO_INT = 20000; - public final static int DEBUG_INT = 10000; - public static final int TRACE_INT = 5000; - public final static int ALL_INT = Integer.MIN_VALUE; - - private final int level; - private final String levelStr; - private final Predicate isEnabled; - private final Log log; - - /** - The {@code OFF} has the highest possible rank and is - intended to turn off logging. */ - final static public Level OFF = new Level(OFF_INT, "OFF", logger -> false, (logger, message, arguments) -> {}); - - /** - The {@code ERROR} level designates error events that - might still allow the application to continue running. */ - final static public Level ERROR = new Level(ERROR_INT, "ERROR", Logger::isErrorEnabled, Logger::error); - - /** - The {@code WARN} level designates potentially harmful situations. - */ - final static public Level WARN = new Level(WARN_INT, "WARN", Logger::isWarnEnabled, Logger::warn); - - /** - The {@code INFO} level designates informational messages - that highlight the progress of the application at coarse-grained - level. */ - final static public Level INFO = new Level(INFO_INT, "INFO", Logger::isInfoEnabled, Logger::info); - - /** - The {@code DEBUG} Level designates fine-grained - informational events that are most useful to debug an - application. */ - final static public Level DEBUG = new Level(DEBUG_INT, "DEBUG", Logger::isDebugEnabled, Logger::debug); - - /** - * The {@code TRACE} Level designates finer-grained - * informational events than the {@code DEBUG} level. - */ - public static final Level TRACE = new Level(TRACE_INT, "TRACE", Logger::isTraceEnabled, Logger::trace); - - /** - The ALL has the lowest possible rank and is intended to - turn on all logging. */ - final static public Level ALL = new Level(ALL_INT, "ALL", logger -> true, Level::logAtLevel); - - /** - Instantiate a Level object. - */ - protected Level(int level, String levelStr, Predicate isEnabled, Log log) { - this.level = level; - this.levelStr = Objects.requireNonNull(levelStr); - this.isEnabled = Objects.requireNonNull(isEnabled); - this.log = Objects.requireNonNull(log); - } - - @Override - public boolean equals(Object o) { - return o instanceof Level && (this.level == ((Level) o).level); - } - - @Override - public int hashCode() { - return levelStr.hashCode(); - } - - public boolean isGreaterOrEqual(Level r) { - return level >= r.level; - } - - @Override - public String toString() { - return levelStr; - } - - private static void logAtLevel(Logger logger, String txt, Object... args) { - logWithLevel(logger, getLevel(logger), txt, args); - } - - /** - * Log at the specified level. If the "logger" is null, nothing is logged. - * If the "level" is null, nothing is logged. If the "txt" is null, - * behaviour depends on the SLF4J implementation. - */ - public static void logWithLevel(Logger logger, Level level, String txt, Object... args) { - if (logger != null && level != null) { - level.log.log(logger, Objects.requireNonNull(txt), args); - } - } - - private interface Log { - void log(Logger logger, String message, Object... arguments); - } - - public static boolean isEnabledFor(Logger logger, Level level) { - return logger != null && level != null && level.isEnabled.test(logger); - } - - private static final List LEVEL_LIST = - Collections.unmodifiableList(Arrays.asList(TRACE, DEBUG, INFO, WARN, ERROR)); - - public static Level getLevel(Logger logger) { - return LEVEL_LIST.stream().filter(level -> level.isEnabled.test(logger)).findFirst().orElse(OFF); - } - - /** - * This uses reflection to call the innards of log4j2 without requiring the module to pull in more than the - * log4j2Api library. Since this method should only be used during test setup, there is no need for it to - * be performant. - */ - public static void setLevel(Logger logger, Level level) { - LoggerContext ctx = LogManager.getContext(false); - org.apache.logging.log4j.Level log4jLevel = org.apache.logging.log4j.Level.toLevel(level.toString()); - try { - Method getConfigurationMethod = ctx.getClass().getMethod("getConfiguration"); - Object config = getConfigurationMethod.invoke(ctx); - Method getLoggerConfigMethod = config.getClass().getMethod("getLoggerConfig", String.class); - Object loggerConfig = getLoggerConfigMethod.invoke(config, logger.getName()); - Object specificConfig = loggerConfig; - if (!logger.getName().equals(loggerConfig.getClass().getMethod("getName").invoke(loggerConfig))) { - specificConfig = getLoggerConfigMethod.getReturnType() - .getConstructor(String.class, org.apache.logging.log4j.Level.class, Boolean.TYPE) - .newInstance(logger.getName(), log4jLevel, true); - specificConfig.getClass() - .getMethod("setParent", getLoggerConfigMethod.getReturnType()) - .invoke(specificConfig, loggerConfig); - config.getClass() - .getMethod("addLogger", String.class, getLoggerConfigMethod.getReturnType()) - .invoke(config, logger.getName(), specificConfig); - } - specificConfig.getClass() - .getMethod("setLevel", org.apache.logging.log4j.Level.class) - .invoke(specificConfig, log4jLevel); - ctx.getClass().getMethod("updateLoggers", getConfigurationMethod.getReturnType()).invoke(ctx, config); - } catch (Throwable ex) { - LogManager.getLogger(Level.class).debug("Cannot set level of {} to {}", logger.getName(), log4jLevel, ex); - } - } -} diff --git a/internal/alpini/common/alpini-common-const/src/main/java/com/linkedin/alpini/consts/QOS.java b/internal/alpini/common/alpini-common-const/src/main/java/com/linkedin/alpini/consts/QOS.java deleted file mode 100644 index 6ec9ff1d9c0..00000000000 --- a/internal/alpini/common/alpini-common-const/src/main/java/com/linkedin/alpini/consts/QOS.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.linkedin.alpini.consts; - -/** - * Sets the quality of service (QOS) for the request. A request with a high QOS will be serviced preferentially - * over a low QOS. Assigning backend and batch jobs a low QOS will help keep high priority frontend requests responsive, - * even when these batch jobs are running. - * - * @author Jemiah Westerman <jwesterman@linkedin.com> - */ -public enum QOS { - LOW, NORMAL, HIGH -} diff --git a/internal/alpini/common/alpini-common-const/src/main/java/com/linkedin/alpini/consts/config/ConfigBuilder.java b/internal/alpini/common/alpini-common-const/src/main/java/com/linkedin/alpini/consts/config/ConfigBuilder.java deleted file mode 100644 index 676b26d65a0..00000000000 --- a/internal/alpini/common/alpini-common-const/src/main/java/com/linkedin/alpini/consts/config/ConfigBuilder.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.linkedin.alpini.consts.config; - -/** - * Used for creation and verification of configs - * Forked from com.linkedin.databus.core.util @ r293057 - * @author cbotev - * - * @param the type of configs to be created - */ -public interface ConfigBuilder { - C build() throws InvalidConfigException; -} diff --git a/internal/alpini/common/alpini-common-const/src/main/java/com/linkedin/alpini/consts/config/InvalidConfigException.java b/internal/alpini/common/alpini-common-const/src/main/java/com/linkedin/alpini/consts/config/InvalidConfigException.java deleted file mode 100644 index 3fea5a3ba0d..00000000000 --- a/internal/alpini/common/alpini-common-const/src/main/java/com/linkedin/alpini/consts/config/InvalidConfigException.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.linkedin.alpini.consts.config; - -/** - * Forked from com.linkedin.databus.core.util @ r293057 - * @author sdas - * - */ -public class InvalidConfigException extends Exception { - private static final long serialVersionUID = 1L; - - public InvalidConfigException(String msg) { - super(msg); - } - - public InvalidConfigException(Throwable cause) { - super(cause); - } - - public InvalidConfigException(String msg, Throwable cause) { - super(msg, cause); - } - -} diff --git a/internal/alpini/common/alpini-common-const/src/main/java/com/linkedin/alpini/consts/package-info.java b/internal/alpini/common/alpini-common-const/src/main/java/com/linkedin/alpini/consts/package-info.java deleted file mode 100644 index 618b4a0bd47..00000000000 --- a/internal/alpini/common/alpini-common-const/src/main/java/com/linkedin/alpini/consts/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Package exclusively for constants and enums. - * - * @author Antony T Curtis {@literal } - */ -package com.linkedin.alpini.consts; diff --git a/internal/alpini/common/alpini-common-const/src/test/java/com/linkedin/alpini/consts/TestLevel.java b/internal/alpini/common/alpini-common-const/src/test/java/com/linkedin/alpini/consts/TestLevel.java deleted file mode 100644 index c748d114ba5..00000000000 --- a/internal/alpini/common/alpini-common-const/src/test/java/com/linkedin/alpini/consts/TestLevel.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.linkedin.alpini.consts; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.testng.Assert; -import org.testng.annotations.Test; - - -/** - * Created by acurtis on 12/6/17. - */ -public class TestLevel { - private final Logger _log = LogManager.getLogger(getClass()); - - @Test(groups = "unit") - public void testSetLevel() { - - Level.setLevel(_log, Level.DEBUG); - - Assert.assertTrue(Level.isEnabledFor(_log, Level.DEBUG)); - Assert.assertEquals(Level.getLevel(_log), Level.DEBUG); - - Assert.assertEquals(LogManager.getLogger(getClass()).getLevel(), org.apache.logging.log4j.Level.DEBUG); - - Level.setLevel(_log, Level.INFO); - - Assert.assertTrue(Level.isEnabledFor(_log, Level.INFO)); - Assert.assertFalse(Level.isEnabledFor(_log, Level.DEBUG)); - Assert.assertEquals(Level.getLevel(_log), Level.INFO); - - Assert.assertEquals(LogManager.getLogger(getClass()).getLevel(), org.apache.logging.log4j.Level.INFO); - - Level.setLevel(_log, Level.WARN); - - Assert.assertTrue(Level.isEnabledFor(_log, Level.WARN)); - Assert.assertFalse(Level.isEnabledFor(_log, Level.INFO)); - Assert.assertEquals(Level.getLevel(_log), Level.WARN); - - Assert.assertEquals(LogManager.getLogger(getClass()).getLevel(), org.apache.logging.log4j.Level.WARN); - - Level.setLevel(_log, Level.ERROR); - - Assert.assertTrue(Level.isEnabledFor(_log, Level.ERROR)); - Assert.assertFalse(Level.isEnabledFor(_log, Level.INFO)); - Assert.assertEquals(Level.getLevel(_log), Level.ERROR); - - Assert.assertEquals(LogManager.getLogger(getClass()).getLevel(), org.apache.logging.log4j.Level.ERROR); - - Level.setLevel(_log, Level.OFF); - Assert.assertFalse(Level.isEnabledFor(_log, Level.ERROR)); - } -} diff --git a/internal/alpini/common/alpini-common-const/src/test/java/com/linkedin/alpini/consts/TestQOS.java b/internal/alpini/common/alpini-common-const/src/test/java/com/linkedin/alpini/consts/TestQOS.java deleted file mode 100644 index 73d26c21b2a..00000000000 --- a/internal/alpini/common/alpini-common-const/src/test/java/com/linkedin/alpini/consts/TestQOS.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.linkedin.alpini.consts; - -import java.util.Arrays; -import org.testng.Assert; -import org.testng.annotations.Test; - - -/** - * Created by acurtis on 12/6/17. - */ -public class TestQOS { - @Test(groups = "unit") - public void testQOS() { - Assert.assertEquals(Arrays.asList(QOS.values()), Arrays.asList(QOS.LOW, QOS.NORMAL, QOS.HIGH)); - - Assert.assertSame(QOS.valueOf("LOW"), QOS.LOW); - } -} diff --git a/internal/alpini/common/alpini-common-io/build.gradle b/internal/alpini/common/alpini-common-io/build.gradle index 1e1e43b69e0..00ea5e96f13 100644 --- a/internal/alpini/common/alpini-common-io/build.gradle +++ b/internal/alpini/common/alpini-common-io/build.gradle @@ -1,7 +1,6 @@ dependencies { testImplementation libraries.testng implementation project(':internal:alpini:common:alpini-common-base') - implementation project(':internal:alpini:common:alpini-common-const') implementation libraries.commonsIo implementation libraries.jsr305 implementation libraries.log4j2api diff --git a/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/CompressOutputStream.java b/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/CompressOutputStream.java deleted file mode 100644 index ec13018dfe4..00000000000 --- a/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/CompressOutputStream.java +++ /dev/null @@ -1,188 +0,0 @@ -package com.linkedin.alpini.io; - -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Objects; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.zip.GZIPOutputStream; -import javax.annotation.Nonnull; -import javax.annotation.WillCloseWhenClosed; - - -/** - * BackupOutputStream encapsulates an GZip compressor and provides methods - * to allow other threads to wait upon the completion of the file. - * However, when an exception occurs, the OutputStream is closed and the - * GZip compressor is not flushed, which should cut off the trailing footer - * leaving an invalid gzipped file. - * - * @author Antony T Curtis - */ -public final class CompressOutputStream extends FilterOutputStream { - private final CountDownLatch _sync = new CountDownLatch(1); - private final OutputStream _destination; - private volatile IOException _exception; - private boolean _closed; - - /** - * Creates a compressed backup output stream built on top of the specified - * underlying output stream. - * - * @param compressionLevel the compression level requested. - * @param executor Thread pool for the parallel compressor. - * @param numThreads requested compression parallelism. - * @param out the underlying output stream to be assigned to - * the field this.out for later use, or - * null if this instance is to be - * created without an underlying stream. - */ - public CompressOutputStream( - final int compressionLevel, - ExecutorService executor, - int numThreads, - @Nonnull @WillCloseWhenClosed OutputStream out) throws IOException { - super( - numThreads > 1 - ? new PigzOutputStream(compressionLevel, executor, numThreads, out) - : new GZIPOutputStream(out, PigzOutputStream.DEFAULT_BLOCK_SIZE) { - { - def.setLevel(compressionLevel); - } - }); - _destination = out; - } - - private void test() throws IOException { - if (_exception != null) { - throw _exception; - } - } - - /** - * Writes the specified byte to this output stream. - * - * @param b the byte. - * @throws java.io.IOException if an I/O error occurs. - */ - @Override - public void write(int b) throws IOException { - test(); - try { - out.write(b); - } catch (IOException e) { - throw setException(e); - } - } - - /** - * Writes b.length bytes to this output stream. - * - * @param b the data to be written. - * @throws java.io.IOException if an I/O error occurs. - */ - @Override - public void write(@Nonnull byte[] b) throws IOException { - test(); - try { - out.write(b); - } catch (IOException e) { - throw setException(e); - } - } - - /** - * Writes len bytes from the specified - * byte array starting at offset off to - * this output stream. - * - * @param b the data. - * @param off the start offset in the data. - * @param len the number of bytes to write. - * @throws java.io.IOException if an I/O error occurs. - */ - @Override - public void write(@Nonnull byte[] b, int off, int len) throws IOException { - test(); - try { - out.write(b, off, len); - } catch (IOException e) { - throw setException(e); - } - } - - /** - * Flushes this output stream and forces any buffered output bytes - * to be written out to the stream. - *

- * The flush method of FilterOutputStream - * calls the flush method of its underlying output stream. - * - * @throws java.io.IOException if an I/O error occurs. - * @see java.io.FilterOutputStream#out - */ - @Override - public void flush() throws IOException { - test(); - try { - out.flush(); - } catch (IOException e) { - throw setException(e); - } - } - - public void await() throws IOException, InterruptedException { - try { - _sync.await(); - } finally { - test(); - } - } - - public boolean await(long timeout, @Nonnull TimeUnit unit) throws IOException, InterruptedException { - try { - return _sync.await(timeout, unit); - } finally { - test(); - } - } - - /** - * Closes this output stream and releases any system resources - * associated with the stream. - * - * @throws java.io.IOException if an I/O error occurs. - */ - @Override - public void close() throws IOException { - try { - if (!_closed) { - if (_exception == null) { - super.close(); - } else { - // When there is an exception, we don't bother closing the compressor - // and only close the destination output stream. - // This should ensure that the archive is "broken" - _destination.close(); - } - } - _closed = true; - } catch (IOException e) { - throw setException(e); - } finally { - test(); - _sync.countDown(); - } - } - - public synchronized IOException setException(@Nonnull IOException cause) { - cause = Objects.requireNonNull(cause); - if (_exception == null) { - _exception = cause; - _sync.countDown(); - } - return _exception; - } -} diff --git a/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/ExternalCommand.java b/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/ExternalCommand.java deleted file mode 100644 index 0185e9c22f3..00000000000 --- a/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/ExternalCommand.java +++ /dev/null @@ -1,525 +0,0 @@ -package com.linkedin.alpini.io; - -/* -* Copyright 2010-2010 LinkedIn, Inc -* -* Licensed 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. -*/ - -import com.linkedin.alpini.base.concurrency.AsyncFuture; -import com.linkedin.alpini.base.concurrency.AsyncPromise; -import com.linkedin.alpini.base.misc.Preconditions; -import com.linkedin.alpini.consts.Level; -import java.io.BufferedInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import javax.annotation.CheckReturnValue; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** -* This class encapsulates a java Process to handle properly -* output and error and preventing potential deadlocks. The idea is that the -* command is executed and you can get the error or output. Simple to use. -* Should not be used for big outputs because they are buffered internally. -* -* @author ypujante@linkedin.com -*/ -public class ExternalCommand { - public static final String JDK_HOME_DIR = System.getProperty("java.home"); - public static final String MODULE = ExternalCommand.class.getName(); - public static final Logger LOG = LogManager.getLogger(ExternalCommand.class); - - private final ProcessBuilder _processBuilder; - - private Process _process; - private InputReader _out; - private InputReader _err; - - private boolean _isTimedOut; - - private static class InputReader extends Thread { - private static final int BUFFER_SIZE = 2048; - - private final Future _in; - private final ByteArrayOutputStream _out; - private final Level _logLevel; - private final boolean _logVerbose; - private boolean _running = false; - private final String _sType; - - InputReader(Future in, Level logLevel, String type) { - _in = in; - _out = new ByteArrayOutputStream(); - _logLevel = logLevel; - _logVerbose = LOG.isDebugEnabled() || logLevel == Level.ERROR; - _sType = type; - } - - @Override - public void run() { - _running = true; - - byte[] buf = new byte[BUFFER_SIZE]; - String prefix = ""; - int n; - InputStream in = null; - - try { - in = new BufferedInputStream(_in.get()); - while ((n = in.available()) >= 0) { - int nbytes = 0; - if (n > 0) { - nbytes = in.read(buf); - _out.write(buf, 0, nbytes); - } else if (n == 0) { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - break; - } - } else { - break; - } - - // Turning on debug logging drastically hurts perf: - if (nbytes > 0 && _logVerbose) { - try { - String outputAsUtf8 = new String(buf, 0, nbytes, StandardCharsets.UTF_8); - if (!prefix.isEmpty()) { - outputAsUtf8 = prefix + outputAsUtf8; - prefix = ""; - } - int pos; - while ((pos = outputAsUtf8.indexOf('\n')) != -1) { - log(outputAsUtf8.substring(0, pos)); - outputAsUtf8 = outputAsUtf8.substring(pos + 1); - } - if (!outputAsUtf8.isEmpty()) { - prefix += outputAsUtf8; - } - } catch (UnsupportedOperationException e) { - // Should not happen - LOG.warn("!!!FAILED TO READ OUTPUT!!!"); - } - } - } - } catch (IOException e) { - LOG.error("error while reading external command", e); - } catch (InterruptedException e) { - LOG.error("interrupted while starting to read from external command", e); - } catch (ExecutionException e) { - LOG.error("exception while starting to read from external command", e.getCause()); - } finally { - IOUtils.closeQuietly(in); - if (_logVerbose) { - log(prefix + ""); - } - } - - _running = false; - } - - public byte[] getOutput() { - if (_running) { - throw new IllegalStateException("wait for process to be completed"); - } - - return _out.toByteArray(); - } - - private void log(String line) { - Level.logWithLevel(LOG, _logLevel, "{}", line); - } - } - - /** - * Constructor */ - public ExternalCommand(ProcessBuilder processBuilder) { - _isTimedOut = false; - _processBuilder = processBuilder; - } - - /** - * After creating the command, you have to start it... - * - * @throws IOException - */ - public void start() throws IOException { - if (_process != null || _out != null || _err != null) { - throw new IllegalStateException("already started"); - } - - AsyncPromise out = AsyncFuture.deferred(true); - AsyncPromise err = AsyncFuture.deferred(true); - - Level logLevel = Level.ERROR; - if (LOG.isDebugEnabled()) { - logLevel = Level.DEBUG; - } else if (LOG.isInfoEnabled()) { - logLevel = Level.INFO; - } - - _out = new InputReader(out, logLevel, "Subprocess output stream"); - _err = new InputReader(err, Level.INFO, "Subprocess error stream"); - - _out.start(); - _err.start(); - - try { - _process = _processBuilder.start(); - out.setSuccess(_process.getInputStream()); - err.setSuccess(_process.getErrorStream()); - } finally { - // These will fail to cancel if successfully set above. - out.cancel(true); - err.cancel(true); - } - } - - /** - * @see ProcessBuilder - */ - public Map getEnvironment() { - return _processBuilder.environment(); - } - - /** - * @see ProcessBuilder - */ - public File getWorkingDirectory() { - return _processBuilder.directory(); - } - - /** - * @see ProcessBuilder - */ - public void setWorkingDirectory(File directory) { - _processBuilder.directory(directory); - } - - /** - * @see ProcessBuilder - */ - public boolean getRedirectErrorStream() { - return _processBuilder.redirectErrorStream(); - } - - /** - * @see ProcessBuilder - */ - public void setRedirectErrorStream(boolean redirectErrorStream) { - _processBuilder.redirectErrorStream(redirectErrorStream); - } - - public void setTimedOut(boolean val) { - _isTimedOut = val; - } - - public boolean isTimedOut() { - return _isTimedOut; - } - - public byte[] getOutput() throws InterruptedException { - waitFor(); - return _out.getOutput(); - } - - public byte[] getError() throws InterruptedException { - waitFor(); - return _err.getOutput(); - } - - /** - * Returns the output as a string. - * - * @param encoding - * @return encoded string - * @throws InterruptedException - * @throws UnsupportedEncodingException - */ - public String getStringOutput(String encoding) throws InterruptedException, UnsupportedEncodingException { - return getStringOutput(Charset.forName(encoding)); - } - - /** - * Returns the output as a string. - * - * @param encoding - * @return encoded string - * @throws InterruptedException - * @throws UnsupportedEncodingException - */ - public String getStringOutput(Charset encoding) throws InterruptedException { - return new String(getOutput(), Objects.requireNonNull(encoding, "encoding")); - } - - /** - * Returns the output as a string. Uses encoding "UTF-8". - * - * @return utf8 encoded string - * @throws InterruptedException - */ - public String getStringOutput() throws InterruptedException { - return getStringOutput(StandardCharsets.UTF_8); - } - - /** - * Returns the error as a string. - * - * @param encoding - * @return error as string - * @throws InterruptedException - */ - public String getStringError(Charset encoding) throws InterruptedException { - return new String(getError(), Objects.requireNonNull(encoding, "encoding")); - } - - /** - * Returns the error as a string. - * - * @param encoding - * @return error as string - * @throws InterruptedException - * @throws UnsupportedEncodingException - */ - public String getStringError(String encoding) throws InterruptedException, UnsupportedEncodingException { - return getStringError(Charset.forName(encoding)); - } - - /** - * Returns the error as a string. Uses encoding "UTF-8". - * - * @return error as string - * @throws InterruptedException - */ - public String getStringError() throws InterruptedException { - return getStringError(StandardCharsets.UTF_8); - } - - /** - * Properly waits until everything is complete: joins on the thread that - * reads the output, joins on the thread that reads the error and finally - * wait for the process to be finished. - * @return the status code of the process. - * - * @throws InterruptedException - */ - public int waitFor() throws InterruptedException { - if (_process == null) { - throw new IllegalStateException("you must call start first"); - } - - int exitCode = _process.waitFor(); - - _out.interrupt(); - _err.interrupt(); - - _out.join(); - _err.join(); - - return exitCode; - } - - private Process checkStart() { - Process process = _process; - Preconditions.checkState(process != null, "you must call start first"); - return process; - } - - /** - * Properly waits until everything is complete: joins on the thread that - * reads the output, joins on the thread that reads the error and finally - * wait for the process to be finished. - * If the process has not completed before the timeout, throws a - * {@link TimeoutException} - * @return the status code of the process. - * - * @throws TimeoutException - * @throws InterruptedException - */ - public int waitFor(long timeout, TimeUnit unit) throws InterruptedException, TimeoutException, IOException { - if (checkStart().waitFor(timeout, unit)) { - return waitFor(); - } else { - throw new TimeoutException(); - } - } - - /** - * Properly waits until everything is complete: joins on the thread that - * reads the output, joins on the thread that reads the error and finally - * wait for the process to be finished. - * If the process has not completed before the timeout, throws a - * {@link TimeoutException} - * @return the status code of the process. - * - * @throws TimeoutException - * @throws InterruptedException - */ - public int waitFor(long timeout) throws InterruptedException, TimeoutException, IOException { - return waitFor(timeout, TimeUnit.MILLISECONDS); - } - - public int exitValue() { - return checkStart().exitValue(); - } - - public void destroy() { - checkStart(); - - _out.interrupt(); - _err.interrupt(); - - _process.destroy(); - - try { - waitFor(); - } catch (Exception e) { - LOG.warn("Error waiting for process termination: " + e.getMessage()); - } - } - - /** - * Creates an external process from the command. It is not started and you have to call - * start on it! - * - * @param commands the command to execute - * @return the process */ - public static ExternalCommand create(String... commands) { - ExternalCommand ec = new ExternalCommand(new ProcessBuilder(commands)); - return ec; - } - - /** - * Creates an external process from the command. It is not started and you have to call - * start on it! - * - * @param commands the command to execute - * @return the process */ - public static ExternalCommand create(List commands) { - ExternalCommand ec = new ExternalCommand(new ProcessBuilder(commands)); - return ec; - } - - /** - * Creates an external process from the command. The command is executed. - * - * @param commands the commands to execute - * @return the process - * @throws IOException if there is an error */ - @CheckReturnValue - public static ExternalCommand start(String... commands) throws IOException { - ExternalCommand ec = new ExternalCommand(new ProcessBuilder(commands)); - ec.start(); - return ec; - } - - /** - * Executes the external command in the given working directory and waits for it to be - * finished. - * - * @param workingDirectory the root directory from where to run the command - * @param command the command to execute (should be relative to the working directory - * @param args the arguments to the command - * @return the process */ - @CheckReturnValue - public static ExternalCommand execute(File workingDirectory, String command, String... args) - throws IOException, InterruptedException { - return executeWithTimeout(workingDirectory, command, 0, args); - } - - /** - * Executes the external command in the given working directory and waits (until timeout - * is elapsed) for it to be finished. - * - * @param workingDirectory - * the root directory from where to run the command - * @param command - * the command to execute (should be relative to the working directory - * @param timeout - * the maximum amount of time to wait for this external command (in ms). If - * this value is less than or equal to 0, timeout is ignored - * @param args - * the arguments to the command - * @return the process - */ - @CheckReturnValue - public static ExternalCommand executeWithTimeout(File workingDirectory, String command, long timeout, String... args) - throws IOException, InterruptedException { - return executeWithTimeoutWithEnv(workingDirectory, command, timeout, null, args); - } - - @CheckReturnValue - public static ExternalCommand executeWithTimeoutWithEnv( - File workingDirectory, - String command, - long timeout, - Map env, - String... args) throws IOException, InterruptedException { - List arguments = new ArrayList<>(args.length + 1); - - arguments.add(new File(workingDirectory, command).getAbsolutePath()); - arguments.addAll(Arrays.asList(args)); - - ExternalCommand cmd = ExternalCommand.create(arguments); - - cmd.setWorkingDirectory(workingDirectory); - - cmd.setRedirectErrorStream(true); - - Map cmdEnvironment = cmd.getEnvironment(); - if (env != null) { - cmdEnvironment.putAll(env); - } - if (!cmdEnvironment.get("PATH").contains(JDK_HOME_DIR + "/bin")) { - final String newpath = String.format("%s/%s:%s", JDK_HOME_DIR, "bin", cmdEnvironment.get("PATH")); - cmdEnvironment.put("PATH", newpath); - LOG.info("forcing JDK8 path {}", newpath); - } - cmdEnvironment.put("JAVA_HOME", JDK_HOME_DIR); - cmdEnvironment.put("JDK_HOME", JDK_HOME_DIR); - - cmd.start(); - try { - /* Use timeout if it is a valid value! */ - if (timeout <= 0) { - cmd.waitFor(); - } else { - cmd.waitFor(timeout); - } - } catch (TimeoutException te) { - cmd.setTimedOut(true); - LOG.warn("Command has timed out [{}] ms", timeout); - } finally { - // clean up - cmd.destroy(); - } - return cmd; - } -} diff --git a/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/IOUtils.java b/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/IOUtils.java deleted file mode 100644 index 37d91ecd29e..00000000000 --- a/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/IOUtils.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.linkedin.alpini.io; - -import java.io.ByteArrayOutputStream; -import java.io.Closeable; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.StringWriter; -import java.nio.charset.Charset; -import javax.annotation.WillClose; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** - * @author Antony T Curtis {@literal } - */ -public enum IOUtils { - SINGLETON; // Effective Java, Item 3 - Enum singleton - - private static final Logger LOG = LogManager.getLogger(IOUtils.class); - - public static final int EOF = -1; - - public static void closeQuietly(@WillClose Closeable stream) { - try (Closeable closeable = stream) { - LOG.debug("closeQuietly({})", closeable); - } catch (IOException ex) { - LOG.debug("Error closing stream {}", stream, ex); - } - } - - public static long copy(InputStream inputStream, OutputStream outputStream) throws IOException { - return copy(inputStream, outputStream, 8192); - } - - public static long copy(InputStream inputStream, OutputStream outputStream, final int bufferSize) throws IOException { - return copy(inputStream, outputStream, new byte[bufferSize]); - } - - public static long copy(InputStream inputStream, OutputStream outputStream, byte[] buffer) throws IOException { - long totalBytesCopied = 0; - int bytesRead; - while (EOF != (bytesRead = inputStream.read(buffer))) { - outputStream.write(buffer, 0, bytesRead); - totalBytesCopied += bytesRead; - } - return totalBytesCopied; - } - - public static byte[] toByteArray(InputStream inputStream) throws IOException { - return toByteArray(inputStream, new byte[4096]); - } - - public static byte[] toByteArray(InputStream inputStream, byte[] buffer) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - int bytesRead; - while (EOF != (bytesRead = inputStream.read(buffer))) { - baos.write(buffer, 0, bytesRead); - } - return baos.toByteArray(); - } - - public static String toString(InputStream inputStream, Charset charset) throws IOException { - return toString(inputStream, charset, new char[4096]); - } - - public static String toString(InputStream inputStream, Charset charset, char[] buffer) throws IOException { - StringWriter writer = new StringWriter(); - InputStreamReader reader = new InputStreamReader(inputStream, charset); - int charsRead; - while (EOF != (charsRead = reader.read(buffer))) { - writer.write(buffer, 0, charsRead); - } - return writer.toString(); - } -} diff --git a/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/MeteredOutputStream.java b/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/MeteredOutputStream.java deleted file mode 100644 index 03ee618d6aa..00000000000 --- a/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/MeteredOutputStream.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.linkedin.alpini.io; - -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Objects; -import javax.annotation.Nonnull; - - -/** - * @author Antony T Curtis - */ -public class MeteredOutputStream extends FilterOutputStream { - private long _bytes; - - /** - * Creates an output stream filter built on top of the specified - * underlying output stream. - * - * @param out the underlying output stream. - */ - public MeteredOutputStream(@Nonnull OutputStream out) { - super(Objects.requireNonNull(out)); - } - - public long getBytesWritten() { - return _bytes; - } - - /** - * Writes the specified byte to this output stream. - * - * @param b the byte. - * @throws java.io.IOException if an I/O error occurs. - */ - @Override - public void write(int b) throws IOException { - out.write(b); - _bytes++; - } - - /** - * Writes b.length bytes to this output stream. - * - * @param b the data to be written. - * @throws java.io.IOException if an I/O error occurs. - */ - @Override - public void write(@Nonnull byte[] b) throws IOException { - out.write(b); - _bytes += b.length; - } - - /** - * Writes len bytes from the specified - * byte array starting at offset off to - * this output stream. - - * @param b the data. - * @param off the start offset in the data. - * @param len the number of bytes to write. - * @throws java.io.IOException if an I/O error occurs. - */ - @Override - public void write(@Nonnull byte[] b, int off, int len) throws IOException { - out.write(b, off, len); - _bytes += len; - } -} diff --git a/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/NullOutputStream.java b/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/NullOutputStream.java deleted file mode 100644 index deceb956d04..00000000000 --- a/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/NullOutputStream.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.linkedin.alpini.io; - -import java.io.IOException; -import java.io.OutputStream; - - -/** - * A simple @{link OutputStream} implementation which is equivalent to - * {@code /dev/null} by acting as a sink for bytes. - * - * @author Antony T Curtis - */ -public final class NullOutputStream extends OutputStream { - private long _bytesWritten = 0; - - @Override - public void write(int b) throws IOException { - _bytesWritten++; - } - - @Override - public void write(byte[] b) throws IOException { - _bytesWritten += b.length; - } - - @Override - public void write(byte[] b, int off, int len) throws IOException { - _bytesWritten += len; - } - - public long getBytesWritten() { - return _bytesWritten; - } -} diff --git a/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/PigzDeflateCompressor.java b/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/PigzDeflateCompressor.java deleted file mode 100644 index 72ee8c37e3a..00000000000 --- a/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/PigzDeflateCompressor.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.linkedin.alpini.io; - -import java.io.IOException; -import java.util.zip.Deflater; -import javax.annotation.Nonnull; - - -/** - * @author Antony T Curtis {@literal } - */ -public class PigzDeflateCompressor extends PigzOutputStream.Compressor { - private final Deflater _deflater; - private final byte[] _inputBytes; - private final byte[] _outputBytes; - private int _inputBytesAvailable; - private int _outputBytesAvailable; - - public PigzDeflateCompressor(@Nonnull PigzOutputStream pigz, int compressionLevel, int blockSize) { - super(pigz); - _deflater = new Deflater(compressionLevel, true); - _inputBytes = new byte[blockSize]; - _outputBytes = new byte[12 + (int) Math.ceil(blockSize * 1.001)]; - } - - @Override - protected void setDeflateDictionary(byte[] dict, int dictLength) { - _deflater.setDictionary(dict, 0, dictLength); - } - - @Override - protected void resetDeflator() { - _inputBytesAvailable = 0; - _outputBytesAvailable = 0; - } - - @Override - protected void reinitDeflator() { - _deflater.reset(); - } - - @Override - protected int write(@Nonnull byte[] b, int off, int len) { - int count = Math.min(len, _inputBytes.length - _inputBytesAvailable); - System.arraycopy(b, off, _inputBytes, _inputBytesAvailable, count); - _inputBytesAvailable += count; - return count; - } - - @Override - protected int getInputAvailable() { - return _inputBytesAvailable; - } - - @Override - protected boolean isInputBufferFull() { - return _inputBytesAvailable == _inputBytes.length; - } - - @Override - @Nonnull - protected byte[] getInputBuffer() { - return _inputBytes; - } - - @Override - @Nonnull - protected byte[] getOutputBuffer() { - return _outputBytes; - } - - @Override - protected int getOutputAvailable() { - return _outputBytesAvailable; - } - - @Override - protected void deflate() throws IOException { - _deflater.setInput(getInputBuffer(), 0, getInputAvailable()); - if (isFinalBlock()) { - _deflater.finish(); - } - _outputBytesAvailable = _deflater.deflate(_outputBytes, 0, _outputBytes.length, Deflater.SYNC_FLUSH); - } -} diff --git a/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/PigzOutputStream.java b/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/PigzOutputStream.java deleted file mode 100644 index b2e0dd45748..00000000000 --- a/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/PigzOutputStream.java +++ /dev/null @@ -1,528 +0,0 @@ -package com.linkedin.alpini.io; - -import com.linkedin.alpini.base.hash.Crc32; -import com.linkedin.alpini.base.misc.Time; -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Objects; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Executor; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.Semaphore; -import java.util.function.Function; -import javax.annotation.Nonnull; -import javax.annotation.WillCloseWhenClosed; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** - * @author Antony T Curtis - */ -public class PigzOutputStream extends FilterOutputStream { - private static final Logger LOG = LogManager.getLogger(PigzOutputStream.class); - - private static final int[] ODD = precomputeCrc32Comb(); - private static final int CHECK_INIT = Crc32.crc32(0, new byte[0], 0, 0); - - public static final int DICT_LENGTH = 32768; - public static final int DEFAULT_BLOCK_SIZE = 128 * 1024; - - private final Executor _executor; - private final BlockingQueue _idleCompressors; - private final ConcurrentLinkedQueue _exceptions = new ConcurrentLinkedQueue<>(); - private final BlockingQueue _writeSemaphoreQueue; - private final BlockingQueue _crcSemaphoreQueue; - private final CountDownLatch _finished = new CountDownLatch(1); - private final int _compressionLevel; - private final byte[] _unaryByte = new byte[1]; - private Compressor _current; - private int _sequence; - private volatile int _crc = CHECK_INIT; - private volatile long _ulen; - private volatile long _clen; - private byte[] _dict; - private int _dictLength; - private boolean _finalBlockSubmitted; - private boolean _closed; - private boolean _footerWritten; - - /** - * Creates a new output stream with the specified compression level, concurrency and a default block size. - * @param compressionLevel gzip compression level, 1..9 - * @param executor executor to run threads. - * @param concurrency maximum number of worker threads. - * @param out the output stream. - * @throws IOException if an I/O error has occurred. - */ - public PigzOutputStream( - int compressionLevel, - @Nonnull Executor executor, - int concurrency, - @Nonnull @WillCloseWhenClosed OutputStream out) throws IOException { - this(compressionLevel, executor, concurrency, out, DEFAULT_BLOCK_SIZE); - } - - /** - * Creates a new output stream with the specified compression level, concurrency and block size. - * @param compressionLevel gzip compression level, 1..9 - * @param executor executor to run threads. - * @param concurrency maximum number of worker threads. - * @param out the output stream. - * @param blockSize compressor block size - * @throws IOException if an I/O error has occurred. - */ - public PigzOutputStream( - int compressionLevel, - @Nonnull Executor executor, - int concurrency, - @Nonnull @WillCloseWhenClosed OutputStream out, - int blockSize) throws IOException { - this( - compressionLevel, - executor, - concurrency, - out, - blockSize, - (pigz) -> new PigzDeflateCompressor(pigz, compressionLevel, blockSize)); - } - - public PigzOutputStream( - int compressionLevel, - @Nonnull Executor executor, - int concurrency, - @Nonnull @WillCloseWhenClosed OutputStream out, - int blockSize, - @Nonnull Function compressorSupplier) throws IOException { - super(Objects.requireNonNull(out)); - try { - executor = Objects.requireNonNull(executor, "executor cannot be null"); - - if (concurrency < 1 || compressionLevel < 1 || compressionLevel > 9 || blockSize < DICT_LENGTH) { - throw new IllegalArgumentException(); - } - - _executor = executor; - _compressionLevel = compressionLevel; - - writeHeader(); - - _idleCompressors = new LinkedBlockingQueue<>(); - _writeSemaphoreQueue = new LinkedBlockingQueue<>(); - _crcSemaphoreQueue = new LinkedBlockingQueue<>(); - - while (concurrency > 0) { - Compressor compressor = compressorSupplier.apply(this); - if (compressor._pigz != this || _idleCompressors.contains(compressor)) { - throw new IllegalArgumentException(); - } - _idleCompressors.add(compressor); - concurrency--; - } - - _writeSemaphoreQueue.add(new Semaphore(1)); - _crcSemaphoreQueue.add(new Semaphore(1)); - } catch (RuntimeException ex) { - IOUtils.closeQuietly(out); - throw ex; - } - } - - private void writeHeader() throws IOException { - int time = (int) (Time.currentTimeMillis() / 1000L); - byte[] header = { (byte) 31, (byte) 139, (byte) 8, (byte) 0, (byte) ((time) & 0xff), (byte) ((time >>> 8) & 0xff), - (byte) ((time >>> 16) & 0xff), (byte) ((time >>> 24) & 0xff), - _compressionLevel >= 9 ? (byte) 2 : _compressionLevel == 1 ? (byte) 4 : (byte) 0, (byte) 3 }; - out.write(header, 0, 10); - out.flush(); - } - - /** - * Writes the specified byte to this output stream. - *

- * Implements the abstract write method of OutputStream. - * - * @param b the byte. - * @throws IOException if an I/O error occurs. - */ - @Override - public void write(int b) throws IOException { - _unaryByte[0] = (byte) b; - write(_unaryByte, 0, 1); - } - - private void throwPendingException() throws IOException { - if (!_exceptions.isEmpty()) { - throw _exceptions.remove(); - } - } - - /** - * Writes len bytes from the specified - * byte array starting at offset off to - * this output stream. - * - * @param b the data. - * @param off the start offset in the data. - * @param len the number of bytes to write. - * @throws IOException if an I/O error occurs. - * @see FilterOutputStream#write(int) - */ - @Override - public void write(@Nonnull byte[] b, int off, int len) throws IOException { - if (_closed) { - throw new IOException("already closed"); - } - if (off < 0 || len < 0 || b.length < off + len) { - throw new ArrayIndexOutOfBoundsException(); - } - while (len > 0) { - throwPendingException(); - - checkCompressor(); - - int count = _current.write(b, off, len); - if (_current.isInputBufferFull()) { - submit(); - } - off += count; - len -= count; - } - } - - /** - * Flushes this output stream and forces any buffered output bytes - * to be written out to the stream. - *

- * The flush method of FilterOutputStream - * calls the flush method of its underlying output stream. - * - * @throws IOException if an I/O error occurs. - * @see FilterOutputStream#out - */ - @Override - public void flush() throws IOException { - throwPendingException(); - - if (_current != null) { - submit(); - } - } - - private void submit() { - _current.setDictionary(_dict, _dictLength); - - /* Set the compression dictionary for the next block */ - if (_current.getInputAvailable() >= DICT_LENGTH || _dict == null) { - _dictLength = Math.min(DICT_LENGTH, _current.getInputAvailable()); - _dict = new byte[DICT_LENGTH]; - System.arraycopy(_current.getInputBuffer(), _current.getInputAvailable() - _dictLength, _dict, 0, _dictLength); - } else if (_dictLength + _current.getInputAvailable() <= DICT_LENGTH) { - System.arraycopy(_current.getInputBuffer(), 0, _dict, _dictLength, _current.getInputAvailable()); - _dictLength += _current.getInputAvailable(); - } else { - byte[] old = _dict; - int excess = _dictLength + _current.getInputAvailable() - DICT_LENGTH; - _dict = new byte[DICT_LENGTH]; - _dictLength -= excess; - System.arraycopy(old, excess, _dict, 0, _dictLength); - System.arraycopy(_current.getInputBuffer(), 0, _dict, _dictLength, _current.getInputAvailable()); - _dictLength += _current.getInputAvailable(); - } - - _executor.execute(_current); - _current = null; - } - - private Compressor checkCompressor() throws IOException { - if (_current == null) { - try { - Semaphore writeSemaphore = _writeSemaphoreQueue.take(); - Semaphore crcSemaphore = _crcSemaphoreQueue.take(); - Semaphore nextWriteSemaphore; - Semaphore nextCrcSemaphore; - - while ((nextWriteSemaphore = _writeSemaphoreQueue.peek()) == null) { - _writeSemaphoreQueue.add(new Semaphore(0)); - } - while ((nextCrcSemaphore = _crcSemaphoreQueue.peek()) == null) { - _crcSemaphoreQueue.add(new Semaphore(0)); - } - - _current = _idleCompressors.take() - .reset(_sequence++, writeSemaphore, nextWriteSemaphore, crcSemaphore, nextCrcSemaphore); - } catch (InterruptedException e) { - throw new IOException(e); - } - } - return _current; - } - - /** - * Closes this output stream and releases any system resources - * associated with the stream. - * - * @throws IOException if an I/O error occurs. - * @see FilterOutputStream#flush() - * @see FilterOutputStream#out - */ - @Override - public void close() throws IOException { - boolean awaiting = false; - try { - _closed = true; - - throwPendingException(); - - if (!_finalBlockSubmitted) { - checkCompressor().setFinalBlock(); - _finalBlockSubmitted = true; - } - - flush(); - - awaiting = true; - _finished.await(); - awaiting = false; - - if (!_footerWritten) { - long crc = _crc; - long ulen = _ulen; - - byte[] trailer = new byte[] { (byte) (crc & 0xff), (byte) ((crc >>> 8) & 0xff), (byte) ((crc >>> 16) & 0xff), - (byte) ((crc >>> 24) & 0xff), (byte) (ulen & 0xff), (byte) ((ulen >>> 8) & 0xff), - (byte) ((ulen >>> 16) & 0xff), (byte) ((ulen >>> 24) & 0xff) }; - out.write(trailer, 0, 8); - out.flush(); - _footerWritten = true; - } - } catch (InterruptedException e) { - throw new IOException(e); - } finally { - if (!awaiting) { - out.close(); - } - } - } - - /** - * Returns how many bytes has been written to this OutputStream. - * @return number of bytes - */ - public long getBytesCompressed() { - return _ulen; - } - - /** - * Returns how many bytes has been written to the underlying OutputStream. - * @return number of bytes - */ - public long getBytesWritten() { - return _clen; - } - - private static final byte[] EMPTY = new byte[0]; - - public static abstract class Compressor implements Runnable { - protected static final Logger LOG = PigzOutputStream.LOG; - private final @Nonnull PigzOutputStream _pigz; - - private final int[] _even = new int[32]; - private final int[] _odd = new int[32]; - - private int _crc32; - private byte[] _dict; - private int _dictLength; - - private boolean _finalBlock; - - private int _sequence; - private Semaphore _writeSerializer; - private Semaphore _nextWriteSerializer; - private Semaphore _crcSerializer; - private Semaphore _nextCrcSerializer; - - protected Compressor(@Nonnull PigzOutputStream pigz) { - _pigz = pigz; - } - - private Compressor reset( - int sequence, - Semaphore writeSerializer, - Semaphore nextWriteSerializer, - Semaphore crcSerializer, - Semaphore nextCrcSerializer) { - _sequence = sequence; - resetDeflator(); - _crc32 = Crc32.crc32(0, EMPTY, 0, 0); - _writeSerializer = writeSerializer; - _nextWriteSerializer = nextWriteSerializer; - _crcSerializer = crcSerializer; - _nextCrcSerializer = nextCrcSerializer; - return this; - } - - private void setFinalBlock() { - _finalBlock = true; - } - - public final boolean isFinalBlock() { - return _finalBlock; - } - - public final int getSequence() { - return _sequence; - } - - public final void setDictionary(byte[] dict, int dictLength) { - _dict = dict; - _dictLength = dictLength; - } - - protected abstract void setDeflateDictionary(byte[] dict, int dictLength); - - protected abstract void resetDeflator(); - - protected abstract void reinitDeflator(); - - protected abstract int write(@Nonnull byte[] b, int off, int len); - - protected abstract int getInputAvailable(); - - protected abstract boolean isInputBufferFull(); - - protected abstract @Nonnull byte[] getInputBuffer(); - - protected abstract @Nonnull byte[] getOutputBuffer(); - - protected abstract int getOutputAvailable(); - - protected abstract void deflate() throws IOException; - - @Override - public final void run() { - try { - if (_dict != null) { - setDeflateDictionary(_dict, _dictLength); - } - - _crc32 = Crc32.crc32(_crc32, getInputBuffer(), 0, getInputAvailable()); - - try { - deflate(); - } catch (IOException ex) { - LOG.warn("deflate exception", ex); - _pigz._exceptions.add(ex); - } - - /* Wait for the write ticket */ - _writeSerializer.acquireUninterruptibly(); - _pigz._writeSemaphoreQueue.add(_writeSerializer); - _writeSerializer = null; - - int ofs = 0; - int len = getOutputAvailable(); - if (len != 0) { - try { - _pigz.out.write(getOutputBuffer(), ofs, len); - _pigz.out.flush(); - _pigz._clen += len; - } catch (IOException e) { - _pigz._exceptions.add(e); - } - } - - /* Release the next write ticket */ - _nextWriteSerializer.release(); - _nextWriteSerializer = null; - - /* Wait for the CRC ticket */ - _crcSerializer.acquireUninterruptibly(); - _pigz._crcSemaphoreQueue.add(_crcSerializer); - _crcSerializer = null; - - _pigz._crc = crc32Comb(_pigz._crc, _crc32, getInputAvailable()); - _pigz._ulen += getInputAvailable(); - - if (_finalBlock) { - /* Indicate that we have finished and that the trailer can be written */ - _pigz._finished.countDown(); - } else { - /* Release the next CRC ticket */ - _nextCrcSerializer.release(); - _nextCrcSerializer = null; - } - } finally { - reinitDeflator(); - _pigz._idleCompressors.add(this); - } - } - - private int crc32Comb(int crc1, int crc2, int len2) { - /* degenerate case (also disallow negative lengths) */ - if (len2 <= 0) { - return crc1; - } - - System.arraycopy(PigzOutputStream.ODD, 0, _odd, 0, 32); - - do { - gf2MatrixSquare(_even, _odd); - if ((len2 & 1) != 0) { - crc1 = gf2MatrixTimes(_even, crc1); - } - len2 >>>= 1; - - if (len2 == 0) { - break; - } - - gf2MatrixSquare(_odd, _even); - if ((len2 & 1) != 0) { - crc1 = gf2MatrixTimes(_odd, crc1); - } - len2 >>>= 1; - } while (len2 != 0); - return crc1 ^ crc2; - } - } - - private static @Nonnull int[] precomputeCrc32Comb() { - int[] even = new int[32]; - int[] odd = new int[32]; - - odd[0] = 0xedb88320; - int row = 1; - for (int n = 1; n < 32; n++) { - odd[n] = row; - row <<= 1; - } - - gf2MatrixSquare(even, odd); - gf2MatrixSquare(odd, even); - - return odd; - } - - private static int gf2MatrixTimes(@Nonnull int[] mat, int vec) { - int sum = 0; - int index = 0; - while (vec != 0) { - if ((vec & 1) != 0) { - sum ^= mat[index]; - } - vec >>>= 1; - index++; - } - return sum; - } - - private static void gf2MatrixSquare(@Nonnull int[] square, @Nonnull int[] mat) { - for (int n = 0; n < 32; n++) { - square[n] = gf2MatrixTimes(mat, mat[n]); - } - } -} diff --git a/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/SubprocessBuilder.java b/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/SubprocessBuilder.java deleted file mode 100644 index e2f50cff286..00000000000 --- a/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/SubprocessBuilder.java +++ /dev/null @@ -1,199 +0,0 @@ -package com.linkedin.alpini.io; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Consumer; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** - * A proxy class for java.lang.ProcessBuilder which may be overridden - * for purposes of test. - * - * @author Antony T Curtis - */ -public class SubprocessBuilder { - private static final Logger LOG = LogManager.getLogger(Process.class); - - private ProcessBuilder _builder; - /** - * if not null , the process stdout is written to this logger - */ - private Consumer _logStdOut; - /** - * if not null , the process stderr is written to this logger - */ - private Consumer _logStdErr; - /** - * Used to generate a unique thread name for the logging threads - */ - private static final AtomicInteger _loggerThreadNumber = new AtomicInteger(0); - - protected ProcessBuilder builder() { - if (_builder == null) { - _builder = new ProcessBuilder(); - } - return _builder; - } - - /** - * @see ProcessBuilder#command() - */ - public List command() { - return builder().command(); - } - - /** - * @see ProcessBuilder#command(java.util.List) - */ - public SubprocessBuilder command(List command) { - builder().command(command); - return this; - } - - /** - * @see ProcessBuilder#command(String...) - */ - public SubprocessBuilder command(String... command) { - return command(Arrays.asList(command)); - } - - /** - * @see ProcessBuilder#directory() - */ - public File directory() { - return builder().directory(); - } - - /** - * @see ProcessBuilder#directory(java.io.File) - */ - public SubprocessBuilder directory(File directory) { - builder().directory(directory); - return this; - } - - /** - * @see ProcessBuilder#environment() - */ - public Map environment() { - return builder().environment(); - } - - /** - * @see ProcessBuilder#redirectErrorStream() - */ - public boolean redirectErrorStream() { - return builder().redirectErrorStream(); - } - - /** - * @see ProcessBuilder#redirectErrorStream(boolean) - */ - public SubprocessBuilder redirectErrorStream(boolean redirectErrorStream) { - builder().redirectErrorStream(redirectErrorStream); - return this; - } - - public ProcessBuilder processBuilder() { - try { - return _builder; - } finally { - _builder = null; - } - } - - /** - * @see ProcessBuilder#start() - */ - public Process start() throws IOException { - Process process = processBuilder().start(); - int threadNumber = _loggerThreadNumber.incrementAndGet(); - - Runnable startLogStdOut; - if (_logStdOut != null) { - Thread thd = new Thread( - new LogStream(process.getInputStream(), _logStdOut), - "EspressoProcessBuilder-Stdout-" + threadNumber); - startLogStdOut = thd::start; - } else { - startLogStdOut = () -> {}; - } - - Runnable startLogErrOut; - if (_logStdErr != null) { - Thread thd = new Thread( - new LogStream(process.getErrorStream(), _logStdErr), - "EspressoProcessBuilder-Stderr-" + threadNumber); - startLogErrOut = thd::start; - } else { - startLogErrOut = () -> {}; - } - - startLogStdOut.run(); - startLogErrOut.run(); - return process; - } - - @Override - public String toString() { - return builder().toString(); - } - - /** - * When the process is started , log the process stdout - * to the Logger. This must be called before starting the process. - * @param consumer Log for std out - */ - public void setStdOutLog(Consumer consumer) { - _logStdOut = consumer; - } - - /** - * When the process is started , log the process stderr - * to the Logger. This must be called before starting the process. - * @param consumer Log for std err - */ - public void setStdErrLog(Consumer consumer) { - _logStdErr = consumer; - } - - private static class LogStream implements Runnable { - final BufferedReader _reader; - Consumer _consumer; - - public LogStream(InputStream input, Consumer consumer) throws IOException { - _reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8)); - _consumer = consumer; - } - - @Override - public void run() { - try { - while (true) { - String line = _reader.readLine(); - if (line == null) { - break; - } - if (!line.isEmpty()) { - _consumer.accept(line); - } - } - } catch (IOException ex) { - LOG.warn("IOException reading from stream", ex); - } finally { - IOUtils.closeQuietly(_reader); - } - } - } - -} diff --git a/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/ZeroInputStream.java b/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/ZeroInputStream.java deleted file mode 100644 index 83c18439c5e..00000000000 --- a/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/ZeroInputStream.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.linkedin.alpini.io; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; -import javax.annotation.Nonnull; - - -/** - * A simple @{link InputStream} implementation which is equivalent to - * {@code /dev/zero} by acting as a source for a stream of NUL bytes. - * - * @author Antony T Curtis - */ -public final class ZeroInputStream extends InputStream { - private long _remaining; - - public ZeroInputStream(long remaining) { - _remaining = remaining; - } - - @Override - public int read() throws IOException { - if (_remaining == 0) { - return -1; - } - _remaining--; - return 0; - } - - @Override - public int read(@Nonnull byte[] b, int off, int len) throws IOException { - if (len < 0 || off < 0 || off + len > b.length) { - throw new ArrayIndexOutOfBoundsException(); - } - int available = available(); - if (available <= 0) { - return -1; - } - len = Math.min(len, available); - Arrays.fill(b, off, off + len, (byte) 0); - _remaining -= len; - return len; - } - - @Override - public int read(@Nonnull byte[] b) throws IOException { - return read(b, 0, b.length); - } - - @Override - public long skip(long n) throws IOException { - if (n < 0) { - throw new IllegalArgumentException(); - } - if (_remaining < 0) { - return n; - } - n = Math.min(n, _remaining); - _remaining -= n; - return n; - } - - @Override - public int available() throws IOException { - return _remaining >= 0 && _remaining <= Integer.MAX_VALUE ? (int) _remaining : Integer.MAX_VALUE; - } - - public long getBytesRemaining() { - return _remaining; - } -} diff --git a/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/package-info.java b/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/package-info.java deleted file mode 100644 index 50a3b48ada2..00000000000 --- a/internal/alpini/common/alpini-common-io/src/main/java/com/linkedin/alpini/io/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * @author Antony T Curtis {@literal } - */ -package com.linkedin.alpini.io; diff --git a/internal/alpini/common/alpini-common-io/src/test/java/com/linkedin/alpini/io/TestCompressOutputStream.java b/internal/alpini/common/alpini-common-io/src/test/java/com/linkedin/alpini/io/TestCompressOutputStream.java deleted file mode 100644 index eacee2c50d8..00000000000 --- a/internal/alpini/common/alpini-common-io/src/test/java/com/linkedin/alpini/io/TestCompressOutputStream.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.linkedin.alpini.io; - -import com.linkedin.alpini.base.concurrency.CompletableFutureTask; -import com.linkedin.alpini.base.concurrency.ExecutorService; -import com.linkedin.alpini.base.concurrency.Executors; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; -import org.testng.Assert; -import org.testng.annotations.Test; - - -/** - * Created by acurtis on 1/24/18. - */ -public class TestCompressOutputStream { - @Test(groups = "unit") - public void testBasic() throws IOException { - ExecutorService ex = Executors.newCachedThreadPool(); - try { - - byte[] input = "This is a quick and simple test of the test foo blah".getBytes(StandardCharsets.US_ASCII); - - CompletableFuture task1; - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - try (CompressOutputStream os = new CompressOutputStream(5, ex, 1, bos)) { - os.write(input); - os.write(input); - os.write(input); - - CompletableFutureTask task = new CompletableFutureTask<>(() -> { - os.await(); - return null; - }); - task1 = task.toCompletableFuture(); - ex.execute(task); - - os.write(input); - os.write(input); - } - task1.join(); - - byte[] bytes1 = bos.toByteArray(); - - CompletableFuture task2; - bos = new ByteArrayOutputStream(); - try (CompressOutputStream os = new CompressOutputStream(5, ex, 4, bos)) { - os.write(input); - os.write(input); - - CompletableFutureTask task = new CompletableFutureTask<>(() -> { - os.await(1, TimeUnit.SECONDS); - return null; - }); - task2 = task.toCompletableFuture(); - ex.execute(task); - - os.write(input); - os.write(input); - os.write(input); - } - task2.join(); - - byte[] bytes2 = bos.toByteArray(); - - Assert.assertTrue(bytes1.length < input.length * 5); - Assert.assertTrue(bytes2.length < input.length * 5); - - } finally { - ex.shutdownNow(); - } - } - -} diff --git a/internal/alpini/common/alpini-common-io/src/test/java/com/linkedin/alpini/io/TestIOUtils.java b/internal/alpini/common/alpini-common-io/src/test/java/com/linkedin/alpini/io/TestIOUtils.java deleted file mode 100644 index 24fcd3c702b..00000000000 --- a/internal/alpini/common/alpini-common-io/src/test/java/com/linkedin/alpini/io/TestIOUtils.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.linkedin.alpini.io; - -import com.linkedin.alpini.base.misc.Time; -import java.io.ByteArrayInputStream; -import java.io.Closeable; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.Random; -import org.mockito.Mockito; -import org.testng.Assert; -import org.testng.annotations.Test; - - -/** - * Created by acurtis on 5/15/17. - */ -public class TestIOUtils { - - // private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(IOUtils.class); - @Test(groups = "unit") - public void testCloseQuietly() throws IOException { - // org.apache.log4j.Appender appender = Mockito.mock(org.apache.log4j.Appender.class); - try { - // LOG.addAppender(appender); - - Throwable ex = new IOException(); - - Closeable stream = Mockito.mock(Closeable.class); - Mockito.doThrow(ex).when(stream).close(); - - IOUtils.closeQuietly(stream); - - Mockito.verify(stream).close(); - - // ArgumentCaptor eventArgumentCaptor = - // ArgumentCaptor.forClass(org.apache.log4j.spi.LoggingEvent.class); - // Mockito.verify(appender).doAppend(eventArgumentCaptor.capture()); - - // org.apache.log4j.spi.LoggingEvent event = eventArgumentCaptor.getValue(); - // Assert.assertSame(event.getThrowableInformation().getThrowable(), ex); - - Mockito.verifyNoMoreInteractions(stream); - // Mockito.verifyNoMoreInteractions(stream, appender); - } finally { - // LOG.removeAppender(appender); - } - } - - @Test(groups = "unit") - public void testToByteArray() throws IOException { - Random rnd = new Random(Time.nanoTime()); - byte[] source = new byte[10000]; - rnd.nextBytes(source); - byte[] bytes = IOUtils.toByteArray(new ByteArrayInputStream(source)); - Assert.assertNotSame(bytes, source); - Assert.assertEquals(bytes, source); - } - - @Test(groups = "unit") - public void testToString() throws IOException { - StringBuilder sb = new StringBuilder(11000); - while (sb.length() < 10000) { - sb.append("The quick brown fox jumps over the lazy dog"); - } - String source = sb.toString(); - String output = IOUtils - .toString(new ByteArrayInputStream(source.getBytes(StandardCharsets.US_ASCII)), StandardCharsets.US_ASCII); - Assert.assertNotSame(output, source); - Assert.assertEquals(output, source); - } -} diff --git a/internal/alpini/common/alpini-common-io/src/test/java/com/linkedin/alpini/io/TestNullOutputStream.java b/internal/alpini/common/alpini-common-io/src/test/java/com/linkedin/alpini/io/TestNullOutputStream.java deleted file mode 100644 index 7eef30c5ce2..00000000000 --- a/internal/alpini/common/alpini-common-io/src/test/java/com/linkedin/alpini/io/TestNullOutputStream.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.linkedin.alpini.io; - -import java.io.IOException; -import org.testng.Assert; -import org.testng.annotations.Test; - - -/** - * Created by acurtis on 1/24/18. - */ -public class TestNullOutputStream { - @Test(groups = "unit") - public void testBasic() throws IOException { - NullOutputStream ns = new NullOutputStream(); - MeteredOutputStream ms = new MeteredOutputStream(ns); - - ms.write(1); - Assert.assertEquals(ns.getBytesWritten(), 1); - Assert.assertEquals(ms.getBytesWritten(), 1); - - ms.write(new byte[50]); - Assert.assertEquals(ns.getBytesWritten(), 51); - Assert.assertEquals(ms.getBytesWritten(), 51); - - ms.write(new byte[100], 0, 42); - Assert.assertEquals(ns.getBytesWritten(), 93); - Assert.assertEquals(ms.getBytesWritten(), 93); - } -} diff --git a/internal/alpini/common/alpini-common-io/src/test/java/com/linkedin/alpini/io/TestPigzOutputStream.java b/internal/alpini/common/alpini-common-io/src/test/java/com/linkedin/alpini/io/TestPigzOutputStream.java deleted file mode 100644 index 5b7f80382fa..00000000000 --- a/internal/alpini/common/alpini-common-io/src/test/java/com/linkedin/alpini/io/TestPigzOutputStream.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.linkedin.alpini.io; - -import com.linkedin.alpini.base.concurrency.ExecutorService; -import com.linkedin.alpini.base.concurrency.Executors; -import java.io.IOException; -import java.io.InputStream; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Callable; -import java.util.concurrent.Future; -import java.util.zip.CRC32; -import java.util.zip.GZIPInputStream; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - - -/** - * @author Antony T Curtis - */ -public class TestPigzOutputStream { - private static final Logger LOG = LogManager.getLogger(TestPigzOutputStream.class); - - private ExecutorService _executor; - - @BeforeClass(groups = { "unit", "functional" }) - public void beforeClass() { - _executor = Executors.newCachedThreadPool(); - } - - @AfterClass(groups = { "unit", "functional" }, alwaysRun = true) - public void afterClass() { - _executor.shutdown(); - } - - @DataProvider - public Object[][] concurrencyGenerator() { - int availableProcessors = Runtime.getRuntime().availableProcessors(); - availableProcessors = Math.min(6, Math.max(2, availableProcessors / 2)); - List result = new ArrayList(); - for (int concurrency = 1; concurrency <= availableProcessors; concurrency++) - result.add(new Object[] { 9, concurrency }); - for (int concurrency = 1; concurrency <= availableProcessors; concurrency++) - result.add(new Object[] { 6, concurrency }); - for (int concurrency = 1; concurrency <= availableProcessors; concurrency++) - result.add(new Object[] { 1, concurrency }); - return result.toArray(new Object[result.size()][]); - } - - @Test(groups = { "functional" }, singleThreaded = true, dataProvider = "concurrencyGenerator", enabled = false) - public void testPigzToNullConcurrency(int compressionLevel, int numberOfThreads) throws IOException { - long start = System.nanoTime(); - PigzOutputStream os = new PigzOutputStream(compressionLevel, _executor, numberOfThreads, new NullOutputStream()); - for (int i = 0; i < 10000000; i++) { - os.write(("Hello world " + i).getBytes()); - } - os.close(); - - double seconds = (System.nanoTime() - start) / 1000000000.0; - LOG.info( - String.format( - "CompressionLevel %d Threads=%d took %.3f seconds to %d bytes at %.3f KB/s\n", - compressionLevel, - numberOfThreads, - seconds, - os.getBytesWritten(), - os.getBytesCompressed() / (1024.0 * seconds))); - } - - @Test(groups = { "unit" }, singleThreaded = true, dataProvider = "concurrencyGenerator") - public void testPigzToDecompressConcurrency(int compressionLevel, int numberOfThreads) throws Exception { - final PipedInputStream pis = new PipedInputStream(); - PigzOutputStream os = - new PigzOutputStream(compressionLevel, _executor, numberOfThreads, new PipedOutputStream(pis)); - - Future check = _executor.submit(new Callable() { - private final InputStream is = new GZIPInputStream(pis); - private final CRC32 crc = new CRC32(); - private final byte[] buffer = new byte[1024]; - - @Override - public Long call() throws Exception { - for (;;) { - int read = is.read(buffer); - if (read == -1) - break; - crc.update(buffer, 0, read); - } - is.close(); - return crc.getValue(); - } - }); - - CRC32 crc = new CRC32(); - for (int i = 0; i < 10000; i++) { - byte[] bytes = ("Hello world " + i).getBytes(); - crc.update(bytes); - os.write(bytes); - } - os.close(); - Assert.assertEquals((long) check.get(), crc.getValue()); - } -} diff --git a/internal/alpini/common/alpini-common-io/src/test/java/com/linkedin/alpini/io/TestZeroInputStream.java b/internal/alpini/common/alpini-common-io/src/test/java/com/linkedin/alpini/io/TestZeroInputStream.java deleted file mode 100644 index 4f032717429..00000000000 --- a/internal/alpini/common/alpini-common-io/src/test/java/com/linkedin/alpini/io/TestZeroInputStream.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.linkedin.alpini.io; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import org.testng.Assert; -import org.testng.annotations.Test; - - -/** - * Created by acurtis on 1/24/18. - */ -public class TestZeroInputStream { - @Test(groups = "unit") - public void testBasic() throws IOException { - ZeroInputStream is = new ZeroInputStream(11235); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - - Assert.assertEquals(is.getBytesRemaining(), 11235L); - Assert.assertEquals(is.available(), 11235); - - Assert.assertEquals(is.read(), 0); - - IOUtils.copy(is, os); - byte[] bytes = os.toByteArray(); - - Assert.assertEquals(bytes.length, 11234); - Assert.assertEquals(is.getBytesRemaining(), 0L); - Assert.assertEquals(is.available(), 0); - Assert.assertEquals(is.read(), -1); - - for (byte b: bytes) { - Assert.assertEquals(b, 0); - } - } - - @Test(groups = "unit") - public void testSkip() throws IOException { - long big = Integer.MAX_VALUE + 11235L; - - ZeroInputStream is = new ZeroInputStream(big); - - Assert.assertEquals(is.getBytesRemaining(), big); - Assert.assertEquals(is.available(), Integer.MAX_VALUE); - - Assert.assertEquals(is.skip(Integer.MAX_VALUE / 2), Integer.MAX_VALUE / 2); - - Assert.assertEquals(is.getBytesRemaining(), big - Integer.MAX_VALUE / 2); - Assert.assertEquals(is.available(), Integer.MAX_VALUE / 2 + 11235 + 1); - - Assert.assertEquals(is.skip(Integer.MAX_VALUE), Integer.MAX_VALUE / 2 + 11235 + 1); - - Assert.assertEquals(is.getBytesRemaining(), 0L); - Assert.assertEquals(is.available(), 0); - } - - @Test(groups = "unit", expectedExceptions = IllegalArgumentException.class) - public void testBadSkip() throws IOException { - - ZeroInputStream is = new ZeroInputStream(1); - - is.skip(-1); - } - - @Test(groups = "unit", expectedExceptions = ArrayIndexOutOfBoundsException.class) - public void testBadRead1() throws IOException { - - ZeroInputStream is = new ZeroInputStream(1); - - is.read(new byte[1], -1, 0); - } - - @Test(groups = "unit", expectedExceptions = ArrayIndexOutOfBoundsException.class) - public void testBadRead2() throws IOException { - - ZeroInputStream is = new ZeroInputStream(1); - - is.read(new byte[1], 0, -1); - } - -} diff --git a/internal/alpini/common/alpini-common-log/build.gradle b/internal/alpini/common/alpini-common-log/build.gradle deleted file mode 100644 index 5e1cce0043f..00000000000 --- a/internal/alpini/common/alpini-common-log/build.gradle +++ /dev/null @@ -1,10 +0,0 @@ -dependencies { - testImplementation libraries.testng - implementation libraries.log4j2api - compileOnly libraries.jsr305 - //implementation project(':internal:alpini:common:alpini-common-base') - //testImplementation spec.external.'mockito-all' - //testImplementation libraries.testng -} - - diff --git a/internal/alpini/common/alpini-common-log/src/main/java/com/linkedin/alpini/log/FastLog.java b/internal/alpini/common/alpini-common-log/src/main/java/com/linkedin/alpini/log/FastLog.java deleted file mode 100644 index f995590f8fd..00000000000 --- a/internal/alpini/common/alpini-common-log/src/main/java/com/linkedin/alpini/log/FastLog.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.linkedin.alpini.log; - -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; - - -public class FastLog implements FastLogMBean { - private static final AtomicReferenceFieldUpdater DEBUG_UPDATER = - AtomicReferenceFieldUpdater.newUpdater(FastLog.class, Boolean.class, "_debugEnabled"); - - private static final AtomicReferenceFieldUpdater TRACE_UPDATER = - AtomicReferenceFieldUpdater.newUpdater(FastLog.class, Boolean.class, "_traceEnabled"); - - private volatile Boolean _debugEnabled = false; - private volatile Boolean _traceEnabled = false; - - public boolean isDebugEnabled() { - return _debugEnabled; - } - - public boolean isTraceEnabled() { - return _traceEnabled; - } - - @Override - public void setDebug(boolean enabled) { - DEBUG_UPDATER.lazySet(this, enabled); - } - - @Override - public void setTrace(boolean enabled) { - TRACE_UPDATER.lazySet(this, enabled); - } -} diff --git a/internal/alpini/common/alpini-common-log/src/main/java/com/linkedin/alpini/log/FastLogContext.java b/internal/alpini/common/alpini-common-log/src/main/java/com/linkedin/alpini/log/FastLogContext.java deleted file mode 100644 index c3666e6388a..00000000000 --- a/internal/alpini/common/alpini-common-log/src/main/java/com/linkedin/alpini/log/FastLogContext.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.linkedin.alpini.log; - -import java.lang.ref.Reference; -import java.lang.ref.WeakReference; -import java.util.Map; -import java.util.WeakHashMap; -import javax.annotation.Nonnull; -import org.apache.logging.log4j.message.MessageFactory; -import org.apache.logging.log4j.spi.ExtendedLogger; -import org.apache.logging.log4j.spi.LoggerContext; - - -public final class FastLogContext implements LoggerContext { - private static final ThreadLocal>>> MAP = - ThreadLocal.withInitial(WeakHashMap::new); - - private final FastLogMBean _fastLog; - private final LoggerContext _context; - - public FastLogContext(@Nonnull FastLogMBean fastLog, @Nonnull LoggerContext context) { - _fastLog = fastLog; - _context = context; - } - - public FastLogMBean getManagementMBean() { - return _fastLog; - } - - LoggerContext internalContext() { - return _context; - } - - @Override - public Object getExternalContext() { - return _context.getExternalContext(); - } - - @Override - public FastLogger getLogger(String name) { - return getLogger(_context.getLogger(name)); - } - - @Override - public FastLogger getLogger(String name, MessageFactory messageFactory) { - return getLogger(_context.getLogger(name, messageFactory)); - } - - private Map> contextMap() { - return MAP.get().computeIfAbsent(this, FastLogContext::newContextMap); - } - - private static Map> newContextMap(FastLogContext fastLogContext) { - return new WeakHashMap<>(); - } - - private FastLogger getLogger(ExtendedLogger logger) { - if (logger == null) { - return null; - } - Map> map = contextMap(); - FastLogger result; - do { - result = map.compute(logger, this::computeLogger).get(); - } while (result == null); - return result; - } - - private Reference computeLogger(@Nonnull ExtendedLogger logger, Reference ref) { - if (ref == null || ref.get() == null) { - ref = new WeakReference<>(new FastLogger(this, logger)); - } - return ref; - } - - @Override - public boolean hasLogger(String name) { - return _context.hasLogger(name); - } - - @Override - public boolean hasLogger(String name, MessageFactory messageFactory) { - return _context.hasLogger(name, messageFactory); - } - - @Override - public boolean hasLogger(String name, Class messageFactoryClass) { - return _context.hasLogger(name, messageFactoryClass); - } - - public boolean isDebugEnabled() { - return _fastLog.isDebugEnabled(); - } - - public boolean isTraceEnabled() { - return _fastLog.isTraceEnabled(); - } -} diff --git a/internal/alpini/common/alpini-common-log/src/main/java/com/linkedin/alpini/log/FastLogContextFactory.java b/internal/alpini/common/alpini-common-log/src/main/java/com/linkedin/alpini/log/FastLogContextFactory.java deleted file mode 100644 index c32ffb4ad1d..00000000000 --- a/internal/alpini/common/alpini-common-log/src/main/java/com/linkedin/alpini/log/FastLogContextFactory.java +++ /dev/null @@ -1,184 +0,0 @@ -package com.linkedin.alpini.log; - -import java.lang.management.ManagementFactory; -import java.lang.ref.Reference; -import java.lang.ref.WeakReference; -import java.net.URI; -import java.util.IdentityHashMap; -import java.util.Map; -import java.util.SortedMap; -import java.util.TreeMap; -import java.util.WeakHashMap; -import javax.annotation.Nonnull; -import javax.management.MBeanServer; -import javax.management.ObjectName; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.simple.SimpleLoggerContextFactory; -import org.apache.logging.log4j.spi.LoggerContext; -import org.apache.logging.log4j.spi.LoggerContextFactory; -import org.apache.logging.log4j.spi.Provider; -import org.apache.logging.log4j.status.StatusLogger; -import org.apache.logging.log4j.util.ProviderUtil; - - -/** - * An alternate Log4j2 {@link LoggerContextFactory} implementation which returns loggers which can - * short-circuit debug and trace messages so that they may be disabled without incurring cost from - * filters installed within Log4j. - * - * This may be installed by specifying - * -Dlog4j2.loggerContextFactory=com.linkedin.alpini.log.FastLogContextFactory - * - * It should install a management mbean {@literal com.linkedin.alpini.log:type=FastLog} which will - * allow enabling DEBUG/TRACE propagation. - */ -public final class FastLogContextFactory implements LoggerContextFactory { - private static final Logger LOGGER = StatusLogger.getLogger(); - - private static final ThreadLocal>>> MAP = - ThreadLocal.withInitial(WeakHashMap::new); - - private volatile LoggerContextFactory _factory; - private final Map _map = new IdentityHashMap<>(); - private FastLog _fastLog; - - public FastLogContextFactory(@Nonnull LoggerContextFactory factory) { - _factory = factory; - } - - public FastLogContextFactory() { - this(defaultContextFactory()); - } - - private static LoggerContextFactory defaultContextFactory() { - LoggerContextFactory factory; - final SortedMap factories = new TreeMap<>(); - // note that the following initial call to ProviderUtil may block until a Provider has been installed when - // running in an OSGi environment - if (ProviderUtil.hasProviders()) { - for (final Provider provider: ProviderUtil.getProviders()) { - final Class factoryClass = provider.loadLoggerContextFactory(); - if (factoryClass != null && !FastLogContextFactory.class.isAssignableFrom(factoryClass)) { - try { - factories.put(provider.getPriority(), factoryClass.newInstance()); - } catch (final Exception e) { - LOGGER.error( - "Unable to create class {} specified in provider URL {}", - factoryClass.getName(), - provider.getUrl(), - e); - } - } - } - - if (factories.isEmpty()) { - LOGGER.error( - "Log4j2 could not find a logging implementation. " - + "Please add log4j-core to the classpath. Using SimpleLogger to log to the console..."); - factory = new SimpleLoggerContextFactory(); - } else if (factories.size() == 1) { - factory = factories.get(factories.lastKey()); - } else { - final StringBuilder sb = new StringBuilder("Multiple logging implementations found: \n"); - for (final Map.Entry entry: factories.entrySet()) { - sb.append("Factory: ").append(entry.getValue().getClass().getName()); - sb.append(", Weighting: ").append(entry.getKey()).append('\n'); - } - factory = factories.get(factories.lastKey()); - sb.append("Using factory: ").append(factory.getClass().getName()); - LOGGER.warn(sb.toString()); - - } - } else { - LOGGER.error( - "Log4j2 could not find a logging implementation. " - + "Please add log4j-core to the classpath. Using SimpleLogger to log to the console..."); - factory = new SimpleLoggerContextFactory(); - } - return factory; - } - - public FastLogMBean getManagementMBean() { - return _fastLog; - } - - private static Map> newContextMap(@Nonnull FastLogContextFactory factory) { - return new WeakHashMap<>(); - } - - private Map> contextMap() { - return MAP.get().computeIfAbsent(this, FastLogContextFactory::newContextMap); - } - - private synchronized FastLogContext getLogContext(@Nonnull LoggerContext context) { - return _map.computeIfAbsent(context, this::makeLogContext); - } - - private synchronized boolean removeLogContext(@Nonnull LoggerContext context) { - return _map.remove(context) != null; - } - - private FastLogContext makeLogContext(@Nonnull LoggerContext context) { - if (_fastLog == null) { - try { - MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); - ObjectName name = new ObjectName("com.linkedin.alpini.log:type=FastLog"); - if (mbs.isRegistered(name)) { - LOGGER.info("unregistering previous instance of FastLog mbean"); - mbs.unregisterMBean(name); - } - _fastLog = new FastLog(); - mbs.registerMBean(_fastLog, name); - } catch (Exception ex) { - LOGGER.error("Error registering mbean", ex); - } - } - return new FastLogContext(getManagementMBean(), context); - } - - private FastLogContext getContext(LoggerContext context) { - if (context == null) { - return null; - } - Map> map = contextMap(); - FastLogContext result; - do { - result = map.compute(context, this::computeReference).get(); - } while (result == null); - return result; - } - - private Reference computeReference(LoggerContext context, Reference ref) { - if (ref == null || ref.get() == null) { - ref = new WeakReference<>(getLogContext(context)); - } - return ref; - } - - @Override - public LoggerContext getContext(String fqcn, ClassLoader loader, Object externalContext, boolean currentContext) { - return getContext(_factory.getContext(fqcn, loader, externalContext, currentContext)); - } - - @Override - public LoggerContext getContext( - String fqcn, - ClassLoader loader, - Object externalContext, - boolean currentContext, - URI configLocation, - String name) { - return getContext(_factory.getContext(fqcn, loader, externalContext, currentContext, configLocation, name)); - } - - @Override - public void removeContext(LoggerContext context) { - if (context instanceof FastLogContext) { - removeContext(((FastLogContext) context).internalContext()); - } else { - if (removeLogContext(context)) { - _factory.removeContext(context); - } - } - } -} diff --git a/internal/alpini/common/alpini-common-log/src/main/java/com/linkedin/alpini/log/FastLogMBean.java b/internal/alpini/common/alpini-common-log/src/main/java/com/linkedin/alpini/log/FastLogMBean.java deleted file mode 100644 index d4fb946f125..00000000000 --- a/internal/alpini/common/alpini-common-log/src/main/java/com/linkedin/alpini/log/FastLogMBean.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.linkedin.alpini.log; - -public interface FastLogMBean { - boolean isDebugEnabled(); - - boolean isTraceEnabled(); - - void setDebug(boolean enabled); - - void setTrace(boolean enabled); -} diff --git a/internal/alpini/common/alpini-common-log/src/main/java/com/linkedin/alpini/log/FastLogger.java b/internal/alpini/common/alpini-common-log/src/main/java/com/linkedin/alpini/log/FastLogger.java deleted file mode 100644 index 62056105d20..00000000000 --- a/internal/alpini/common/alpini-common-log/src/main/java/com/linkedin/alpini/log/FastLogger.java +++ /dev/null @@ -1,3194 +0,0 @@ -package com.linkedin.alpini.log; - -import javax.annotation.Nonnull; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.Marker; -import org.apache.logging.log4j.message.EntryMessage; -import org.apache.logging.log4j.message.Message; -import org.apache.logging.log4j.message.MessageFactory; -import org.apache.logging.log4j.spi.ExtendedLogger; -import org.apache.logging.log4j.util.MessageSupplier; -import org.apache.logging.log4j.util.Supplier; - - -public final class FastLogger implements ExtendedLogger { - private final FastLogContext _context; - private final ExtendedLogger _logger; - - public FastLogger(@Nonnull FastLogContext context, @Nonnull ExtendedLogger logger) { - _context = context; - _logger = logger; - } - - public FastLogMBean getManagementMBean() { - return _context.getManagementMBean(); - } - - @Override - public void catching(Level level, Throwable t) { - if (maybeEnabled(level)) { - _logger.catching(level, t); - } - } - - @Override - public void catching(Throwable t) { - if (_context.isTraceEnabled()) { - _logger.catching(t); - } - } - - @Override - public void debug(Marker marker, Message msg) { - if (logMsg(msg) && _context.isDebugEnabled()) { - _logger.debug(marker, msg); - } - } - - @Override - public void debug(Marker marker, Message msg, Throwable t) { - if (logMsg(msg) && _context.isDebugEnabled()) { - _logger.debug(marker, msg, t); - } - } - - @Override - public void debug(Marker marker, MessageSupplier msgSupplier) { - if (_context.isDebugEnabled()) { - _logger.debug(marker, msgSupplier); - } - } - - @Override - public void debug(Marker marker, MessageSupplier msgSupplier, Throwable t) { - if (_context.isDebugEnabled()) { - _logger.debug(marker, msgSupplier, t); - } - } - - @Override - public void debug(Marker marker, CharSequence message) { - if (_context.isDebugEnabled()) { - _logger.debug(marker, message); - } - } - - @Override - public void debug(Marker marker, CharSequence message, Throwable t) { - if (_context.isDebugEnabled()) { - _logger.debug(marker, message, t); - } - } - - @Override - public void debug(Marker marker, Object message) { - if (_context.isDebugEnabled()) { - _logger.debug(marker, message); - } - } - - @Override - public void debug(Marker marker, Object message, Throwable t) { - if (_context.isDebugEnabled()) { - _logger.debug(marker, message, t); - } - } - - @Override - public void debug(Marker marker, String message) { - if (_context.isDebugEnabled()) { - _logger.debug(marker, message); - } - } - - @Override - public void debug(Marker marker, String message, Object... params) { - if (_context.isDebugEnabled()) { - _logger.debug(marker, message, params); - } - } - - @Override - public void debug(Marker marker, String message, Supplier... paramSuppliers) { - if (_context.isDebugEnabled()) { - _logger.debug(marker, message, paramSuppliers); - } - } - - @Override - public void debug(Marker marker, String message, Throwable t) { - if (_context.isDebugEnabled()) { - _logger.debug(marker, message, t); - } - } - - @Override - public void debug(Marker marker, Supplier msgSupplier) { - if (_context.isDebugEnabled()) { - _logger.debug(marker, msgSupplier); - } - } - - @Override - public void debug(Marker marker, Supplier msgSupplier, Throwable t) { - if (_context.isDebugEnabled()) { - _logger.debug(marker, msgSupplier, t); - } - } - - @Override - public void debug(Message msg) { - if (logMsg(msg) && _context.isDebugEnabled()) { - _logger.debug(msg); - } - } - - @Override - public void debug(Message msg, Throwable t) { - if (logMsg(msg) && _context.isDebugEnabled()) { - _logger.debug(msg, t); - } - } - - @Override - public void debug(MessageSupplier msgSupplier) { - if (_context.isDebugEnabled()) { - _logger.debug(msgSupplier); - } - } - - @Override - public void debug(MessageSupplier msgSupplier, Throwable t) { - if (_context.isDebugEnabled()) { - _logger.debug(msgSupplier, t); - } - } - - @Override - public void debug(CharSequence message) { - if (_context.isDebugEnabled()) { - _logger.debug(message); - } - } - - @Override - public void debug(CharSequence message, Throwable t) { - if (_context.isDebugEnabled()) { - _logger.debug(message, t); - } - } - - @Override - public void debug(Object message) { - if (_context.isDebugEnabled()) { - _logger.debug(message); - } - } - - @Override - public void debug(Object message, Throwable t) { - if (_context.isDebugEnabled()) { - _logger.debug(message, t); - } - } - - @Override - public void debug(String message) { - if (_context.isDebugEnabled()) { - _logger.debug(message); - } - } - - @Override - public void debug(String message, Object... params) { - if (_context.isDebugEnabled()) { - _logger.debug(message, params); - } - } - - @Override - public void debug(String message, Supplier... paramSuppliers) { - if (_context.isDebugEnabled()) { - _logger.debug(message, paramSuppliers); - } - } - - @Override - public void debug(String message, Throwable t) { - if (_context.isDebugEnabled()) { - _logger.debug(message, t); - } - } - - @Override - public void debug(Supplier msgSupplier) { - if (_context.isDebugEnabled()) { - _logger.debug(msgSupplier); - } - } - - @Override - public void debug(Supplier msgSupplier, Throwable t) { - if (_context.isDebugEnabled()) { - _logger.debug(msgSupplier, t); - } - } - - @Override - public void debug(Marker marker, String message, Object p0) { - if (_context.isDebugEnabled()) { - _logger.debug(marker, message, p0); - } - } - - @Override - public void debug(Marker marker, String message, Object p0, Object p1) { - if (_context.isDebugEnabled()) { - _logger.debug(marker, message, p0, p1); - } - } - - @Override - public void debug(Marker marker, String message, Object p0, Object p1, Object p2) { - if (_context.isDebugEnabled()) { - _logger.debug(marker, message, p0, p1, p2); - } - } - - @Override - public void debug(Marker marker, String message, Object p0, Object p1, Object p2, Object p3) { - if (_context.isDebugEnabled()) { - _logger.debug(marker, message, p0, p1, p2, p3); - } - } - - @Override - public void debug(Marker marker, String message, Object p0, Object p1, Object p2, Object p3, Object p4) { - if (_context.isDebugEnabled()) { - _logger.debug(marker, message, p0, p1, p2, p3, p4); - } - } - - @Override - public void debug(Marker marker, String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5) { - if (_context.isDebugEnabled()) { - _logger.debug(marker, message, p0, p1, p2, p3, p4, p5); - } - } - - @Override - public void debug( - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6) { - if (_context.isDebugEnabled()) { - _logger.debug(marker, message, p0, p1, p2, p3, p4, p5, p6); - } - } - - @Override - public void debug( - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7) { - if (_context.isDebugEnabled()) { - _logger.debug(marker, message, p0, p1, p2, p3, p4, p5, p6, p7); - } - } - - @Override - public void debug( - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8) { - if (_context.isDebugEnabled()) { - _logger.debug(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - } - } - - @Override - public void debug( - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8, - Object p9) { - if (_context.isDebugEnabled()) { - _logger.debug(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - } - } - - @Override - public void debug(String message, Object p0) { - if (_context.isDebugEnabled()) { - _logger.debug(message, p0); - } - } - - @Override - public void debug(String message, Object p0, Object p1) { - if (_context.isDebugEnabled()) { - _logger.debug(message, p0, p1); - } - } - - @Override - public void debug(String message, Object p0, Object p1, Object p2) { - if (_context.isDebugEnabled()) { - _logger.debug(message, p0, p1, p2); - } - } - - @Override - public void debug(String message, Object p0, Object p1, Object p2, Object p3) { - if (_context.isDebugEnabled()) { - _logger.debug(message, p0, p1, p2, p3); - } - } - - @Override - public void debug(String message, Object p0, Object p1, Object p2, Object p3, Object p4) { - if (_context.isDebugEnabled()) { - _logger.debug(message, p0, p1, p2, p3, p4); - } - } - - @Override - public void debug(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5) { - if (_context.isDebugEnabled()) { - _logger.debug(message, p0, p1, p2, p3, p4, p5); - } - } - - @Override - public void debug(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6) { - if (_context.isDebugEnabled()) { - _logger.debug(message, p0, p1, p2, p3, p4, p5, p6); - } - } - - @Override - public void debug( - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7) { - if (_context.isDebugEnabled()) { - _logger.debug(message, p0, p1, p2, p3, p4, p5, p6, p7); - } - } - - @Override - public void debug( - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8) { - if (_context.isDebugEnabled()) { - _logger.debug(message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - } - } - - @Override - public void debug( - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8, - Object p9) { - if (_context.isDebugEnabled()) { - _logger.debug(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - } - } - - @Override - public void entry() { - if (_context.isTraceEnabled()) { - _logger.entry(); - } - } - - @Override - public void entry(Object... params) { - if (_context.isTraceEnabled()) { - _logger.entry(params); - } - } - - @Override - public void error(Marker marker, Message msg) { - if (logMsg(msg)) { - _logger.error(marker, msg); - } - } - - @Override - public void error(Marker marker, Message msg, Throwable t) { - if (logMsg(msg)) { - _logger.error(marker, msg, t); - } - } - - @Override - public void error(Marker marker, MessageSupplier msgSupplier) { - _logger.error(marker, msgSupplier); - } - - @Override - public void error(Marker marker, MessageSupplier msgSupplier, Throwable t) { - _logger.error(marker, msgSupplier, t); - } - - @Override - public void error(Marker marker, CharSequence message) { - _logger.error(marker, message); - } - - @Override - public void error(Marker marker, CharSequence message, Throwable t) { - _logger.error(marker, message, t); - } - - @Override - public void error(Marker marker, Object message) { - _logger.error(marker, message); - } - - @Override - public void error(Marker marker, Object message, Throwable t) { - _logger.error(marker, message, t); - } - - @Override - public void error(Marker marker, String message) { - _logger.error(marker, message); - } - - @Override - public void error(Marker marker, String message, Object... params) { - _logger.error(marker, message, params); - } - - @Override - public void error(Marker marker, String message, Supplier... paramSuppliers) { - _logger.error(marker, message, paramSuppliers); - } - - @Override - public void error(Marker marker, String message, Throwable t) { - _logger.error(marker, message, t); - } - - @Override - public void error(Marker marker, Supplier msgSupplier) { - _logger.error(marker, msgSupplier); - } - - @Override - public void error(Marker marker, Supplier msgSupplier, Throwable t) { - _logger.error(marker, msgSupplier, t); - } - - @Override - public void error(Message msg) { - _logger.error(msg); - } - - @Override - public void error(Message msg, Throwable t) { - _logger.error(msg, t); - } - - @Override - public void error(MessageSupplier msgSupplier) { - _logger.error(msgSupplier); - } - - @Override - public void error(MessageSupplier msgSupplier, Throwable t) { - _logger.error(msgSupplier, t); - } - - @Override - public void error(CharSequence message) { - _logger.error(message); - } - - @Override - public void error(CharSequence message, Throwable t) { - _logger.error(message, t); - } - - @Override - public void error(Object message) { - _logger.error(message); - } - - @Override - public void error(Object message, Throwable t) { - _logger.error(message, t); - } - - @Override - public void error(String message) { - _logger.error(message); - } - - @Override - public void error(String message, Object... params) { - _logger.error(message, params); - } - - @Override - public void error(String message, Supplier... paramSuppliers) { - _logger.error(message, paramSuppliers); - } - - @Override - public void error(String message, Throwable t) { - _logger.error(message, t); - } - - @Override - public void error(Supplier msgSupplier) { - _logger.error(msgSupplier); - } - - @Override - public void error(Supplier msgSupplier, Throwable t) { - _logger.error(msgSupplier, t); - } - - @Override - public void error(Marker marker, String message, Object p0) { - _logger.error(marker, message, p0); - } - - @Override - public void error(Marker marker, String message, Object p0, Object p1) { - _logger.error(marker, message, p0, p1); - } - - @Override - public void error(Marker marker, String message, Object p0, Object p1, Object p2) { - _logger.error(marker, message, p0, p1, p2); - } - - @Override - public void error(Marker marker, String message, Object p0, Object p1, Object p2, Object p3) { - _logger.error(marker, message, p0, p1, p2, p3); - } - - @Override - public void error(Marker marker, String message, Object p0, Object p1, Object p2, Object p3, Object p4) { - _logger.error(marker, message, p0, p1, p2, p3, p4); - } - - @Override - public void error(Marker marker, String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5) { - _logger.error(marker, message, p0, p1, p2, p3, p4, p5); - } - - @Override - public void error( - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6) { - _logger.error(marker, message, p0, p1, p2, p3, p4, p5, p6); - } - - @Override - public void error( - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7) { - _logger.error(marker, message, p0, p1, p2, p3, p4, p5, p6, p7); - } - - @Override - public void error( - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8) { - _logger.error(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - } - - @Override - public void error( - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8, - Object p9) { - _logger.error(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - } - - @Override - public void error(String message, Object p0) { - _logger.error(message, p0); - } - - @Override - public void error(String message, Object p0, Object p1) { - _logger.error(message, p0, p1); - } - - @Override - public void error(String message, Object p0, Object p1, Object p2) { - _logger.error(message, p0, p1, p2); - } - - @Override - public void error(String message, Object p0, Object p1, Object p2, Object p3) { - _logger.error(message, p0, p1, p2, p3); - } - - @Override - public void error(String message, Object p0, Object p1, Object p2, Object p3, Object p4) { - _logger.error(message, p0, p1, p2, p3, p4); - } - - @Override - public void error(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5) { - _logger.error(message, p0, p1, p2, p3, p4, p5); - } - - @Override - public void error(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6) { - _logger.error(message, p0, p1, p2, p3, p4, p5, p6); - } - - @Override - public void error( - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7) { - _logger.error(message, p0, p1, p2, p3, p4, p5, p6, p7); - } - - @Override - public void error( - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8) { - _logger.error(message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - } - - @Override - public void error( - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8, - Object p9) { - _logger.error(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - } - - @Override - public void exit() { - if (_context.isTraceEnabled()) { - _logger.exit(); - } - } - - @Override - public R exit(R result) { - if (_context.isTraceEnabled()) { - return _logger.exit(result); - } - return result; - } - - @Override - public void fatal(Marker marker, Message msg) { - if (logMsg(msg)) { - _logger.fatal(marker, msg); - } - } - - @Override - public void fatal(Marker marker, Message msg, Throwable t) { - if (logMsg(msg)) { - _logger.fatal(marker, msg, t); - } - } - - @Override - public void fatal(Marker marker, MessageSupplier msgSupplier) { - _logger.fatal(marker, msgSupplier); - } - - @Override - public void fatal(Marker marker, MessageSupplier msgSupplier, Throwable t) { - _logger.fatal(marker, msgSupplier, t); - } - - @Override - public void fatal(Marker marker, CharSequence message) { - _logger.fatal(marker, message); - } - - @Override - public void fatal(Marker marker, CharSequence message, Throwable t) { - _logger.fatal(marker, message, t); - } - - @Override - public void fatal(Marker marker, Object message) { - _logger.fatal(marker, message); - } - - @Override - public void fatal(Marker marker, Object message, Throwable t) { - _logger.fatal(marker, message, t); - } - - @Override - public void fatal(Marker marker, String message) { - _logger.fatal(marker, message); - } - - @Override - public void fatal(Marker marker, String message, Object... params) { - _logger.fatal(marker, message, params); - } - - @Override - public void fatal(Marker marker, String message, Supplier... paramSuppliers) { - _logger.fatal(marker, message, paramSuppliers); - } - - @Override - public void fatal(Marker marker, String message, Throwable t) { - _logger.fatal(marker, message, t); - } - - @Override - public void fatal(Marker marker, Supplier msgSupplier) { - _logger.fatal(marker, msgSupplier); - } - - @Override - public void fatal(Marker marker, Supplier msgSupplier, Throwable t) { - _logger.fatal(marker, msgSupplier, t); - } - - @Override - public void fatal(Message msg) { - if (logMsg(msg)) { - _logger.fatal(msg); - } - } - - @Override - public void fatal(Message msg, Throwable t) { - if (logMsg(msg)) { - _logger.fatal(msg, t); - } - } - - @Override - public void fatal(MessageSupplier msgSupplier) { - _logger.fatal(msgSupplier); - } - - @Override - public void fatal(MessageSupplier msgSupplier, Throwable t) { - _logger.fatal(msgSupplier, t); - } - - @Override - public void fatal(CharSequence message) { - _logger.fatal(message); - } - - @Override - public void fatal(CharSequence message, Throwable t) { - _logger.fatal(message, t); - } - - @Override - public void fatal(Object message) { - _logger.fatal(message); - } - - @Override - public void fatal(Object message, Throwable t) { - _logger.fatal(message, t); - } - - @Override - public void fatal(String message) { - _logger.fatal(message); - } - - @Override - public void fatal(String message, Object... params) { - _logger.fatal(message, params); - } - - @Override - public void fatal(String message, Supplier... paramSuppliers) { - _logger.fatal(message, paramSuppliers); - } - - @Override - public void fatal(String message, Throwable t) { - _logger.fatal(message, t); - } - - @Override - public void fatal(Supplier msgSupplier) { - _logger.fatal(msgSupplier); - } - - @Override - public void fatal(Supplier msgSupplier, Throwable t) { - _logger.fatal(msgSupplier, t); - } - - @Override - public void fatal(Marker marker, String message, Object p0) { - _logger.fatal(marker, message, p0); - } - - @Override - public void fatal(Marker marker, String message, Object p0, Object p1) { - _logger.fatal(marker, message, p0, p1); - } - - @Override - public void fatal(Marker marker, String message, Object p0, Object p1, Object p2) { - _logger.fatal(marker, message, p0, p1, p2); - } - - @Override - public void fatal(Marker marker, String message, Object p0, Object p1, Object p2, Object p3) { - _logger.fatal(marker, message, p0, p1, p2, p3); - } - - @Override - public void fatal(Marker marker, String message, Object p0, Object p1, Object p2, Object p3, Object p4) { - _logger.fatal(marker, message, p0, p1, p2, p3, p4); - } - - @Override - public void fatal(Marker marker, String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5) { - _logger.fatal(marker, message, p0, p1, p2, p3, p4, p5); - } - - @Override - public void fatal( - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6) { - _logger.fatal(marker, message, p0, p1, p2, p3, p4, p5, p6); - } - - @Override - public void fatal( - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7) { - _logger.fatal(marker, message, p0, p1, p2, p3, p4, p5, p6, p7); - } - - @Override - public void fatal( - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8) { - _logger.fatal(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - } - - @Override - public void fatal( - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8, - Object p9) { - _logger.fatal(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - } - - @Override - public void fatal(String message, Object p0) { - _logger.fatal(message, p0); - } - - @Override - public void fatal(String message, Object p0, Object p1) { - _logger.fatal(message, p0, p1); - } - - @Override - public void fatal(String message, Object p0, Object p1, Object p2) { - _logger.fatal(message, p0, p1, p2); - } - - @Override - public void fatal(String message, Object p0, Object p1, Object p2, Object p3) { - _logger.fatal(message, p0, p1, p2, p3); - } - - @Override - public void fatal(String message, Object p0, Object p1, Object p2, Object p3, Object p4) { - _logger.fatal(message, p0, p1, p2, p3, p4); - } - - @Override - public void fatal(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5) { - _logger.fatal(message, p0, p1, p2, p3, p4, p5); - } - - @Override - public void fatal(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6) { - _logger.fatal(message, p0, p1, p2, p3, p4, p5, p6); - } - - @Override - public void fatal( - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7) { - _logger.fatal(message, p0, p1, p2, p3, p4, p5, p6, p7); - } - - @Override - public void fatal( - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8) { - _logger.fatal(message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - } - - @Override - public void fatal( - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8, - Object p9) { - _logger.fatal(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - } - - @Override - public Level getLevel() { - return _logger.getLevel(); - } - - @Override - public MF getMessageFactory() { - return _logger.getMessageFactory(); - } - - @Override - public String getName() { - return _logger.getName(); - } - - @Override - public void info(Marker marker, Message msg) { - _logger.info(marker, msg); - } - - @Override - public void info(Marker marker, Message msg, Throwable t) { - _logger.info(marker, msg, t); - } - - @Override - public void info(Marker marker, MessageSupplier msgSupplier) { - _logger.info(marker, msgSupplier); - } - - @Override - public void info(Marker marker, MessageSupplier msgSupplier, Throwable t) { - _logger.info(marker, msgSupplier, t); - } - - @Override - public void info(Marker marker, CharSequence message) { - _logger.info(marker, message); - } - - @Override - public void info(Marker marker, CharSequence message, Throwable t) { - _logger.info(marker, message, t); - } - - @Override - public void info(Marker marker, Object message) { - _logger.info(marker, message); - } - - @Override - public void info(Marker marker, Object message, Throwable t) { - _logger.info(marker, message, t); - } - - @Override - public void info(Marker marker, String message) { - _logger.info(marker, message); - } - - @Override - public void info(Marker marker, String message, Object... params) { - _logger.info(marker, message, params); - } - - @Override - public void info(Marker marker, String message, Supplier... paramSuppliers) { - _logger.info(marker, message, paramSuppliers); - } - - @Override - public void info(Marker marker, String message, Throwable t) { - _logger.info(marker, message, t); - } - - @Override - public void info(Marker marker, Supplier msgSupplier) { - _logger.info(marker, msgSupplier); - } - - @Override - public void info(Marker marker, Supplier msgSupplier, Throwable t) { - _logger.info(marker, msgSupplier, t); - } - - @Override - public void info(Message msg) { - if (logMsg(msg)) { - _logger.info(msg); - } - } - - @Override - public void info(Message msg, Throwable t) { - if (logMsg(msg)) { - _logger.info(msg, t); - } - } - - @Override - public void info(MessageSupplier msgSupplier) { - _logger.info(msgSupplier); - } - - @Override - public void info(MessageSupplier msgSupplier, Throwable t) { - _logger.info(msgSupplier, t); - } - - @Override - public void info(CharSequence message) { - _logger.info(message); - } - - @Override - public void info(CharSequence message, Throwable t) { - _logger.info(message, t); - } - - @Override - public void info(Object message) { - _logger.info(message); - } - - @Override - public void info(Object message, Throwable t) { - _logger.info(message, t); - } - - @Override - public void info(String message) { - _logger.info(message); - } - - @Override - public void info(String message, Object... params) { - _logger.info(message, params); - } - - @Override - public void info(String message, Supplier... paramSuppliers) { - _logger.info(message, paramSuppliers); - } - - @Override - public void info(String message, Throwable t) { - _logger.info(message, t); - } - - @Override - public void info(Supplier msgSupplier) { - _logger.info(msgSupplier); - } - - @Override - public void info(Supplier msgSupplier, Throwable t) { - _logger.info(msgSupplier, t); - } - - @Override - public void info(Marker marker, String message, Object p0) { - _logger.info(marker, message, p0); - } - - @Override - public void info(Marker marker, String message, Object p0, Object p1) { - _logger.info(marker, message, p0, p1); - } - - @Override - public void info(Marker marker, String message, Object p0, Object p1, Object p2) { - _logger.info(marker, message, p0, p1, p2); - } - - @Override - public void info(Marker marker, String message, Object p0, Object p1, Object p2, Object p3) { - _logger.info(marker, message, p0, p1, p2, p3); - } - - @Override - public void info(Marker marker, String message, Object p0, Object p1, Object p2, Object p3, Object p4) { - _logger.info(marker, message, p0, p1, p2, p3, p4); - } - - @Override - public void info(Marker marker, String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5) { - _logger.info(marker, message, p0, p1, p2, p3, p4, p5); - } - - @Override - public void info( - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6) { - _logger.info(marker, message, p0, p1, p2, p3, p4, p5, p6); - } - - @Override - public void info( - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7) { - _logger.info(marker, message, p0, p1, p2, p3, p4, p5, p6, p7); - } - - @Override - public void info( - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8) { - _logger.info(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - } - - @Override - public void info( - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8, - Object p9) { - _logger.info(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - } - - @Override - public void info(String message, Object p0) { - _logger.info(message, p0); - } - - @Override - public void info(String message, Object p0, Object p1) { - _logger.info(message, p0, p1); - } - - @Override - public void info(String message, Object p0, Object p1, Object p2) { - _logger.info(message, p0, p1, p2); - } - - @Override - public void info(String message, Object p0, Object p1, Object p2, Object p3) { - _logger.info(message, p0, p1, p2, p3); - } - - @Override - public void info(String message, Object p0, Object p1, Object p2, Object p3, Object p4) { - _logger.info(message, p0, p1, p2, p3, p4); - } - - @Override - public void info(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5) { - _logger.info(message, p0, p1, p2, p3, p4, p5); - } - - @Override - public void info(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6) { - _logger.info(message, p0, p1, p2, p3, p4, p5, p6); - } - - @Override - public void info( - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7) { - _logger.info(message, p0, p1, p2, p3, p4, p5, p6, p7); - } - - @Override - public void info( - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8) { - _logger.info(message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - } - - @Override - public void info( - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8, - Object p9) { - _logger.info(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - } - - @Override - public boolean isDebugEnabled() { - return _context.isDebugEnabled() && _logger.isDebugEnabled(); - } - - @Override - public boolean isDebugEnabled(Marker marker) { - return _context.isDebugEnabled() && _logger.isDebugEnabled(marker); - } - - private boolean maybeEnabled(Level level) { - if (level.isLessSpecificThan(Level.TRACE)) { - return _context.isTraceEnabled(); - } - if (level.isLessSpecificThan(Level.DEBUG)) { - return _context.isDebugEnabled(); - } - return true; - } - - @Override - public boolean isEnabled(Level level) { - return maybeEnabled(level) && _logger.isEnabled(level); - } - - @Override - public boolean isEnabled(Level level, Marker marker) { - return maybeEnabled(level) && _logger.isEnabled(level, marker); - } - - @Override - public boolean isErrorEnabled() { - return _logger.isErrorEnabled(); - } - - @Override - public boolean isErrorEnabled(Marker marker) { - return _logger.isErrorEnabled(marker); - } - - @Override - public boolean isFatalEnabled() { - return _logger.isFatalEnabled(); - } - - @Override - public boolean isFatalEnabled(Marker marker) { - return _logger.isFatalEnabled(marker); - } - - @Override - public boolean isInfoEnabled() { - return _logger.isInfoEnabled(); - } - - @Override - public boolean isInfoEnabled(Marker marker) { - return _logger.isInfoEnabled(marker); - } - - @Override - public boolean isTraceEnabled() { - return _context.isTraceEnabled() && _logger.isTraceEnabled(); - } - - @Override - public boolean isTraceEnabled(Marker marker) { - return _context.isTraceEnabled() && _logger.isTraceEnabled(marker); - } - - @Override - public boolean isWarnEnabled() { - return _logger.isWarnEnabled(); - } - - @Override - public boolean isWarnEnabled(Marker marker) { - return _logger.isWarnEnabled(marker); - } - - @Override - public void log(Level level, Marker marker, Message msg) { - if (logMsg(msg) && maybeEnabled(level)) { - _logger.log(level, marker, msg); - } - } - - @Override - public void log(Level level, Marker marker, Message msg, Throwable t) { - if (logMsg(msg) && maybeEnabled(level)) { - _logger.log(level, marker, msg, t); - } - } - - @Override - public void log(Level level, Marker marker, MessageSupplier msgSupplier) { - if (maybeEnabled(level)) { - _logger.log(level, marker, msgSupplier); - } - } - - @Override - public void log(Level level, Marker marker, MessageSupplier msgSupplier, Throwable t) { - if (maybeEnabled(level)) { - _logger.log(level, marker, msgSupplier, t); - } - } - - @Override - public void log(Level level, Marker marker, CharSequence message) { - if (maybeEnabled(level)) { - _logger.log(level, marker, message); - } - } - - @Override - public void log(Level level, Marker marker, CharSequence message, Throwable t) { - if (maybeEnabled(level)) { - _logger.log(level, marker, message, t); - } - } - - @Override - public void log(Level level, Marker marker, Object message) { - if (maybeEnabled(level)) { - _logger.log(level, marker, message); - } - } - - @Override - public void log(Level level, Marker marker, Object message, Throwable t) { - if (maybeEnabled(level)) { - _logger.log(level, marker, message, t); - } - } - - @Override - public void log(Level level, Marker marker, String message) { - if (maybeEnabled(level)) { - _logger.log(level, marker, message); - } - } - - @Override - public void log(Level level, Marker marker, String message, Object... params) { - if (maybeEnabled(level)) { - _logger.log(level, marker, message, params); - } - } - - @Override - public void log(Level level, Marker marker, String message, Supplier... paramSuppliers) { - if (maybeEnabled(level)) { - _logger.log(level, marker, message, paramSuppliers); - } - } - - @Override - public void log(Level level, Marker marker, String message, Throwable t) { - if (maybeEnabled(level)) { - _logger.log(level, marker, message, t); - } - } - - @Override - public void log(Level level, Marker marker, Supplier msgSupplier) { - if (maybeEnabled(level)) { - _logger.log(level, marker, msgSupplier); - } - } - - @Override - public void log(Level level, Marker marker, Supplier msgSupplier, Throwable t) { - if (maybeEnabled(level)) { - _logger.log(level, marker, msgSupplier, t); - } - } - - @Override - public void log(Level level, Message msg) { - if (logMsg(msg) && maybeEnabled(level)) { - _logger.log(level, msg); - } - } - - @Override - public void log(Level level, Message msg, Throwable t) { - if (logMsg(msg) && maybeEnabled(level)) { - _logger.log(level, msg, t); - } - } - - @Override - public void log(Level level, MessageSupplier msgSupplier) { - if (maybeEnabled(level)) { - _logger.log(level, msgSupplier); - } - } - - @Override - public void log(Level level, MessageSupplier msgSupplier, Throwable t) { - if (maybeEnabled(level)) { - _logger.log(level, msgSupplier, t); - } - } - - @Override - public void log(Level level, CharSequence message) { - if (maybeEnabled(level)) { - _logger.log(level, message); - } - } - - @Override - public void log(Level level, CharSequence message, Throwable t) { - if (maybeEnabled(level)) { - _logger.log(level, message, t); - } - } - - @Override - public void log(Level level, Object message) { - if (maybeEnabled(level)) { - _logger.log(level, message); - } - } - - @Override - public void log(Level level, Object message, Throwable t) { - if (maybeEnabled(level)) { - _logger.log(level, message, t); - } - } - - @Override - public void log(Level level, String message) { - if (maybeEnabled(level)) { - _logger.log(level, message); - } - } - - @Override - public void log(Level level, String message, Object... params) { - if (maybeEnabled(level)) { - _logger.log(level, message, params); - } - } - - @Override - public void log(Level level, String message, Supplier... paramSuppliers) { - if (maybeEnabled(level)) { - _logger.log(level, message, paramSuppliers); - } - } - - @Override - public void log(Level level, String message, Throwable t) { - if (maybeEnabled(level)) { - _logger.log(level, message, t); - } - } - - @Override - public void log(Level level, Supplier msgSupplier) { - if (maybeEnabled(level)) { - _logger.log(level, msgSupplier); - } - } - - @Override - public void log(Level level, Supplier msgSupplier, Throwable t) { - if (maybeEnabled(level)) { - _logger.log(level, msgSupplier, t); - } - } - - @Override - public void log(Level level, Marker marker, String message, Object p0) { - if (maybeEnabled(level)) { - _logger.log(level, marker, message, p0); - } - } - - @Override - public void log(Level level, Marker marker, String message, Object p0, Object p1) { - if (maybeEnabled(level)) { - _logger.log(level, marker, message, p0, p1); - } - } - - @Override - public void log(Level level, Marker marker, String message, Object p0, Object p1, Object p2) { - if (maybeEnabled(level)) { - _logger.log(level, marker, message, p0, p1, p2); - } - } - - @Override - public void log(Level level, Marker marker, String message, Object p0, Object p1, Object p2, Object p3) { - if (maybeEnabled(level)) { - _logger.log(level, marker, message, p0, p1, p2, p3); - } - } - - @Override - public void log(Level level, Marker marker, String message, Object p0, Object p1, Object p2, Object p3, Object p4) { - if (maybeEnabled(level)) { - _logger.log(level, marker, message, p0, p1, p2, p3, p4); - } - } - - @Override - public void log( - Level level, - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5) { - if (maybeEnabled(level)) { - _logger.log(level, marker, message, p0, p1, p2, p3, p4, p5); - } - } - - @Override - public void log( - Level level, - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6) { - if (maybeEnabled(level)) { - _logger.log(level, marker, message, p0, p1, p2, p3, p4, p5, p6); - } - } - - @Override - public void log( - Level level, - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7) { - if (maybeEnabled(level)) { - _logger.log(level, marker, message, p0, p1, p2, p3, p4, p5, p6, p7); - } - } - - @Override - public void log( - Level level, - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8) { - if (maybeEnabled(level)) { - _logger.log(level, marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - } - } - - @Override - public void log( - Level level, - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8, - Object p9) { - if (maybeEnabled(level)) { - _logger.log(level, marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - } - } - - @Override - public void log(Level level, String message, Object p0) { - if (maybeEnabled(level)) { - _logger.log(level, message, p0); - } - } - - @Override - public void log(Level level, String message, Object p0, Object p1) { - if (maybeEnabled(level)) { - _logger.log(level, message, p0, p1); - } - } - - @Override - public void log(Level level, String message, Object p0, Object p1, Object p2) { - if (maybeEnabled(level)) { - _logger.log(level, message, p0, p1, p2); - } - } - - @Override - public void log(Level level, String message, Object p0, Object p1, Object p2, Object p3) { - if (maybeEnabled(level)) { - _logger.log(level, message, p0, p1, p2, p3); - } - } - - @Override - public void log(Level level, String message, Object p0, Object p1, Object p2, Object p3, Object p4) { - if (maybeEnabled(level)) { - _logger.log(level, message, p0, p1, p2, p3, p4); - } - } - - @Override - public void log(Level level, String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5) { - if (maybeEnabled(level)) { - _logger.log(level, message, p0, p1, p2, p3, p4, p5); - } - } - - @Override - public void log( - Level level, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6) { - if (maybeEnabled(level)) { - _logger.log(level, message, p0, p1, p2, p3, p4, p5, p6); - } - } - - @Override - public void log( - Level level, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7) { - if (maybeEnabled(level)) { - _logger.log(level, message, p0, p1, p2, p3, p4, p5, p6, p7); - } - } - - @Override - public void log( - Level level, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8) { - if (maybeEnabled(level)) { - _logger.log(level, message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - } - } - - @Override - public void log( - Level level, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8, - Object p9) { - if (maybeEnabled(level)) { - _logger.log(level, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - } - } - - @Override - public void printf(Level level, Marker marker, String format, Object... params) { - if (maybeEnabled(level)) { - _logger.printf(level, marker, format, params); - } - } - - @Override - public void printf(Level level, String format, Object... params) { - if (maybeEnabled(level)) { - _logger.printf(level, format, params); - } - } - - @Override - public T throwing(Level level, T t) { - if (maybeEnabled(level)) { - return _logger.throwing(level, t); - } - return t; - } - - @Override - public T throwing(T t) { - if (_context.isTraceEnabled()) { - return _logger.throwing(t); - } - return t; - } - - @Override - public void trace(Marker marker, Message msg) { - if (logMsg(msg) && _context.isTraceEnabled()) { - _logger.trace(marker, msg); - } - } - - @Override - public void trace(Marker marker, Message msg, Throwable t) { - if (logMsg(msg) && _context.isTraceEnabled()) { - _logger.trace(marker, msg, t); - } - } - - @Override - public void trace(Marker marker, MessageSupplier msgSupplier) { - if (_context.isTraceEnabled()) { - _logger.trace(marker, msgSupplier); - } - } - - @Override - public void trace(Marker marker, MessageSupplier msgSupplier, Throwable t) { - if (_context.isTraceEnabled()) { - _logger.trace(marker, msgSupplier, t); - } - } - - @Override - public void trace(Marker marker, CharSequence message) { - if (_context.isTraceEnabled()) { - _logger.trace(marker, message); - } - } - - @Override - public void trace(Marker marker, CharSequence message, Throwable t) { - if (_context.isTraceEnabled()) { - _logger.trace(marker, message, t); - } - } - - @Override - public void trace(Marker marker, Object message) { - if (_context.isTraceEnabled()) { - _logger.trace(marker, message); - } - } - - @Override - public void trace(Marker marker, Object message, Throwable t) { - if (_context.isTraceEnabled()) { - _logger.trace(marker, message, t); - } - } - - @Override - public void trace(Marker marker, String message) { - if (_context.isTraceEnabled()) { - _logger.trace(marker, message); - } - } - - @Override - public void trace(Marker marker, String message, Object... params) { - if (_context.isTraceEnabled()) { - _logger.trace(marker, message, params); - } - } - - @Override - public void trace(Marker marker, String message, Supplier... paramSuppliers) { - if (_context.isTraceEnabled()) { - _logger.trace(marker, message, paramSuppliers); - } - } - - @Override - public void trace(Marker marker, String message, Throwable t) { - if (_context.isTraceEnabled()) { - _logger.trace(marker, message, t); - } - } - - @Override - public void trace(Marker marker, Supplier msgSupplier) { - if (_context.isTraceEnabled()) { - _logger.trace(marker, msgSupplier); - } - } - - @Override - public void trace(Marker marker, Supplier msgSupplier, Throwable t) { - if (_context.isTraceEnabled()) { - _logger.trace(marker, msgSupplier, t); - } - } - - @Override - public void trace(Message msg) { - if (logMsg(msg) && _context.isTraceEnabled()) { - _logger.trace(msg); - } - } - - @Override - public void trace(Message msg, Throwable t) { - if (logMsg(msg) && _context.isTraceEnabled()) { - _logger.trace(msg, t); - } - } - - @Override - public void trace(MessageSupplier msgSupplier) { - if (_context.isTraceEnabled()) { - _logger.trace(msgSupplier); - } - } - - @Override - public void trace(MessageSupplier msgSupplier, Throwable t) { - if (_context.isTraceEnabled()) { - _logger.trace(msgSupplier, t); - } - } - - @Override - public void trace(CharSequence message) { - if (_context.isTraceEnabled()) { - _logger.trace(message); - } - } - - @Override - public void trace(CharSequence message, Throwable t) { - if (_context.isTraceEnabled()) { - _logger.trace(message, t); - } - } - - @Override - public void trace(Object message) { - if (_context.isTraceEnabled()) { - _logger.trace(message); - } - } - - @Override - public void trace(Object message, Throwable t) { - if (_context.isTraceEnabled()) { - _logger.trace(message, t); - } - } - - @Override - public void trace(String message) { - if (_context.isTraceEnabled()) { - _logger.trace(message); - } - } - - @Override - public void trace(String message, Object... params) { - if (_context.isTraceEnabled()) { - _logger.trace(message, params); - } - } - - @Override - public void trace(String message, Supplier... paramSuppliers) { - if (_context.isTraceEnabled()) { - _logger.trace(message, paramSuppliers); - } - } - - @Override - public void trace(String message, Throwable t) { - if (_context.isTraceEnabled()) { - _logger.trace(message, t); - } - } - - @Override - public void trace(Supplier msgSupplier) { - if (_context.isTraceEnabled()) { - _logger.trace(msgSupplier); - } - } - - @Override - public void trace(Supplier msgSupplier, Throwable t) { - if (_context.isTraceEnabled()) { - _logger.trace(msgSupplier, t); - } - } - - @Override - public void trace(Marker marker, String message, Object p0) { - if (_context.isTraceEnabled()) { - _logger.trace(marker, message, p0); - } - } - - @Override - public void trace(Marker marker, String message, Object p0, Object p1) { - if (_context.isTraceEnabled()) { - _logger.trace(marker, message, p0, p1); - } - } - - @Override - public void trace(Marker marker, String message, Object p0, Object p1, Object p2) { - if (_context.isTraceEnabled()) { - _logger.trace(marker, message, p0, p1, p2); - } - } - - @Override - public void trace(Marker marker, String message, Object p0, Object p1, Object p2, Object p3) { - if (_context.isTraceEnabled()) { - _logger.trace(marker, message, p0, p1, p2, p3); - } - } - - @Override - public void trace(Marker marker, String message, Object p0, Object p1, Object p2, Object p3, Object p4) { - if (_context.isTraceEnabled()) { - _logger.trace(marker, message, p0, p1, p2, p3, p4); - } - } - - @Override - public void trace(Marker marker, String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5) { - if (_context.isTraceEnabled()) { - _logger.trace(marker, message, p0, p1, p2, p3, p4, p5); - } - } - - @Override - public void trace( - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6) { - if (_context.isTraceEnabled()) { - _logger.trace(marker, message, p0, p1, p2, p3, p4, p5, p6); - } - } - - @Override - public void trace( - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7) { - if (_context.isTraceEnabled()) { - _logger.trace(marker, message, p0, p1, p2, p3, p4, p5, p6, p7); - } - } - - @Override - public void trace( - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8) { - if (_context.isTraceEnabled()) { - _logger.trace(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - } - } - - @Override - public void trace( - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8, - Object p9) { - if (_context.isTraceEnabled()) { - _logger.trace(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - } - } - - @Override - public void trace(String message, Object p0) { - if (_context.isTraceEnabled()) { - _logger.trace(message, p0); - } - } - - @Override - public void trace(String message, Object p0, Object p1) { - if (_context.isTraceEnabled()) { - _logger.trace(message, p0, p1); - } - } - - @Override - public void trace(String message, Object p0, Object p1, Object p2) { - if (_context.isTraceEnabled()) { - _logger.trace(message, p0, p1, p2); - } - } - - @Override - public void trace(String message, Object p0, Object p1, Object p2, Object p3) { - if (_context.isTraceEnabled()) { - _logger.trace(message, p0, p1, p2, p3); - } - } - - @Override - public void trace(String message, Object p0, Object p1, Object p2, Object p3, Object p4) { - if (_context.isTraceEnabled()) { - _logger.trace(message, p0, p1, p2, p3, p4); - } - } - - @Override - public void trace(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5) { - if (_context.isTraceEnabled()) { - _logger.trace(message, p0, p1, p2, p3, p4, p5); - } - } - - @Override - public void trace(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6) { - if (_context.isTraceEnabled()) { - _logger.trace(message, p0, p1, p2, p3, p4, p5, p6); - } - } - - @Override - public void trace( - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7) { - if (_context.isTraceEnabled()) { - _logger.trace(message, p0, p1, p2, p3, p4, p5, p6, p7); - } - } - - @Override - public void trace( - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8) { - if (_context.isTraceEnabled()) { - _logger.trace(message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - } - } - - @Override - public void trace( - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8, - Object p9) { - if (_context.isTraceEnabled()) { - _logger.trace(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - } - } - - @Override - public EntryMessage traceEntry() { - return _context.isTraceEnabled() ? _logger.traceEntry() : NoLog.INSTANCE; - } - - @Override - public EntryMessage traceEntry(String format, Object... params) { - return _context.isTraceEnabled() ? _logger.traceEntry(format, params) : NoLog.INSTANCE; - } - - @Override - public EntryMessage traceEntry(Supplier... paramSuppliers) { - return _context.isTraceEnabled() ? _logger.traceEntry(paramSuppliers) : NoLog.INSTANCE; - } - - @Override - public EntryMessage traceEntry(String format, Supplier... paramSuppliers) { - return _context.isTraceEnabled() ? _logger.traceEntry(format, paramSuppliers) : NoLog.INSTANCE; - } - - @Override - public EntryMessage traceEntry(Message message) { - return logMsg(message) && _context.isTraceEnabled() ? _logger.traceEntry(message) : NoLog.INSTANCE; - } - - @Override - public void traceExit() { - if (_context.isTraceEnabled()) { - _logger.traceExit(); - } - } - - @Override - public R traceExit(R result) { - if (_context.isTraceEnabled()) { - return _logger.traceExit(result); - } - return result; - } - - @Override - public R traceExit(String format, R result) { - if (_context.isTraceEnabled()) { - return _logger.traceExit(format, result); - } - return result; - } - - @Override - public void traceExit(EntryMessage message) { - if (logMsg(message) && _context.isTraceEnabled()) { - _logger.traceExit(message); - } - } - - @Override - public R traceExit(EntryMessage message, R result) { - if (logMsg(message) && _context.isTraceEnabled()) { - return _logger.traceExit(message, result); - } - return result; - } - - @Override - public R traceExit(Message message, R result) { - if (logMsg(message) && _context.isTraceEnabled()) { - return _logger.traceExit(message, result); - } - return result; - } - - @Override - public void warn(Marker marker, Message msg) { - if (logMsg(msg)) { - _logger.warn(marker, msg); - } - } - - @Override - public void warn(Marker marker, Message msg, Throwable t) { - if (logMsg(msg)) { - _logger.warn(marker, msg, t); - } - } - - @Override - public void warn(Marker marker, MessageSupplier msgSupplier) { - _logger.warn(marker, msgSupplier); - } - - @Override - public void warn(Marker marker, MessageSupplier msgSupplier, Throwable t) { - _logger.warn(marker, msgSupplier, t); - } - - @Override - public void warn(Marker marker, CharSequence message) { - _logger.warn(marker, message); - } - - @Override - public void warn(Marker marker, CharSequence message, Throwable t) { - _logger.warn(marker, message, t); - } - - @Override - public void warn(Marker marker, Object message) { - _logger.warn(marker, message); - } - - @Override - public void warn(Marker marker, Object message, Throwable t) { - _logger.warn(marker, message, t); - } - - @Override - public void warn(Marker marker, String message) { - _logger.warn(marker, message); - } - - @Override - public void warn(Marker marker, String message, Object... params) { - _logger.warn(marker, message, params); - } - - @Override - public void warn(Marker marker, String message, Supplier... paramSuppliers) { - _logger.warn(marker, message, paramSuppliers); - } - - @Override - public void warn(Marker marker, String message, Throwable t) { - _logger.warn(marker, message, t); - } - - @Override - public void warn(Marker marker, Supplier msgSupplier) { - _logger.warn(marker, msgSupplier); - } - - @Override - public void warn(Marker marker, Supplier msgSupplier, Throwable t) { - _logger.warn(marker, msgSupplier, t); - } - - @Override - public void warn(Message msg) { - if (logMsg(msg)) { - _logger.warn(msg); - } - } - - @Override - public void warn(Message msg, Throwable t) { - if (logMsg(msg)) { - _logger.warn(msg, t); - } - } - - @Override - public void warn(MessageSupplier msgSupplier) { - _logger.warn(msgSupplier); - } - - @Override - public void warn(MessageSupplier msgSupplier, Throwable t) { - _logger.warn(msgSupplier, t); - } - - @Override - public void warn(CharSequence message) { - _logger.warn(message); - } - - @Override - public void warn(CharSequence message, Throwable t) { - _logger.warn(message, t); - } - - @Override - public void warn(Object message) { - _logger.warn(message); - } - - @Override - public void warn(Object message, Throwable t) { - _logger.warn(message, t); - } - - @Override - public void warn(String message) { - _logger.warn(message); - } - - @Override - public void warn(String message, Object... params) { - _logger.warn(message, params); - } - - @Override - public void warn(String message, Supplier... paramSuppliers) { - _logger.warn(message, paramSuppliers); - } - - @Override - public void warn(String message, Throwable t) { - _logger.warn(message, t); - } - - @Override - public void warn(Supplier msgSupplier) { - _logger.warn(msgSupplier); - } - - @Override - public void warn(Supplier msgSupplier, Throwable t) { - _logger.warn(msgSupplier, t); - } - - @Override - public void warn(Marker marker, String message, Object p0) { - _logger.warn(marker, message, p0); - } - - @Override - public void warn(Marker marker, String message, Object p0, Object p1) { - _logger.warn(marker, message, p0, p1); - } - - @Override - public void warn(Marker marker, String message, Object p0, Object p1, Object p2) { - _logger.warn(marker, message, p0, p1, p2); - } - - @Override - public void warn(Marker marker, String message, Object p0, Object p1, Object p2, Object p3) { - _logger.warn(marker, message, p0, p1, p2, p3); - } - - @Override - public void warn(Marker marker, String message, Object p0, Object p1, Object p2, Object p3, Object p4) { - _logger.warn(marker, message, p0, p1, p2, p3, p4); - } - - @Override - public void warn(Marker marker, String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5) { - _logger.warn(marker, message, p0, p1, p2, p3, p4, p5); - } - - @Override - public void warn( - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6) { - _logger.warn(marker, message, p0, p1, p2, p3, p4, p5, p6); - } - - @Override - public void warn( - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7) { - _logger.warn(marker, message, p0, p1, p2, p3, p4, p5, p6, p7); - } - - @Override - public void warn( - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8) { - _logger.warn(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - } - - @Override - public void warn( - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8, - Object p9) { - _logger.warn(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - } - - @Override - public void warn(String message, Object p0) { - _logger.warn(message, p0); - } - - @Override - public void warn(String message, Object p0, Object p1) { - _logger.warn(message, p0, p1); - } - - @Override - public void warn(String message, Object p0, Object p1, Object p2) { - _logger.warn(message, p0, p1, p2); - } - - @Override - public void warn(String message, Object p0, Object p1, Object p2, Object p3) { - _logger.warn(message, p0, p1, p2, p3); - } - - @Override - public void warn(String message, Object p0, Object p1, Object p2, Object p3, Object p4) { - _logger.warn(message, p0, p1, p2, p3, p4); - } - - @Override - public void warn(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5) { - _logger.warn(message, p0, p1, p2, p3, p4, p5); - } - - @Override - public void warn(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6) { - _logger.warn(message, p0, p1, p2, p3, p4, p5, p6); - } - - @Override - public void warn( - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7) { - _logger.warn(message, p0, p1, p2, p3, p4, p5, p6, p7); - } - - @Override - public void warn( - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8) { - _logger.warn(message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - } - - @Override - public void warn( - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8, - Object p9) { - _logger.warn(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - } - - @Override - public boolean isEnabled(Level level, Marker marker, Message message, Throwable t) { - return logMsg(message) && maybeEnabled(level) && _logger.isEnabled(level, marker, message, t); - } - - @Override - public boolean isEnabled(Level level, Marker marker, CharSequence message, Throwable t) { - return maybeEnabled(level) && _logger.isEnabled(level, marker, message, t); - } - - @Override - public boolean isEnabled(Level level, Marker marker, Object message, Throwable t) { - return maybeEnabled(level) && _logger.isEnabled(level, marker, message, t); - } - - @Override - public boolean isEnabled(Level level, Marker marker, String message, Throwable t) { - return maybeEnabled(level) && _logger.isEnabled(level, marker, message, t); - } - - @Override - public boolean isEnabled(Level level, Marker marker, String message) { - return maybeEnabled(level) && _logger.isEnabled(level, marker, message); - } - - @Override - public boolean isEnabled(Level level, Marker marker, String message, Object... params) { - return maybeEnabled(level) && _logger.isEnabled(level, marker, message, params); - } - - @Override - public boolean isEnabled(Level level, Marker marker, String message, Object p0) { - return maybeEnabled(level) && _logger.isEnabled(level, marker, message, p0); - } - - @Override - public boolean isEnabled(Level level, Marker marker, String message, Object p0, Object p1) { - return maybeEnabled(level) && _logger.isEnabled(level, marker, message, p0, p1); - } - - @Override - public boolean isEnabled(Level level, Marker marker, String message, Object p0, Object p1, Object p2) { - return maybeEnabled(level) && _logger.isEnabled(level, marker, message, p0, p1, p2); - } - - @Override - public boolean isEnabled(Level level, Marker marker, String message, Object p0, Object p1, Object p2, Object p3) { - return maybeEnabled(level) && _logger.isEnabled(level, marker, message, p0, p1, p2, p3); - } - - @Override - public boolean isEnabled( - Level level, - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4) { - return maybeEnabled(level) && _logger.isEnabled(level, marker, message, p0, p1, p2, p3, p4); - } - - @Override - public boolean isEnabled( - Level level, - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5) { - return maybeEnabled(level) && _logger.isEnabled(level, marker, message, p0, p1, p2, p3, p4, p5); - } - - @Override - public boolean isEnabled( - Level level, - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6) { - return maybeEnabled(level) && _logger.isEnabled(level, marker, message, p0, p1, p2, p3, p4, p5, p6); - } - - @Override - public boolean isEnabled( - Level level, - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7) { - return maybeEnabled(level) && _logger.isEnabled(level, marker, message, p0, p1, p2, p3, p4, p5, p6, p7); - } - - @Override - public boolean isEnabled( - Level level, - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8) { - return maybeEnabled(level) && _logger.isEnabled(level, marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - } - - @Override - public boolean isEnabled( - Level level, - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8, - Object p9) { - return maybeEnabled(level) && _logger.isEnabled(level, marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - } - - @Override - public void logIfEnabled(String fqcn, Level level, Marker marker, Message message, Throwable t) { - if (logMsg(message) && maybeEnabled(level)) { - _logger.logIfEnabled(fqcn, level, marker, message, t); - } - } - - @Override - public void logIfEnabled(String fqcn, Level level, Marker marker, CharSequence message, Throwable t) { - if (maybeEnabled(level)) { - _logger.logIfEnabled(fqcn, level, marker, message, t); - } - } - - @Override - public void logIfEnabled(String fqcn, Level level, Marker marker, Object message, Throwable t) { - if (maybeEnabled(level)) { - _logger.logIfEnabled(fqcn, level, marker, message, t); - } - } - - @Override - public void logIfEnabled(String fqcn, Level level, Marker marker, String message, Throwable t) { - if (maybeEnabled(level)) { - _logger.logIfEnabled(fqcn, level, marker, message, t); - } - } - - @Override - public void logIfEnabled(String fqcn, Level level, Marker marker, String message) { - if (maybeEnabled(level)) { - _logger.logIfEnabled(fqcn, level, marker, message); - } - } - - @Override - public void logIfEnabled(String fqcn, Level level, Marker marker, String message, Object... params) { - if (maybeEnabled(level)) { - _logger.logIfEnabled(fqcn, level, marker, message, params); - } - } - - @Override - public void logIfEnabled(String fqcn, Level level, Marker marker, String message, Object p0) { - if (maybeEnabled(level)) { - _logger.logIfEnabled(fqcn, level, marker, message, p0); - } - } - - @Override - public void logIfEnabled(String fqcn, Level level, Marker marker, String message, Object p0, Object p1) { - if (maybeEnabled(level)) { - _logger.logIfEnabled(fqcn, level, marker, message, p0, p1); - } - } - - @Override - public void logIfEnabled(String fqcn, Level level, Marker marker, String message, Object p0, Object p1, Object p2) { - if (maybeEnabled(level)) { - _logger.logIfEnabled(fqcn, level, marker, message, p0, p1, p2); - } - } - - @Override - public void logIfEnabled( - String fqcn, - Level level, - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3) { - if (maybeEnabled(level)) { - _logger.logIfEnabled(fqcn, level, marker, message, p0, p1, p2, p3); - } - } - - @Override - public void logIfEnabled( - String fqcn, - Level level, - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4) { - if (maybeEnabled(level)) { - _logger.logIfEnabled(fqcn, level, marker, message, p0, p1, p2, p3, p4); - } - } - - @Override - public void logIfEnabled( - String fqcn, - Level level, - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5) { - if (maybeEnabled(level)) { - _logger.logIfEnabled(fqcn, level, marker, message, p0, p1, p2, p3, p4, p5); - } - } - - @Override - public void logIfEnabled( - String fqcn, - Level level, - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6) { - if (maybeEnabled(level)) { - _logger.logIfEnabled(fqcn, level, marker, message, p0, p1, p2, p3, p4, p5, p6); - } - } - - @Override - public void logIfEnabled( - String fqcn, - Level level, - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7) { - if (maybeEnabled(level)) { - _logger.logIfEnabled(fqcn, level, marker, message, p0, p1, p2, p3, p4, p5, p6, p7); - } - } - - @Override - public void logIfEnabled( - String fqcn, - Level level, - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8) { - if (maybeEnabled(level)) { - _logger.logIfEnabled(fqcn, level, marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - } - } - - @Override - public void logIfEnabled( - String fqcn, - Level level, - Marker marker, - String message, - Object p0, - Object p1, - Object p2, - Object p3, - Object p4, - Object p5, - Object p6, - Object p7, - Object p8, - Object p9) { - if (maybeEnabled(level)) { - _logger.logIfEnabled(fqcn, level, marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - } - } - - @Override - public void logMessage(String fqcn, Level level, Marker marker, Message message, Throwable t) { - if (logMsg(message) && maybeEnabled(level)) { - _logger.logIfEnabled(fqcn, level, marker, message, t); - } - } - - @Override - public void logIfEnabled(String fqcn, Level level, Marker marker, MessageSupplier msgSupplier, Throwable t) { - if (maybeEnabled(level)) { - _logger.logIfEnabled(fqcn, level, marker, msgSupplier, t); - } - } - - @Override - public void logIfEnabled(String fqcn, Level level, Marker marker, String message, Supplier... paramSuppliers) { - if (maybeEnabled(level)) { - _logger.logIfEnabled(fqcn, level, marker, message, paramSuppliers); - } - } - - @Override - public void logIfEnabled(String fqcn, Level level, Marker marker, Supplier msgSupplier, Throwable t) { - if (maybeEnabled(level)) { - _logger.logIfEnabled(fqcn, level, marker, msgSupplier, t); - } - } - - private static boolean logMsg(Message msg) { - return msg != null && msg != NoMsg.INSTANCE && msg != NoLog.INSTANCE; - } - - private static class NoMsg implements Message { - private static final Message INSTANCE = new NoMsg(); - private static final Object[] PARAMS = {}; - - @Override - public final String getFormattedMessage() { - return ""; - } - - @Override - public final String getFormat() { - return ""; - } - - @Override - public final Object[] getParameters() { - return PARAMS; - } - - @Override - public final Throwable getThrowable() { - return null; - } - - @Override - public final String toString() { - return ""; - } - } - - private static final class NoLog extends NoMsg implements EntryMessage { - private static final EntryMessage INSTANCE = new NoLog(); - - @Override - public String getText() { - return ""; - } - - @Override - public Message getMessage() { - return NoMsg.INSTANCE; - } - } -} diff --git a/internal/alpini/common/alpini-common-log/src/test/java/com/linkedin/alpini/TestFastLogContextFactory.java b/internal/alpini/common/alpini-common-log/src/test/java/com/linkedin/alpini/TestFastLogContextFactory.java deleted file mode 100644 index 4ab31231306..00000000000 --- a/internal/alpini/common/alpini-common-log/src/test/java/com/linkedin/alpini/TestFastLogContextFactory.java +++ /dev/null @@ -1,119 +0,0 @@ -package com.linkedin.alpini; - -import com.linkedin.alpini.log.FastLogContextFactory; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.message.MessageFactory; -import org.apache.logging.log4j.spi.ExtendedLogger; -import org.apache.logging.log4j.spi.LoggerContext; -import org.apache.logging.log4j.spi.LoggerContextFactory; -import org.mockito.Mockito; -import org.testng.Assert; -import org.testng.annotations.Test; - - -@Test(groups = "unit") -public class TestFastLogContextFactory { - @Test - public void testConstruct() { - LoggerContextFactory oldFactory = LogManager.getFactory(); - try { - LogManager.setFactory(new FastLogContextFactory()); - - LogManager.getLogger(getClass()).error("Hello World"); // this should never reach the underlying logger - - } finally { - LogManager.setFactory(oldFactory); - } - } - - @Test - public void testLog() { - - LoggerContextFactory oldFactory = LogManager.getFactory(); - try { - LoggerContextFactory mockFactory = Mockito.mock(LoggerContextFactory.class); - LogManager.setFactory(new FastLogContextFactory(mockFactory)); - - LoggerContext mockContext = Mockito.mock(LoggerContext.class); - - Mockito - .when( - mockFactory - .getContext(Mockito.anyString(), Mockito.any(ClassLoader.class), Mockito.any(), Mockito.anyBoolean())) - .thenReturn(mockContext); - - ExtendedLogger mockLogger = Mockito.mock(ExtendedLogger.class); - Mockito.when(mockContext.getLogger(Mockito.anyString())).thenReturn(mockLogger); - - Logger logger = LogManager.getLogger(TestFastLogContextFactory.class); - - Mockito.verify(mockFactory) - .getContext( - Mockito.eq("org.apache.logging.log4j.LogManager"), - Mockito.any(ClassLoader.class), - Mockito.isNull(), - Mockito.eq(false)); - - Mockito.verify(mockContext).getLogger(Mockito.eq(getClass().getName())); - - logger.debug("Hello World"); // this should never reach the underlying logger - - Mockito.verifyNoMoreInteractions(mockFactory, mockContext, mockLogger); - - } finally { - LogManager.setFactory(oldFactory); - } - } - - @Test - public void testLogContext() { - - LoggerContextFactory oldFactory = LogManager.getFactory(); - try { - LoggerContextFactory mockFactory = Mockito.mock(LoggerContextFactory.class); - LogManager.setFactory(new FastLogContextFactory(mockFactory)); - - LoggerContext mockContext = Mockito.mock(LoggerContext.class); - - Mockito.when(mockFactory.getContext(Mockito.anyString(), Mockito.any(), Mockito.any(), Mockito.anyBoolean())) - .thenReturn(mockContext); - - ExtendedLogger mockLogger = Mockito.mock(ExtendedLogger.class); - Mockito.when(mockContext.getLogger(Mockito.anyString())).thenReturn(mockLogger); - - LoggerContext context = LogManager.getContext(); - - Assert.assertFalse(context.hasLogger("foo")); - - Mockito.verify(mockFactory) - .getContext( - Mockito.eq("org.apache.logging.log4j.LogManager"), - Mockito.isNull(ClassLoader.class), - Mockito.isNull(), - Mockito.eq(true)); - - Mockito.verify(mockContext).hasLogger(Mockito.eq("foo")); - - Mockito.verifyNoMoreInteractions(mockFactory, mockContext, mockLogger); - - MessageFactory factory = Mockito.mock(MessageFactory.class); - - Assert.assertFalse(context.hasLogger("bar", factory)); - - Mockito.verify(mockContext).hasLogger(Mockito.eq("bar"), Mockito.same(factory)); - - Mockito.verifyNoMoreInteractions(mockFactory, mockContext, mockLogger); - - Assert.assertFalse(context.hasLogger("xyz", factory.getClass())); - - Mockito.verify(mockContext).hasLogger(Mockito.eq("xyz"), Mockito.same(factory.getClass())); - - Mockito.verifyNoMoreInteractions(mockFactory, mockContext, mockLogger); - - } finally { - LogManager.setFactory(oldFactory); - } - } - -} diff --git a/internal/alpini/common/alpini-common-log/src/test/java/com/linkedin/alpini/TestFastLogger.java b/internal/alpini/common/alpini-common-log/src/test/java/com/linkedin/alpini/TestFastLogger.java deleted file mode 100644 index 06671cb5e9a..00000000000 --- a/internal/alpini/common/alpini-common-log/src/test/java/com/linkedin/alpini/TestFastLogger.java +++ /dev/null @@ -1,6195 +0,0 @@ -package com.linkedin.alpini; - -import com.linkedin.alpini.log.FastLogContextFactory; -import com.linkedin.alpini.log.FastLogMBean; -import com.linkedin.alpini.log.FastLogger; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.Marker; -import org.apache.logging.log4j.message.EntryMessage; -import org.apache.logging.log4j.message.Message; -import org.apache.logging.log4j.message.MessageFactory; -import org.apache.logging.log4j.spi.ExtendedLogger; -import org.apache.logging.log4j.spi.LoggerContext; -import org.apache.logging.log4j.spi.LoggerContextFactory; -import org.apache.logging.log4j.util.MessageSupplier; -import org.apache.logging.log4j.util.Supplier; -import org.mockito.Mockito; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - - -@Test(groups = "unit") -public class TestFastLogger { - static final LoggerContextFactory ORIGINAL_FACTORY = LogManager.getFactory(); - - LoggerContextFactory _mockFactory; - LoggerContext _mockContext; - ExtendedLogger _mockLogger; - FastLogMBean _mBean; - - @BeforeClass - public void beforeClass() { - _mockFactory = Mockito.mock(LoggerContextFactory.class); - - _mockContext = Mockito.mock(LoggerContext.class); - - Mockito - .when( - _mockFactory - .getContext(Mockito.anyString(), Mockito.any(ClassLoader.class), Mockito.any(), Mockito.anyBoolean())) - .thenReturn(_mockContext); - - _mockLogger = Mockito.mock(ExtendedLogger.class); - Mockito.when(_mockContext.getLogger(Mockito.anyString())).thenReturn(_mockLogger); - - LogManager.setFactory(new FastLogContextFactory(_mockFactory)); - - Logger logger = LogManager.getLogger(getClass()); - - _mBean = ((FastLogger) logger).getManagementMBean(); - - Mockito.verify(_mockFactory) - .getContext( - Mockito.eq("org.apache.logging.log4j.LogManager"), - Mockito.any(ClassLoader.class), - Mockito.isNull(), - Mockito.eq(false)); - - verifyMockContext(); - } - - @AfterClass(alwaysRun = true) - public void afterClass() { - LogManager.setFactory(ORIGINAL_FACTORY); - } - - @BeforeMethod - public void beforeMethod() { - Mockito.reset(_mockLogger, _mockContext); - Mockito.when(_mockContext.getLogger(Mockito.anyString())).thenReturn(_mockLogger); - } - - private void verifyMockContext() { - Mockito.verify(_mockContext).getLogger(Mockito.eq(getClass().getName())); - } - - @Test - public void testErrorMarkerMessage() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Message message = Mockito.mock(Message.class); - - log.error(marker, message); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorMarkerMessageThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Message message = Mockito.mock(Message.class); - Throwable ex = new Error(); - - log.error(marker, message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorMarkerMessageSupplier() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - MessageSupplier message = Mockito.mock(MessageSupplier.class); - - log.error(marker, message); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorMarkerMessageSupplierThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - MessageSupplier message = Mockito.mock(MessageSupplier.class); - Throwable ex = new Error(); - - log.error(marker, message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorMarkerSupplier() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Supplier message = Mockito.mock(Supplier.class); - - log.error(marker, message); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorMarkerSupplierThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Supplier message = Mockito.mock(Supplier.class); - Throwable ex = new Error(); - - log.error(marker, message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorMarkerCharSequence() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - CharSequence message = Mockito.mock(CharSequence.class); - log.error(marker, message); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorMarkerCharSequenceThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - CharSequence message = Mockito.mock(CharSequence.class); - Throwable ex = new Error(); - log.error(marker, message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorMarkerObject() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Object message = new Object(); - log.error(marker, message); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorMarkerObjectThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Object message = new Object(); - Throwable ex = new Error(); - log.error(marker, message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorMarkerString() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - log.error(marker, message); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorMarkerStringThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Throwable ex = new Error(); - log.error(marker, message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorMarkerStringSupplierVararg() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Supplier p0 = Mockito.mock(Supplier.class); - Supplier p1 = Mockito.mock(Supplier.class); - Supplier p2 = Mockito.mock(Supplier.class); - Supplier p3 = Mockito.mock(Supplier.class); - Supplier p4 = Mockito.mock(Supplier.class); - Supplier p5 = Mockito.mock(Supplier.class); - Supplier p6 = Mockito.mock(Supplier.class); - Supplier p7 = Mockito.mock(Supplier.class); - Supplier p8 = Mockito.mock(Supplier.class); - Supplier p9 = Mockito.mock(Supplier.class); - Supplier pa = Mockito.mock(Supplier.class); - log.error(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorMarkerStringVararg() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - Object p9 = new Object(); - Object pa = new Object(); - log.error(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorMarkerStringP9() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - Object p9 = new Object(); - log.error(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorMarkerStringP8() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - log.error(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorMarkerStringP7() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - log.error(marker, message, p0, p1, p2, p3, p4, p5, p6, p7); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(marker, message, p0, p1, p2, p3, p4, p5, p6, p7); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorMarkerStringP6() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - log.error(marker, message, p0, p1, p2, p3, p4, p5, p6); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(marker, message, p0, p1, p2, p3, p4, p5, p6); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorMarkerStringP5() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - log.error(marker, message, p0, p1, p2, p3, p4, p5); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(marker, message, p0, p1, p2, p3, p4, p5); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorMarkerStringP4() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - log.error(marker, message, p0, p1, p2, p3, p4); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(marker, message, p0, p1, p2, p3, p4); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorMarkerStringP3() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - log.error(marker, message, p0, p1, p2, p3); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(marker, message, p0, p1, p2, p3); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorMarkerStringP2() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - log.error(marker, message, p0, p1, p2); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(marker, message, p0, p1, p2); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorMarkerStringP1() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - log.error(marker, message, p0, p1); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(marker, message, p0, p1); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testMarkerErrorStringP0() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - log.error(marker, message, p0); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(marker, message, p0); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorMessage() { - Logger log = LogManager.getLogger(getClass()); - - Message message = Mockito.mock(Message.class); - - log.error(message); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorMessageThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Message message = Mockito.mock(Message.class); - Throwable ex = new Error(); - - log.error(message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorMessageSupplier() { - Logger log = LogManager.getLogger(getClass()); - - MessageSupplier message = Mockito.mock(MessageSupplier.class); - - log.error(message); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorMessageSupplierThrowable() { - Logger log = LogManager.getLogger(getClass()); - - MessageSupplier message = Mockito.mock(MessageSupplier.class); - Throwable ex = new Error(); - - log.error(message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorSupplier() { - Logger log = LogManager.getLogger(getClass()); - - Supplier message = Mockito.mock(Supplier.class); - - log.error(message); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorSupplierThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Supplier message = Mockito.mock(Supplier.class); - Throwable ex = new Error(); - - log.error(message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorCharSequence() { - Logger log = LogManager.getLogger(getClass()); - - CharSequence message = Mockito.mock(CharSequence.class); - log.error(message); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorCharSequenceThrowable() { - Logger log = LogManager.getLogger(getClass()); - - CharSequence message = Mockito.mock(CharSequence.class); - Throwable ex = new Error(); - log.error(message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorObject() { - Logger log = LogManager.getLogger(getClass()); - - Object message = new Object(); - log.error(message); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorObjectThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Object message = new Object(); - Throwable ex = new Error(); - log.error(message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorString() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - log.error(message); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorStringThrowable() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Throwable ex = new Error(); - log.error(message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorStringSupplierVararg() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Supplier p0 = Mockito.mock(Supplier.class); - Supplier p1 = Mockito.mock(Supplier.class); - Supplier p2 = Mockito.mock(Supplier.class); - Supplier p3 = Mockito.mock(Supplier.class); - Supplier p4 = Mockito.mock(Supplier.class); - Supplier p5 = Mockito.mock(Supplier.class); - Supplier p6 = Mockito.mock(Supplier.class); - Supplier p7 = Mockito.mock(Supplier.class); - Supplier p8 = Mockito.mock(Supplier.class); - Supplier p9 = Mockito.mock(Supplier.class); - Supplier pa = Mockito.mock(Supplier.class); - log.error(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorStringVararg() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - Object p9 = new Object(); - Object pa = new Object(); - log.error(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorStringP9() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - Object p9 = new Object(); - log.error(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorStringP8() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - log.error(message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorStringP7() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - log.error(message, p0, p1, p2, p3, p4, p5, p6, p7); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(message, p0, p1, p2, p3, p4, p5, p6, p7); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorStringP6() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - log.error(message, p0, p1, p2, p3, p4, p5, p6); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(message, p0, p1, p2, p3, p4, p5, p6); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorStringP5() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - log.error(message, p0, p1, p2, p3, p4, p5); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(message, p0, p1, p2, p3, p4, p5); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorStringP4() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - log.error(message, p0, p1, p2, p3, p4); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(message, p0, p1, p2, p3, p4); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorStringP3() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - log.error(message, p0, p1, p2, p3); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(message, p0, p1, p2, p3); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorStringP2() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - log.error(message, p0, p1, p2); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(message, p0, p1, p2); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorStringP1() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - log.error(message, p0, p1); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(message, p0, p1); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testErrorStringP0() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - log.error(message, p0); - - verifyMockContext(); - Mockito.verify(_mockLogger).error(message, p0); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMarkerMessage() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Message message = Mockito.mock(Message.class); - - log.warn(marker, message); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMarkerMessageThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Message message = Mockito.mock(Message.class); - Throwable ex = new Error(); - - log.warn(marker, message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMarkerMessageSupplier() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - MessageSupplier message = Mockito.mock(MessageSupplier.class); - - log.warn(marker, message); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMarkerMessageSupplierThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - MessageSupplier message = Mockito.mock(MessageSupplier.class); - Throwable ex = new Error(); - - log.warn(marker, message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMarkerSupplier() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Supplier message = Mockito.mock(Supplier.class); - - log.warn(marker, message); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMarkerSupplierThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Supplier message = Mockito.mock(Supplier.class); - Throwable ex = new Error(); - - log.warn(marker, message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMarkerCharSequence() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - CharSequence message = Mockito.mock(CharSequence.class); - log.warn(marker, message); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMarkerCharSequenceThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - CharSequence message = Mockito.mock(CharSequence.class); - Throwable ex = new Error(); - log.warn(marker, message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMarkerObject() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Object message = new Object(); - log.warn(marker, message); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMarkerObjectThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Object message = new Object(); - Throwable ex = new Error(); - log.warn(marker, message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMarkerString() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - log.warn(marker, message); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMarkerStringThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Throwable ex = new Error(); - log.warn(marker, message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMarkerStringSupplierVararg() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Supplier p0 = Mockito.mock(Supplier.class); - Supplier p1 = Mockito.mock(Supplier.class); - Supplier p2 = Mockito.mock(Supplier.class); - Supplier p3 = Mockito.mock(Supplier.class); - Supplier p4 = Mockito.mock(Supplier.class); - Supplier p5 = Mockito.mock(Supplier.class); - Supplier p6 = Mockito.mock(Supplier.class); - Supplier p7 = Mockito.mock(Supplier.class); - Supplier p8 = Mockito.mock(Supplier.class); - Supplier p9 = Mockito.mock(Supplier.class); - Supplier pa = Mockito.mock(Supplier.class); - log.warn(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMarkerStringVararg() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - Object p9 = new Object(); - Object pa = new Object(); - log.warn(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMarkerStringP9() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - Object p9 = new Object(); - log.warn(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMarkerStringP8() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - log.warn(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMarkerStringP7() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - log.warn(marker, message, p0, p1, p2, p3, p4, p5, p6, p7); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(marker, message, p0, p1, p2, p3, p4, p5, p6, p7); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMarkerStringP6() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - log.warn(marker, message, p0, p1, p2, p3, p4, p5, p6); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(marker, message, p0, p1, p2, p3, p4, p5, p6); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMarkerStringP5() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - log.warn(marker, message, p0, p1, p2, p3, p4, p5); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(marker, message, p0, p1, p2, p3, p4, p5); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMarkerStringP4() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - log.warn(marker, message, p0, p1, p2, p3, p4); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(marker, message, p0, p1, p2, p3, p4); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMarkerStringP3() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - log.warn(marker, message, p0, p1, p2, p3); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(marker, message, p0, p1, p2, p3); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMarkerStringP2() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - log.warn(marker, message, p0, p1, p2); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(marker, message, p0, p1, p2); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMarkerStringP1() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - log.warn(marker, message, p0, p1); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(marker, message, p0, p1); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testMarkerWarnStringP0() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - log.warn(marker, message, p0); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(marker, message, p0); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMessage() { - Logger log = LogManager.getLogger(getClass()); - - Message message = Mockito.mock(Message.class); - - log.warn(message); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMessageThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Message message = Mockito.mock(Message.class); - Throwable ex = new Error(); - - log.warn(message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMessageSupplier() { - Logger log = LogManager.getLogger(getClass()); - - MessageSupplier message = Mockito.mock(MessageSupplier.class); - - log.warn(message); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnMessageSupplierThrowable() { - Logger log = LogManager.getLogger(getClass()); - - MessageSupplier message = Mockito.mock(MessageSupplier.class); - Throwable ex = new Error(); - - log.warn(message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnSupplier() { - Logger log = LogManager.getLogger(getClass()); - - Supplier message = Mockito.mock(Supplier.class); - - log.warn(message); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnSupplierThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Supplier message = Mockito.mock(Supplier.class); - Throwable ex = new Error(); - - log.warn(message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnCharSequence() { - Logger log = LogManager.getLogger(getClass()); - - CharSequence message = Mockito.mock(CharSequence.class); - log.warn(message); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnCharSequenceThrowable() { - Logger log = LogManager.getLogger(getClass()); - - CharSequence message = Mockito.mock(CharSequence.class); - Throwable ex = new Error(); - log.warn(message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnObject() { - Logger log = LogManager.getLogger(getClass()); - - Object message = new Object(); - log.warn(message); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnObjectThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Object message = new Object(); - Throwable ex = new Error(); - log.warn(message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnString() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - log.warn(message); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnStringThrowable() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Throwable ex = new Error(); - log.warn(message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnStringSupplierVararg() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Supplier p0 = Mockito.mock(Supplier.class); - Supplier p1 = Mockito.mock(Supplier.class); - Supplier p2 = Mockito.mock(Supplier.class); - Supplier p3 = Mockito.mock(Supplier.class); - Supplier p4 = Mockito.mock(Supplier.class); - Supplier p5 = Mockito.mock(Supplier.class); - Supplier p6 = Mockito.mock(Supplier.class); - Supplier p7 = Mockito.mock(Supplier.class); - Supplier p8 = Mockito.mock(Supplier.class); - Supplier p9 = Mockito.mock(Supplier.class); - Supplier pa = Mockito.mock(Supplier.class); - log.warn(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnStringVararg() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - Object p9 = new Object(); - Object pa = new Object(); - log.warn(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnStringP9() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - Object p9 = new Object(); - log.warn(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnStringP8() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - log.warn(message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnStringP7() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - log.warn(message, p0, p1, p2, p3, p4, p5, p6, p7); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(message, p0, p1, p2, p3, p4, p5, p6, p7); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnStringP6() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - log.warn(message, p0, p1, p2, p3, p4, p5, p6); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(message, p0, p1, p2, p3, p4, p5, p6); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnStringP5() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - log.warn(message, p0, p1, p2, p3, p4, p5); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(message, p0, p1, p2, p3, p4, p5); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnStringP4() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - log.warn(message, p0, p1, p2, p3, p4); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(message, p0, p1, p2, p3, p4); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnStringP3() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - log.warn(message, p0, p1, p2, p3); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(message, p0, p1, p2, p3); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnStringP2() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - log.warn(message, p0, p1, p2); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(message, p0, p1, p2); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnStringP1() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - log.warn(message, p0, p1); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(message, p0, p1); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testWarnStringP0() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - log.warn(message, p0); - - verifyMockContext(); - Mockito.verify(_mockLogger).warn(message, p0); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMarkerMessage() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Message message = Mockito.mock(Message.class); - - log.fatal(marker, message); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMarkerMessageThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Message message = Mockito.mock(Message.class); - Throwable ex = new Error(); - - log.fatal(marker, message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMarkerMessageSupplier() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - MessageSupplier message = Mockito.mock(MessageSupplier.class); - - log.fatal(marker, message); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMarkerMessageSupplierThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - MessageSupplier message = Mockito.mock(MessageSupplier.class); - Throwable ex = new Error(); - - log.fatal(marker, message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMarkerSupplier() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Supplier message = Mockito.mock(Supplier.class); - - log.fatal(marker, message); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMarkerSupplierThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Supplier message = Mockito.mock(Supplier.class); - Throwable ex = new Error(); - - log.fatal(marker, message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMarkerCharSequence() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - CharSequence message = Mockito.mock(CharSequence.class); - log.fatal(marker, message); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMarkerCharSequenceThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - CharSequence message = Mockito.mock(CharSequence.class); - Throwable ex = new Error(); - log.fatal(marker, message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMarkerObject() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Object message = new Object(); - log.fatal(marker, message); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMarkerObjectThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Object message = new Object(); - Throwable ex = new Error(); - log.fatal(marker, message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMarkerString() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - log.fatal(marker, message); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMarkerStringThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Throwable ex = new Error(); - log.fatal(marker, message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMarkerStringSupplierVararg() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Supplier p0 = Mockito.mock(Supplier.class); - Supplier p1 = Mockito.mock(Supplier.class); - Supplier p2 = Mockito.mock(Supplier.class); - Supplier p3 = Mockito.mock(Supplier.class); - Supplier p4 = Mockito.mock(Supplier.class); - Supplier p5 = Mockito.mock(Supplier.class); - Supplier p6 = Mockito.mock(Supplier.class); - Supplier p7 = Mockito.mock(Supplier.class); - Supplier p8 = Mockito.mock(Supplier.class); - Supplier p9 = Mockito.mock(Supplier.class); - Supplier pa = Mockito.mock(Supplier.class); - log.fatal(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMarkerStringVararg() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - Object p9 = new Object(); - Object pa = new Object(); - log.fatal(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMarkerStringP9() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - Object p9 = new Object(); - log.fatal(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMarkerStringP8() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - log.fatal(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMarkerStringP7() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - log.fatal(marker, message, p0, p1, p2, p3, p4, p5, p6, p7); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(marker, message, p0, p1, p2, p3, p4, p5, p6, p7); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMarkerStringP6() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - log.fatal(marker, message, p0, p1, p2, p3, p4, p5, p6); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(marker, message, p0, p1, p2, p3, p4, p5, p6); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMarkerStringP5() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - log.fatal(marker, message, p0, p1, p2, p3, p4, p5); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(marker, message, p0, p1, p2, p3, p4, p5); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMarkerStringP4() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - log.fatal(marker, message, p0, p1, p2, p3, p4); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(marker, message, p0, p1, p2, p3, p4); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMarkerStringP3() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - log.fatal(marker, message, p0, p1, p2, p3); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(marker, message, p0, p1, p2, p3); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMarkerStringP2() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - log.fatal(marker, message, p0, p1, p2); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(marker, message, p0, p1, p2); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMarkerStringP1() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - log.fatal(marker, message, p0, p1); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(marker, message, p0, p1); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testMarkerFatalStringP0() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - log.fatal(marker, message, p0); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(marker, message, p0); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMessage() { - Logger log = LogManager.getLogger(getClass()); - - Message message = Mockito.mock(Message.class); - - log.fatal(message); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMessageThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Message message = Mockito.mock(Message.class); - Throwable ex = new Error(); - - log.fatal(message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMessageSupplier() { - Logger log = LogManager.getLogger(getClass()); - - MessageSupplier message = Mockito.mock(MessageSupplier.class); - - log.fatal(message); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalMessageSupplierThrowable() { - Logger log = LogManager.getLogger(getClass()); - - MessageSupplier message = Mockito.mock(MessageSupplier.class); - Throwable ex = new Error(); - - log.fatal(message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalSupplier() { - Logger log = LogManager.getLogger(getClass()); - - Supplier message = Mockito.mock(Supplier.class); - - log.fatal(message); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalSupplierThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Supplier message = Mockito.mock(Supplier.class); - Throwable ex = new Error(); - - log.fatal(message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalCharSequence() { - Logger log = LogManager.getLogger(getClass()); - - CharSequence message = Mockito.mock(CharSequence.class); - log.fatal(message); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalCharSequenceThrowable() { - Logger log = LogManager.getLogger(getClass()); - - CharSequence message = Mockito.mock(CharSequence.class); - Throwable ex = new Error(); - log.fatal(message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalObject() { - Logger log = LogManager.getLogger(getClass()); - - Object message = new Object(); - log.fatal(message); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalObjectThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Object message = new Object(); - Throwable ex = new Error(); - log.fatal(message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalString() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - log.fatal(message); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalStringThrowable() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Throwable ex = new Error(); - log.fatal(message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalStringSupplierVararg() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Supplier p0 = Mockito.mock(Supplier.class); - Supplier p1 = Mockito.mock(Supplier.class); - Supplier p2 = Mockito.mock(Supplier.class); - Supplier p3 = Mockito.mock(Supplier.class); - Supplier p4 = Mockito.mock(Supplier.class); - Supplier p5 = Mockito.mock(Supplier.class); - Supplier p6 = Mockito.mock(Supplier.class); - Supplier p7 = Mockito.mock(Supplier.class); - Supplier p8 = Mockito.mock(Supplier.class); - Supplier p9 = Mockito.mock(Supplier.class); - Supplier pa = Mockito.mock(Supplier.class); - log.fatal(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalStringVararg() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - Object p9 = new Object(); - Object pa = new Object(); - log.fatal(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalStringP9() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - Object p9 = new Object(); - log.fatal(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalStringP8() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - log.fatal(message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalStringP7() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - log.fatal(message, p0, p1, p2, p3, p4, p5, p6, p7); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(message, p0, p1, p2, p3, p4, p5, p6, p7); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalStringP6() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - log.fatal(message, p0, p1, p2, p3, p4, p5, p6); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(message, p0, p1, p2, p3, p4, p5, p6); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalStringP5() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - log.fatal(message, p0, p1, p2, p3, p4, p5); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(message, p0, p1, p2, p3, p4, p5); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalStringP4() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - log.fatal(message, p0, p1, p2, p3, p4); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(message, p0, p1, p2, p3, p4); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalStringP3() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - log.fatal(message, p0, p1, p2, p3); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(message, p0, p1, p2, p3); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalStringP2() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - log.fatal(message, p0, p1, p2); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(message, p0, p1, p2); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalStringP1() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - log.fatal(message, p0, p1); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(message, p0, p1); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testFatalStringP0() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - log.fatal(message, p0); - - verifyMockContext(); - Mockito.verify(_mockLogger).fatal(message, p0); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMarkerMessage() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Message message = Mockito.mock(Message.class); - - log.info(marker, message); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMarkerMessageThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Message message = Mockito.mock(Message.class); - Throwable ex = new Error(); - - log.info(marker, message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMarkerMessageSupplier() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - MessageSupplier message = Mockito.mock(MessageSupplier.class); - - log.info(marker, message); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMarkerMessageSupplierThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - MessageSupplier message = Mockito.mock(MessageSupplier.class); - Throwable ex = new Error(); - - log.info(marker, message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMarkerSupplier() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Supplier message = Mockito.mock(Supplier.class); - - log.info(marker, message); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMarkerSupplierThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Supplier message = Mockito.mock(Supplier.class); - Throwable ex = new Error(); - - log.info(marker, message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMarkerCharSequence() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - CharSequence message = Mockito.mock(CharSequence.class); - log.info(marker, message); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMarkerCharSequenceThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - CharSequence message = Mockito.mock(CharSequence.class); - Throwable ex = new Error(); - log.info(marker, message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMarkerObject() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Object message = new Object(); - log.info(marker, message); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMarkerObjectThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Object message = new Object(); - Throwable ex = new Error(); - log.info(marker, message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMarkerString() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - log.info(marker, message); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMarkerStringThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Throwable ex = new Error(); - log.info(marker, message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMarkerStringSupplierVararg() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Supplier p0 = Mockito.mock(Supplier.class); - Supplier p1 = Mockito.mock(Supplier.class); - Supplier p2 = Mockito.mock(Supplier.class); - Supplier p3 = Mockito.mock(Supplier.class); - Supplier p4 = Mockito.mock(Supplier.class); - Supplier p5 = Mockito.mock(Supplier.class); - Supplier p6 = Mockito.mock(Supplier.class); - Supplier p7 = Mockito.mock(Supplier.class); - Supplier p8 = Mockito.mock(Supplier.class); - Supplier p9 = Mockito.mock(Supplier.class); - Supplier pa = Mockito.mock(Supplier.class); - log.info(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMarkerStringVararg() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - Object p9 = new Object(); - Object pa = new Object(); - log.info(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMarkerStringP9() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - Object p9 = new Object(); - log.info(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMarkerStringP8() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - log.info(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMarkerStringP7() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - log.info(marker, message, p0, p1, p2, p3, p4, p5, p6, p7); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(marker, message, p0, p1, p2, p3, p4, p5, p6, p7); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMarkerStringP6() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - log.info(marker, message, p0, p1, p2, p3, p4, p5, p6); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(marker, message, p0, p1, p2, p3, p4, p5, p6); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMarkerStringP5() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - log.info(marker, message, p0, p1, p2, p3, p4, p5); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(marker, message, p0, p1, p2, p3, p4, p5); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMarkerStringP4() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - log.info(marker, message, p0, p1, p2, p3, p4); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(marker, message, p0, p1, p2, p3, p4); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMarkerStringP3() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - log.info(marker, message, p0, p1, p2, p3); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(marker, message, p0, p1, p2, p3); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMarkerStringP2() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - log.info(marker, message, p0, p1, p2); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(marker, message, p0, p1, p2); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMarkerStringP1() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - log.info(marker, message, p0, p1); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(marker, message, p0, p1); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testMarkerInfoStringP0() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - log.info(marker, message, p0); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(marker, message, p0); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMessage() { - Logger log = LogManager.getLogger(getClass()); - - Message message = Mockito.mock(Message.class); - - log.info(message); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMessageThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Message message = Mockito.mock(Message.class); - Throwable ex = new Error(); - - log.info(message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMessageSupplier() { - Logger log = LogManager.getLogger(getClass()); - - MessageSupplier message = Mockito.mock(MessageSupplier.class); - - log.info(message); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoMessageSupplierThrowable() { - Logger log = LogManager.getLogger(getClass()); - - MessageSupplier message = Mockito.mock(MessageSupplier.class); - Throwable ex = new Error(); - - log.info(message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoSupplier() { - Logger log = LogManager.getLogger(getClass()); - - Supplier message = Mockito.mock(Supplier.class); - - log.info(message); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoSupplierThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Supplier message = Mockito.mock(Supplier.class); - Throwable ex = new Error(); - - log.info(message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoCharSequence() { - Logger log = LogManager.getLogger(getClass()); - - CharSequence message = Mockito.mock(CharSequence.class); - log.info(message); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoCharSequenceThrowable() { - Logger log = LogManager.getLogger(getClass()); - - CharSequence message = Mockito.mock(CharSequence.class); - Throwable ex = new Error(); - log.info(message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoObject() { - Logger log = LogManager.getLogger(getClass()); - - Object message = new Object(); - log.info(message); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoObjectThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Object message = new Object(); - Throwable ex = new Error(); - log.info(message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoString() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - log.info(message); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoStringThrowable() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Throwable ex = new Error(); - log.info(message, ex); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoStringSupplierVararg() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Supplier p0 = Mockito.mock(Supplier.class); - Supplier p1 = Mockito.mock(Supplier.class); - Supplier p2 = Mockito.mock(Supplier.class); - Supplier p3 = Mockito.mock(Supplier.class); - Supplier p4 = Mockito.mock(Supplier.class); - Supplier p5 = Mockito.mock(Supplier.class); - Supplier p6 = Mockito.mock(Supplier.class); - Supplier p7 = Mockito.mock(Supplier.class); - Supplier p8 = Mockito.mock(Supplier.class); - Supplier p9 = Mockito.mock(Supplier.class); - Supplier pa = Mockito.mock(Supplier.class); - log.info(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoStringVararg() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - Object p9 = new Object(); - Object pa = new Object(); - log.info(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoStringP9() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - Object p9 = new Object(); - log.info(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoStringP8() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - log.info(message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoStringP7() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - log.info(message, p0, p1, p2, p3, p4, p5, p6, p7); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(message, p0, p1, p2, p3, p4, p5, p6, p7); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoStringP6() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - log.info(message, p0, p1, p2, p3, p4, p5, p6); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(message, p0, p1, p2, p3, p4, p5, p6); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoStringP5() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - log.info(message, p0, p1, p2, p3, p4, p5); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(message, p0, p1, p2, p3, p4, p5); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoStringP4() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - log.info(message, p0, p1, p2, p3, p4); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(message, p0, p1, p2, p3, p4); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoStringP3() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - log.info(message, p0, p1, p2, p3); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(message, p0, p1, p2, p3); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoStringP2() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - log.info(message, p0, p1, p2); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(message, p0, p1, p2); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoStringP1() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - log.info(message, p0, p1); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(message, p0, p1); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testInfoStringP0() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - log.info(message, p0); - - verifyMockContext(); - Mockito.verify(_mockLogger).info(message, p0); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testDebugMarkerMessage() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Message message = Mockito.mock(Message.class); - - log.debug(marker, message); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - - log.debug(marker, message); - - Mockito.verify(_mockLogger).debug(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugMarkerMessageThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Message message = Mockito.mock(Message.class); - Throwable ex = new Error(); - - log.debug(marker, message, ex); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(marker, message, ex); - - Mockito.verify(_mockLogger).debug(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugMarkerMessageSupplier() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - MessageSupplier message = Mockito.mock(MessageSupplier.class); - - log.debug(marker, message); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(marker, message); - - Mockito.verify(_mockLogger).debug(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugMarkerMessageSupplierThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - MessageSupplier message = Mockito.mock(MessageSupplier.class); - Throwable ex = new Error(); - - log.debug(marker, message, ex); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(marker, message, ex); - - Mockito.verify(_mockLogger).debug(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugMarkerSupplier() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Supplier message = Mockito.mock(Supplier.class); - - log.debug(marker, message); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(marker, message); - - Mockito.verify(_mockLogger).debug(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugMarkerSupplierThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Supplier message = Mockito.mock(Supplier.class); - Throwable ex = new Error(); - - log.debug(marker, message, ex); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(marker, message, ex); - - Mockito.verify(_mockLogger).debug(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugMarkerCharSequence() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - CharSequence message = Mockito.mock(CharSequence.class); - log.debug(marker, message); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(marker, message); - - Mockito.verify(_mockLogger).debug(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugMarkerCharSequenceThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - CharSequence message = Mockito.mock(CharSequence.class); - Throwable ex = new Error(); - log.debug(marker, message, ex); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(marker, message, ex); - - Mockito.verify(_mockLogger).debug(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugMarkerObject() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Object message = new Object(); - log.debug(marker, message); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(marker, message); - - Mockito.verify(_mockLogger).debug(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugMarkerObjectThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Object message = new Object(); - Throwable ex = new Error(); - log.debug(marker, message, ex); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(marker, message, ex); - - Mockito.verify(_mockLogger).debug(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugMarkerString() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - log.debug(marker, message); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(marker, message); - - Mockito.verify(_mockLogger).debug(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugMarkerStringThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Throwable ex = new Error(); - log.debug(marker, message, ex); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(marker, message, ex); - - Mockito.verify(_mockLogger).debug(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugMarkerStringSupplierVararg() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Supplier p0 = Mockito.mock(Supplier.class); - Supplier p1 = Mockito.mock(Supplier.class); - Supplier p2 = Mockito.mock(Supplier.class); - Supplier p3 = Mockito.mock(Supplier.class); - Supplier p4 = Mockito.mock(Supplier.class); - Supplier p5 = Mockito.mock(Supplier.class); - Supplier p6 = Mockito.mock(Supplier.class); - Supplier p7 = Mockito.mock(Supplier.class); - Supplier p8 = Mockito.mock(Supplier.class); - Supplier p9 = Mockito.mock(Supplier.class); - Supplier pa = Mockito.mock(Supplier.class); - log.debug(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - Mockito.verify(_mockLogger).debug(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugMarkerStringVararg() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - Object p9 = new Object(); - Object pa = new Object(); - log.debug(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - Mockito.verify(_mockLogger).debug(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugMarkerStringP9() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - Object p9 = new Object(); - log.debug(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - - Mockito.verify(_mockLogger).debug(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugMarkerStringP8() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - log.debug(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - - Mockito.verify(_mockLogger).debug(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugMarkerStringP7() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - log.debug(marker, message, p0, p1, p2, p3, p4, p5, p6, p7); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(marker, message, p0, p1, p2, p3, p4, p5, p6, p7); - - Mockito.verify(_mockLogger).debug(marker, message, p0, p1, p2, p3, p4, p5, p6, p7); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugMarkerStringP6() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - log.debug(marker, message, p0, p1, p2, p3, p4, p5, p6); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(marker, message, p0, p1, p2, p3, p4, p5, p6); - - Mockito.verify(_mockLogger).debug(marker, message, p0, p1, p2, p3, p4, p5, p6); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugMarkerStringP5() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - log.debug(marker, message, p0, p1, p2, p3, p4, p5); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(marker, message, p0, p1, p2, p3, p4, p5); - - Mockito.verify(_mockLogger).debug(marker, message, p0, p1, p2, p3, p4, p5); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugMarkerStringP4() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - log.debug(marker, message, p0, p1, p2, p3, p4); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(marker, message, p0, p1, p2, p3, p4); - - Mockito.verify(_mockLogger).debug(marker, message, p0, p1, p2, p3, p4); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugMarkerStringP3() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - log.debug(marker, message, p0, p1, p2, p3); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(marker, message, p0, p1, p2, p3); - - Mockito.verify(_mockLogger).debug(marker, message, p0, p1, p2, p3); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugMarkerStringP2() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - log.debug(marker, message, p0, p1, p2); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(marker, message, p0, p1, p2); - - Mockito.verify(_mockLogger).debug(marker, message, p0, p1, p2); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugMarkerStringP1() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - log.debug(marker, message, p0, p1); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(marker, message, p0, p1); - - Mockito.verify(_mockLogger).debug(marker, message, p0, p1); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testMarkerDebugStringP0() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - log.debug(marker, message, p0); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(marker, message, p0); - - Mockito.verify(_mockLogger).debug(marker, message, p0); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugMessage() { - Logger log = LogManager.getLogger(getClass()); - - Message message = Mockito.mock(Message.class); - - log.debug(message); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(message); - - Mockito.verify(_mockLogger).debug(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugMessageThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Message message = Mockito.mock(Message.class); - Throwable ex = new Error(); - - log.debug(message, ex); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(message, ex); - - Mockito.verify(_mockLogger).debug(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugMessageSupplier() { - Logger log = LogManager.getLogger(getClass()); - - MessageSupplier message = Mockito.mock(MessageSupplier.class); - - log.debug(message); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(message); - - Mockito.verify(_mockLogger).debug(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugMessageSupplierThrowable() { - Logger log = LogManager.getLogger(getClass()); - - MessageSupplier message = Mockito.mock(MessageSupplier.class); - Throwable ex = new Error(); - - log.debug(message, ex); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(message, ex); - - Mockito.verify(_mockLogger).debug(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugSupplier() { - Logger log = LogManager.getLogger(getClass()); - - Supplier message = Mockito.mock(Supplier.class); - - log.debug(message); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(message); - - Mockito.verify(_mockLogger).debug(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugSupplierThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Supplier message = Mockito.mock(Supplier.class); - Throwable ex = new Error(); - - log.debug(message, ex); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(message, ex); - - Mockito.verify(_mockLogger).debug(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugCharSequence() { - Logger log = LogManager.getLogger(getClass()); - - CharSequence message = Mockito.mock(CharSequence.class); - log.debug(message); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(message); - - Mockito.verify(_mockLogger).debug(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugCharSequenceThrowable() { - Logger log = LogManager.getLogger(getClass()); - - CharSequence message = Mockito.mock(CharSequence.class); - Throwable ex = new Error(); - log.debug(message, ex); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(message, ex); - - Mockito.verify(_mockLogger).debug(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugObject() { - Logger log = LogManager.getLogger(getClass()); - - Object message = new Object(); - log.debug(message); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(message); - - Mockito.verify(_mockLogger).debug(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugObjectThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Object message = new Object(); - Throwable ex = new Error(); - log.debug(message, ex); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(message, ex); - - Mockito.verify(_mockLogger).debug(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugString() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - log.debug(message); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(message); - - Mockito.verify(_mockLogger).debug(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugStringThrowable() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Throwable ex = new Error(); - log.debug(message, ex); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(message, ex); - - Mockito.verify(_mockLogger).debug(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugStringSupplierVararg() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Supplier p0 = Mockito.mock(Supplier.class); - Supplier p1 = Mockito.mock(Supplier.class); - Supplier p2 = Mockito.mock(Supplier.class); - Supplier p3 = Mockito.mock(Supplier.class); - Supplier p4 = Mockito.mock(Supplier.class); - Supplier p5 = Mockito.mock(Supplier.class); - Supplier p6 = Mockito.mock(Supplier.class); - Supplier p7 = Mockito.mock(Supplier.class); - Supplier p8 = Mockito.mock(Supplier.class); - Supplier p9 = Mockito.mock(Supplier.class); - Supplier pa = Mockito.mock(Supplier.class); - log.debug(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - Mockito.verify(_mockLogger).debug(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugStringVararg() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - Object p9 = new Object(); - Object pa = new Object(); - log.debug(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - Mockito.verify(_mockLogger).debug(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugStringP9() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - Object p9 = new Object(); - log.debug(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - - Mockito.verify(_mockLogger).debug(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugStringP8() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - log.debug(message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - - Mockito.verify(_mockLogger).debug(message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugStringP7() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - log.debug(message, p0, p1, p2, p3, p4, p5, p6, p7); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(message, p0, p1, p2, p3, p4, p5, p6, p7); - - Mockito.verify(_mockLogger).debug(message, p0, p1, p2, p3, p4, p5, p6, p7); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugStringP6() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - log.debug(message, p0, p1, p2, p3, p4, p5, p6); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(message, p0, p1, p2, p3, p4, p5, p6); - - Mockito.verify(_mockLogger).debug(message, p0, p1, p2, p3, p4, p5, p6); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugStringP5() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - log.debug(message, p0, p1, p2, p3, p4, p5); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(message, p0, p1, p2, p3, p4, p5); - - Mockito.verify(_mockLogger).debug(message, p0, p1, p2, p3, p4, p5); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugStringP4() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - log.debug(message, p0, p1, p2, p3, p4); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(message, p0, p1, p2, p3, p4); - - Mockito.verify(_mockLogger).debug(message, p0, p1, p2, p3, p4); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugStringP3() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - log.debug(message, p0, p1, p2, p3); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(message, p0, p1, p2, p3); - - Mockito.verify(_mockLogger).debug(message, p0, p1, p2, p3); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugStringP2() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - log.debug(message, p0, p1, p2); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(message, p0, p1, p2); - - Mockito.verify(_mockLogger).debug(message, p0, p1, p2); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugStringP1() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - log.debug(message, p0, p1); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(message, p0, p1); - - Mockito.verify(_mockLogger).debug(message, p0, p1); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testDebugStringP0() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - log.debug(message, p0); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - log.debug(message, p0); - - Mockito.verify(_mockLogger).debug(message, p0); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testTraceMarkerMessage() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Message message = Mockito.mock(Message.class); - - log.trace(marker, message); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - - log.trace(marker, message); - - Mockito.verify(_mockLogger).trace(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceMarkerMessageThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Message message = Mockito.mock(Message.class); - Throwable ex = new Error(); - - log.trace(marker, message, ex); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(marker, message, ex); - - Mockito.verify(_mockLogger).trace(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceMarkerMessageSupplier() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - MessageSupplier message = Mockito.mock(MessageSupplier.class); - - log.trace(marker, message); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(marker, message); - - Mockito.verify(_mockLogger).trace(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceMarkerMessageSupplierThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - MessageSupplier message = Mockito.mock(MessageSupplier.class); - Throwable ex = new Error(); - - log.trace(marker, message, ex); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(marker, message, ex); - - Mockito.verify(_mockLogger).trace(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceMarkerSupplier() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Supplier message = Mockito.mock(Supplier.class); - - log.trace(marker, message); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(marker, message); - - Mockito.verify(_mockLogger).trace(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceMarkerSupplierThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Supplier message = Mockito.mock(Supplier.class); - Throwable ex = new Error(); - - log.trace(marker, message, ex); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(marker, message, ex); - - Mockito.verify(_mockLogger).trace(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceMarkerCharSequence() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - CharSequence message = Mockito.mock(CharSequence.class); - log.trace(marker, message); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(marker, message); - - Mockito.verify(_mockLogger).trace(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceMarkerCharSequenceThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - CharSequence message = Mockito.mock(CharSequence.class); - Throwable ex = new Error(); - log.trace(marker, message, ex); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(marker, message, ex); - - Mockito.verify(_mockLogger).trace(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceMarkerObject() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Object message = new Object(); - log.trace(marker, message); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(marker, message); - - Mockito.verify(_mockLogger).trace(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceMarkerObjectThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Object message = new Object(); - Throwable ex = new Error(); - log.trace(marker, message, ex); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(marker, message, ex); - - Mockito.verify(_mockLogger).trace(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceMarkerString() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - log.trace(marker, message); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(marker, message); - - Mockito.verify(_mockLogger).trace(Mockito.same(marker), Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceMarkerStringThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Throwable ex = new Error(); - log.trace(marker, message, ex); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(marker, message, ex); - - Mockito.verify(_mockLogger).trace(Mockito.same(marker), Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceMarkerStringSupplierVararg() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Supplier p0 = Mockito.mock(Supplier.class); - Supplier p1 = Mockito.mock(Supplier.class); - Supplier p2 = Mockito.mock(Supplier.class); - Supplier p3 = Mockito.mock(Supplier.class); - Supplier p4 = Mockito.mock(Supplier.class); - Supplier p5 = Mockito.mock(Supplier.class); - Supplier p6 = Mockito.mock(Supplier.class); - Supplier p7 = Mockito.mock(Supplier.class); - Supplier p8 = Mockito.mock(Supplier.class); - Supplier p9 = Mockito.mock(Supplier.class); - Supplier pa = Mockito.mock(Supplier.class); - log.trace(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - Mockito.verify(_mockLogger).trace(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceMarkerStringVararg() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - Object p9 = new Object(); - Object pa = new Object(); - log.trace(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - Mockito.verify(_mockLogger).trace(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceMarkerStringP9() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - Object p9 = new Object(); - log.trace(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - - Mockito.verify(_mockLogger).trace(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceMarkerStringP8() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - log.trace(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - - Mockito.verify(_mockLogger).trace(marker, message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceMarkerStringP7() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - log.trace(marker, message, p0, p1, p2, p3, p4, p5, p6, p7); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(marker, message, p0, p1, p2, p3, p4, p5, p6, p7); - - Mockito.verify(_mockLogger).trace(marker, message, p0, p1, p2, p3, p4, p5, p6, p7); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceMarkerStringP6() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - log.trace(marker, message, p0, p1, p2, p3, p4, p5, p6); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(marker, message, p0, p1, p2, p3, p4, p5, p6); - - Mockito.verify(_mockLogger).trace(marker, message, p0, p1, p2, p3, p4, p5, p6); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceMarkerStringP5() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - log.trace(marker, message, p0, p1, p2, p3, p4, p5); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(marker, message, p0, p1, p2, p3, p4, p5); - - Mockito.verify(_mockLogger).trace(marker, message, p0, p1, p2, p3, p4, p5); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceMarkerStringP4() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - log.trace(marker, message, p0, p1, p2, p3, p4); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(marker, message, p0, p1, p2, p3, p4); - - Mockito.verify(_mockLogger).trace(marker, message, p0, p1, p2, p3, p4); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceMarkerStringP3() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - log.trace(marker, message, p0, p1, p2, p3); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(marker, message, p0, p1, p2, p3); - - Mockito.verify(_mockLogger).trace(marker, message, p0, p1, p2, p3); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceMarkerStringP2() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - log.trace(marker, message, p0, p1, p2); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(marker, message, p0, p1, p2); - - Mockito.verify(_mockLogger).trace(marker, message, p0, p1, p2); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceMarkerStringP1() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - log.trace(marker, message, p0, p1); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(marker, message, p0, p1); - - Mockito.verify(_mockLogger).trace(marker, message, p0, p1); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testMarkerTraceStringP0() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - String message = "Hello World"; - Object p0 = new Object(); - log.trace(marker, message, p0); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(marker, message, p0); - - Mockito.verify(_mockLogger).trace(marker, message, p0); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceMessage() { - Logger log = LogManager.getLogger(getClass()); - - Message message = Mockito.mock(Message.class); - - log.trace(message); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(message); - - Mockito.verify(_mockLogger).trace(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceMessageThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Message message = Mockito.mock(Message.class); - Throwable ex = new Error(); - - log.trace(message, ex); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(message, ex); - - Mockito.verify(_mockLogger).trace(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceMessageSupplier() { - Logger log = LogManager.getLogger(getClass()); - - MessageSupplier message = Mockito.mock(MessageSupplier.class); - - log.trace(message); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(message); - - Mockito.verify(_mockLogger).trace(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceMessageSupplierThrowable() { - Logger log = LogManager.getLogger(getClass()); - - MessageSupplier message = Mockito.mock(MessageSupplier.class); - Throwable ex = new Error(); - - log.trace(message, ex); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(message, ex); - - Mockito.verify(_mockLogger).trace(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceSupplier() { - Logger log = LogManager.getLogger(getClass()); - - Supplier message = Mockito.mock(Supplier.class); - - log.trace(message); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(message); - - Mockito.verify(_mockLogger).trace(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceSupplierThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Supplier message = Mockito.mock(Supplier.class); - Throwable ex = new Error(); - - log.trace(message, ex); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(message, ex); - - Mockito.verify(_mockLogger).trace(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceCharSequence() { - Logger log = LogManager.getLogger(getClass()); - - CharSequence message = Mockito.mock(CharSequence.class); - log.trace(message); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(message); - - Mockito.verify(_mockLogger).trace(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceCharSequenceThrowable() { - Logger log = LogManager.getLogger(getClass()); - - CharSequence message = Mockito.mock(CharSequence.class); - Throwable ex = new Error(); - log.trace(message, ex); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(message, ex); - - Mockito.verify(_mockLogger).trace(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceObject() { - Logger log = LogManager.getLogger(getClass()); - - Object message = new Object(); - log.trace(message); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(message); - - Mockito.verify(_mockLogger).trace(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceObjectThrowable() { - Logger log = LogManager.getLogger(getClass()); - - Object message = new Object(); - Throwable ex = new Error(); - log.trace(message, ex); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(message, ex); - - Mockito.verify(_mockLogger).trace(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceString() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - log.trace(message); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(message); - - Mockito.verify(_mockLogger).trace(Mockito.same(message)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceStringThrowable() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Throwable ex = new Error(); - log.trace(message, ex); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(message, ex); - - Mockito.verify(_mockLogger).trace(Mockito.same(message), Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceStringSupplierVararg() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Supplier p0 = Mockito.mock(Supplier.class); - Supplier p1 = Mockito.mock(Supplier.class); - Supplier p2 = Mockito.mock(Supplier.class); - Supplier p3 = Mockito.mock(Supplier.class); - Supplier p4 = Mockito.mock(Supplier.class); - Supplier p5 = Mockito.mock(Supplier.class); - Supplier p6 = Mockito.mock(Supplier.class); - Supplier p7 = Mockito.mock(Supplier.class); - Supplier p8 = Mockito.mock(Supplier.class); - Supplier p9 = Mockito.mock(Supplier.class); - Supplier pa = Mockito.mock(Supplier.class); - log.trace(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - Mockito.verify(_mockLogger).trace(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceStringVararg() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - Object p9 = new Object(); - Object pa = new Object(); - log.trace(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - - Mockito.verify(_mockLogger).trace(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceStringP9() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - Object p9 = new Object(); - log.trace(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - - Mockito.verify(_mockLogger).trace(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceStringP8() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - Object p8 = new Object(); - log.trace(message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - - Mockito.verify(_mockLogger).trace(message, p0, p1, p2, p3, p4, p5, p6, p7, p8); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceStringP7() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - Object p7 = new Object(); - log.trace(message, p0, p1, p2, p3, p4, p5, p6, p7); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(message, p0, p1, p2, p3, p4, p5, p6, p7); - - Mockito.verify(_mockLogger).trace(message, p0, p1, p2, p3, p4, p5, p6, p7); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceStringP6() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - Object p6 = new Object(); - log.trace(message, p0, p1, p2, p3, p4, p5, p6); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(message, p0, p1, p2, p3, p4, p5, p6); - - Mockito.verify(_mockLogger).trace(message, p0, p1, p2, p3, p4, p5, p6); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceStringP5() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - Object p5 = new Object(); - log.trace(message, p0, p1, p2, p3, p4, p5); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(message, p0, p1, p2, p3, p4, p5); - - Mockito.verify(_mockLogger).trace(message, p0, p1, p2, p3, p4, p5); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceStringP4() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - Object p4 = new Object(); - log.trace(message, p0, p1, p2, p3, p4); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(message, p0, p1, p2, p3, p4); - - Mockito.verify(_mockLogger).trace(message, p0, p1, p2, p3, p4); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceStringP3() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - Object p3 = new Object(); - log.trace(message, p0, p1, p2, p3); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(message, p0, p1, p2, p3); - - Mockito.verify(_mockLogger).trace(message, p0, p1, p2, p3); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceStringP2() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - Object p2 = new Object(); - log.trace(message, p0, p1, p2); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(message, p0, p1, p2); - - Mockito.verify(_mockLogger).trace(message, p0, p1, p2); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceStringP1() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - Object p1 = new Object(); - log.trace(message, p0, p1); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(message, p0, p1); - - Mockito.verify(_mockLogger).trace(message, p0, p1); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceStringP0() { - Logger log = LogManager.getLogger(getClass()); - - String message = "Hello World"; - Object p0 = new Object(); - log.trace(message, p0); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.trace(message, p0); - - Mockito.verify(_mockLogger).trace(message, p0); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceCatching() { - Logger log = LogManager.getLogger(getClass()); - - Throwable ex = new Error(); - log.catching(ex); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.catching(ex); - - Mockito.verify(_mockLogger).catching(Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceEntry() { - Logger log = LogManager.getLogger(getClass()); - - log.entry(); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.entry(); - - Mockito.verify(_mockLogger).entry(); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceEntryVarargs() { - Logger log = LogManager.getLogger(getClass()); - - Object o = new Object(); - log.entry(o); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.entry(o); - - Mockito.verify(_mockLogger).entry(Mockito.same(o)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceExit() { - Logger log = LogManager.getLogger(getClass()); - - log.exit(); - log.traceExit(); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - log.exit(); - log.traceExit(); - - Mockito.verify(_mockLogger).exit(); - Mockito.verify(_mockLogger).traceExit(); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceExitArg() { - Logger log = LogManager.getLogger(getClass()); - - Mockito.when(_mockLogger.exit(Mockito.any())).thenAnswer(invocation -> invocation.getArgument(0)); - Mockito.when(_mockLogger.traceExit(Mockito.any(Object.class))).thenAnswer(invocation -> invocation.getArgument(0)); - - Object o = new Object(); - Assert.assertSame(log.exit(o), o); - Assert.assertSame(log.traceExit(o), o); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - Assert.assertSame(log.exit(o), o); - Assert.assertSame(log.traceExit(o), o); - - Mockito.verify(_mockLogger).exit(Mockito.same(o)); - Mockito.verify(_mockLogger).traceExit(Mockito.same(o)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceEntryExit() { - Logger log = LogManager.getLogger(getClass()); - - EntryMessage msg1 = log.traceEntry(); - Assert.assertNotNull(msg1); - log.traceExit(msg1); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - - log.traceExit(msg1); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Mockito.doReturn(Mockito.mock(EntryMessage.class)).when(_mockLogger).traceEntry(); - - EntryMessage msg3 = log.traceEntry(); - Assert.assertNotNull(msg1); - log.traceExit(msg3); - - Mockito.verify(_mockLogger).traceEntry(); - Mockito.verify(_mockLogger).traceExit(Mockito.same(msg3)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceEntryExitArg() { - Logger log = LogManager.getLogger(getClass()); - - Mockito.when(_mockLogger.traceExit(Mockito.any(EntryMessage.class), Mockito.any(Object.class))) - .thenAnswer(invocation -> invocation.getArgument(1)); - Mockito.when(_mockLogger.traceExit(Mockito.any(String.class), Mockito.any(Object.class))) - .thenAnswer(invocation -> invocation.getArgument(1)); - Mockito.when(_mockLogger.traceExit(Mockito.any(Message.class), Mockito.any(Object.class))) - .thenAnswer(invocation -> invocation.getArgument(1)); - - Object o = new Object(); - Message msg0 = Mockito.mock(Message.class); - EntryMessage e0 = log.traceEntry(msg0); - Assert.assertNotNull(e0); - Assert.assertSame(log.traceExit(e0, o), o); - Assert.assertSame(log.traceExit("foo", o), o); - Assert.assertSame(log.traceExit(Mockito.mock(Message.class), o), o); - - String msg2 = "Hello world"; - Assert.assertSame(log.traceEntry(msg2), e0); - Assert.assertSame(log.traceEntry(msg2, Mockito.mock(Supplier.class)), e0); - Supplier msg1 = Mockito.mock(Supplier.class); - Assert.assertSame(log.traceEntry(msg1), e0); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - - Assert.assertSame(log.traceExit(e0, o), o); - Mockito.verifyNoMoreInteractions(_mockLogger); - - EntryMessage r1 = Mockito.mock(EntryMessage.class); - EntryMessage r2 = Mockito.mock(EntryMessage.class); - EntryMessage r3 = Mockito.mock(EntryMessage.class); - EntryMessage r4 = Mockito.mock(EntryMessage.class); - - Mockito.doReturn(r1).when(_mockLogger).traceEntry(Mockito.any(Message.class)); - Mockito.doReturn(r2).when(_mockLogger).traceEntry(Mockito.anyString(), Mockito.anyString()); - Mockito.doReturn(r3).when(_mockLogger).traceEntry(Mockito.anyString(), Mockito.any(Supplier.class)); - Mockito.doReturn(r4).when(_mockLogger).traceEntry(Mockito.any(Supplier.class)); - - Assert.assertSame(log.traceEntry(msg0), r1); - String obj = "arg"; - Assert.assertSame(log.traceEntry(msg2, obj), r2); - Supplier supplier = Mockito.mock(Supplier.class); - Assert.assertSame(log.traceEntry(msg2, supplier), r3); - Assert.assertSame(log.traceEntry(msg1), r4); - - Assert.assertSame(log.traceExit(r1, o), o); - Assert.assertSame(log.traceExit(msg2, o), o); - - Message msg4 = Mockito.mock(Message.class); - Assert.assertSame(log.traceExit(msg4, o), o); - - Mockito.verify(_mockLogger).traceEntry(Mockito.same(msg0)); - Mockito.verify(_mockLogger).traceEntry(Mockito.same(msg1)); - Mockito.verify(_mockLogger).traceEntry(Mockito.same(msg2), Mockito.same(obj)); - Mockito.verify(_mockLogger).traceEntry(Mockito.same(msg2), Mockito.same(supplier)); - Mockito.verify(_mockLogger).traceExit(Mockito.same(r1), Mockito.same(o)); - Mockito.verify(_mockLogger).traceExit(Mockito.same(msg2), Mockito.same(o)); - Mockito.verify(_mockLogger).traceExit(Mockito.same(msg4), Mockito.same(o)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testTraceThrowing() { - Logger log = LogManager.getLogger(getClass()); - - Mockito.doAnswer(invocation -> invocation.getArgument(0)).when(_mockLogger).throwing(Mockito.any(Throwable.class)); - - Throwable ex = new Error(); - Assert.assertSame(log.throwing(ex), ex); - - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - Assert.assertSame(log.throwing(ex), ex); - - Mockito.verify(_mockLogger).throwing(Mockito.same(ex)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testGetLevel() { - Logger log = LogManager.getLogger(getClass()); - Level level = Level.forName("TEST", 42); - - Mockito.doReturn(level).when(_mockLogger).getLevel(); - - Assert.assertSame(log.getLevel(), level); - verifyMockContext(); - Mockito.verify(_mockLogger).getLevel(); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testGetMessageFactory() { - Logger log = LogManager.getLogger(getClass()); - MessageFactory factory = Mockito.mock(MessageFactory.class); - - Mockito.doReturn(factory).when(_mockLogger).getMessageFactory(); - - Assert.assertSame(log.getMessageFactory(), factory); - verifyMockContext(); - Mockito.verify(_mockLogger).getMessageFactory(); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testGetName() { - Logger log = LogManager.getLogger(getClass()); - String name = "Hwllo world!"; - - Mockito.doReturn(name).when(_mockLogger).getName(); - - Assert.assertSame(log.getName(), name); - verifyMockContext(); - Mockito.verify(_mockLogger).getName(); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testIsDebugEnabled() { - Logger log = LogManager.getLogger(getClass()); - - Assert.assertFalse(log.isDebugEnabled()); - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - - Assert.assertFalse(log.isDebugEnabled()); - Mockito.verify(_mockLogger).isDebugEnabled(); - - Mockito.reset(_mockLogger); - Mockito.doReturn(true).when(_mockLogger).isDebugEnabled(); - - Assert.assertTrue(log.isDebugEnabled()); - Mockito.verify(_mockLogger).isDebugEnabled(); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testIsDebugEnabledMarker() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Assert.assertFalse(log.isDebugEnabled(marker)); - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setDebug(true); - - Assert.assertFalse(log.isDebugEnabled(marker)); - Mockito.verify(_mockLogger).isDebugEnabled(Mockito.same(marker)); - - Mockito.reset(_mockLogger); - Mockito.doReturn(true).when(_mockLogger).isDebugEnabled(Mockito.any(Marker.class)); - - Assert.assertTrue(log.isDebugEnabled(marker)); - Mockito.verify(_mockLogger).isDebugEnabled(Mockito.same(marker)); - } finally { - _mBean.setDebug(false); - } - } - - @Test - public void testIsTraceEnabled() { - Logger log = LogManager.getLogger(getClass()); - - Assert.assertFalse(log.isTraceEnabled()); - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - - Assert.assertFalse(log.isTraceEnabled()); - Mockito.verify(_mockLogger).isTraceEnabled(); - - Mockito.reset(_mockLogger); - Mockito.doReturn(true).when(_mockLogger).isTraceEnabled(); - - Assert.assertTrue(log.isTraceEnabled()); - Mockito.verify(_mockLogger).isTraceEnabled(); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testIsTraceEnabledMarker() { - Logger log = LogManager.getLogger(getClass()); - - Marker marker = Mockito.mock(Marker.class); - Assert.assertFalse(log.isTraceEnabled(marker)); - verifyMockContext(); - Mockito.verifyNoMoreInteractions(_mockLogger); - - try { - _mBean.setTrace(true); - - Assert.assertFalse(log.isTraceEnabled(marker)); - Mockito.verify(_mockLogger).isTraceEnabled(Mockito.same(marker)); - - Mockito.reset(_mockLogger); - Mockito.doReturn(true).when(_mockLogger).isTraceEnabled(Mockito.any(Marker.class)); - - Assert.assertTrue(log.isTraceEnabled(marker)); - Mockito.verify(_mockLogger).isTraceEnabled(Mockito.same(marker)); - } finally { - _mBean.setTrace(false); - } - } - - @Test - public void testIsInfoEnabled() { - Logger log = LogManager.getLogger(getClass()); - Assert.assertFalse(log.isInfoEnabled()); - Mockito.doReturn(true).when(_mockLogger).isInfoEnabled(); - Assert.assertTrue(log.isInfoEnabled()); - verifyMockContext(); - Mockito.verify(_mockLogger, Mockito.times(2)).isInfoEnabled(); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testIsWarnEnabled() { - Logger log = LogManager.getLogger(getClass()); - Assert.assertFalse(log.isWarnEnabled()); - Mockito.doReturn(true).when(_mockLogger).isWarnEnabled(); - Assert.assertTrue(log.isWarnEnabled()); - verifyMockContext(); - Mockito.verify(_mockLogger, Mockito.times(2)).isWarnEnabled(); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testIsErrorEnabled() { - Logger log = LogManager.getLogger(getClass()); - Assert.assertFalse(log.isErrorEnabled()); - Mockito.doReturn(true).when(_mockLogger).isErrorEnabled(); - Assert.assertTrue(log.isErrorEnabled()); - verifyMockContext(); - Mockito.verify(_mockLogger, Mockito.times(2)).isErrorEnabled(); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testIsFatalEnabled() { - Logger log = LogManager.getLogger(getClass()); - Assert.assertFalse(log.isFatalEnabled()); - Mockito.doReturn(true).when(_mockLogger).isFatalEnabled(); - Assert.assertTrue(log.isFatalEnabled()); - verifyMockContext(); - Mockito.verify(_mockLogger, Mockito.times(2)).isFatalEnabled(); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testIsInfoEnabledMarker() { - Logger log = LogManager.getLogger(getClass()); - Marker marker = Mockito.mock(Marker.class); - Assert.assertFalse(log.isInfoEnabled(marker)); - Mockito.doReturn(true).when(_mockLogger).isInfoEnabled(Mockito.any(Marker.class)); - Assert.assertTrue(log.isInfoEnabled(marker)); - verifyMockContext(); - Mockito.verify(_mockLogger, Mockito.times(2)).isInfoEnabled(Mockito.same(marker)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testIsWarnEnabledMarker() { - Logger log = LogManager.getLogger(getClass()); - Marker marker = Mockito.mock(Marker.class); - Assert.assertFalse(log.isWarnEnabled(marker)); - Mockito.doReturn(true).when(_mockLogger).isWarnEnabled(Mockito.any(Marker.class)); - Assert.assertTrue(log.isWarnEnabled(marker)); - verifyMockContext(); - Mockito.verify(_mockLogger, Mockito.times(2)).isWarnEnabled(Mockito.same(marker)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testIsErrorEnabledMarker() { - Logger log = LogManager.getLogger(getClass()); - Marker marker = Mockito.mock(Marker.class); - Assert.assertFalse(log.isErrorEnabled(marker)); - Mockito.doReturn(true).when(_mockLogger).isErrorEnabled(Mockito.any(Marker.class)); - Assert.assertTrue(log.isErrorEnabled(marker)); - verifyMockContext(); - Mockito.verify(_mockLogger, Mockito.times(2)).isErrorEnabled(Mockito.same(marker)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testIsFatalEnabledMarker() { - Logger log = LogManager.getLogger(getClass()); - Marker marker = Mockito.mock(Marker.class); - Assert.assertFalse(log.isFatalEnabled(marker)); - Mockito.doReturn(true).when(_mockLogger).isFatalEnabled(Mockito.any(Marker.class)); - Assert.assertTrue(log.isFatalEnabled(marker)); - verifyMockContext(); - Mockito.verify(_mockLogger, Mockito.times(2)).isFatalEnabled(Mockito.same(marker)); - Mockito.verifyNoMoreInteractions(_mockLogger); - } - - @Test - public void testIsEnabled() { - Logger log = LogManager.getLogger(getClass()); - Assert.assertFalse(log.isEnabled(Level.TRACE)); - Assert.assertFalse(log.isEnabled(Level.DEBUG)); - Assert.assertFalse(log.isEnabled(Level.INFO)); - verifyMockContext(); - Mockito.verify(_mockLogger).isEnabled(Mockito.same(Level.INFO)); - Mockito.verifyNoMoreInteractions(_mockLogger); - Mockito.reset(_mockLogger); - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.INFO))).thenReturn(true); - Assert.assertTrue(log.isEnabled(Level.INFO)); - Mockito.verify(_mockLogger).isEnabled(Mockito.same(Level.INFO)); - Mockito.verifyNoMoreInteractions(_mockLogger); - Mockito.reset(_mockLogger); - - try { - _mBean.setDebug(true); - - Assert.assertFalse(log.isEnabled(Level.TRACE)); - Assert.assertFalse(log.isEnabled(Level.DEBUG)); - Mockito.verify(_mockLogger).isEnabled(Mockito.same(Level.DEBUG)); - Mockito.verifyNoMoreInteractions(_mockLogger); - Mockito.reset(_mockLogger); - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - Assert.assertFalse(log.isEnabled(Level.TRACE)); - Assert.assertTrue(log.isEnabled(Level.DEBUG)); - Mockito.verify(_mockLogger).isEnabled(Mockito.same(Level.DEBUG)); - Mockito.verifyNoMoreInteractions(_mockLogger); - Mockito.reset(_mockLogger); - - _mBean.setTrace(true); - - Assert.assertFalse(log.isEnabled(Level.TRACE)); - Assert.assertFalse(log.isEnabled(Level.DEBUG)); - Mockito.verify(_mockLogger).isEnabled(Mockito.same(Level.DEBUG)); - Mockito.verify(_mockLogger).isEnabled(Mockito.same(Level.TRACE)); - Mockito.verifyNoMoreInteractions(_mockLogger); - Mockito.reset(_mockLogger); - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.TRACE))).thenReturn(true); - Assert.assertTrue(log.isEnabled(Level.TRACE)); - Assert.assertFalse(log.isEnabled(Level.DEBUG)); - Mockito.verify(_mockLogger).isEnabled(Mockito.same(Level.DEBUG)); - Mockito.verify(_mockLogger).isEnabled(Mockito.same(Level.TRACE)); - Mockito.verifyNoMoreInteractions(_mockLogger); - Mockito.reset(_mockLogger); - - } finally { - _mBean.setDebug(false); - _mBean.setTrace(false); - } - } - - @Test - public void testIsEnabledMarker() { - Logger log = LogManager.getLogger(getClass()); - Marker marker = Mockito.mock(Marker.class); - Assert.assertFalse(log.isEnabled(Level.TRACE, marker)); - Assert.assertFalse(log.isEnabled(Level.DEBUG, marker)); - Assert.assertFalse(log.isEnabled(Level.INFO, marker)); - verifyMockContext(); - Mockito.verify(_mockLogger).isEnabled(Mockito.same(Level.INFO), Mockito.same(marker)); - Mockito.verifyNoMoreInteractions(_mockLogger); - Mockito.reset(_mockLogger); - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.INFO), Mockito.any(Marker.class))).thenReturn(true); - Assert.assertTrue(log.isEnabled(Level.INFO, marker)); - Mockito.verify(_mockLogger).isEnabled(Mockito.same(Level.INFO), Mockito.same(marker)); - Mockito.verifyNoMoreInteractions(_mockLogger); - Mockito.reset(_mockLogger); - - try { - _mBean.setDebug(true); - - Assert.assertFalse(log.isEnabled(Level.TRACE, marker)); - Assert.assertFalse(log.isEnabled(Level.DEBUG, marker)); - Mockito.verify(_mockLogger).isEnabled(Mockito.same(Level.DEBUG), Mockito.same(marker)); - Mockito.verifyNoMoreInteractions(_mockLogger); - Mockito.reset(_mockLogger); - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG), Mockito.any(Marker.class))).thenReturn(true); - Assert.assertFalse(log.isEnabled(Level.TRACE, marker)); - Assert.assertTrue(log.isEnabled(Level.DEBUG, marker)); - Mockito.verify(_mockLogger).isEnabled(Mockito.same(Level.DEBUG), Mockito.same(marker)); - Mockito.verifyNoMoreInteractions(_mockLogger); - Mockito.reset(_mockLogger); - - _mBean.setTrace(true); - - Assert.assertFalse(log.isEnabled(Level.TRACE, marker)); - Assert.assertFalse(log.isEnabled(Level.DEBUG, marker)); - Mockito.verify(_mockLogger).isEnabled(Mockito.same(Level.DEBUG), Mockito.same(marker)); - Mockito.verify(_mockLogger).isEnabled(Mockito.same(Level.TRACE), Mockito.same(marker)); - Mockito.verifyNoMoreInteractions(_mockLogger); - Mockito.reset(_mockLogger); - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.TRACE), Mockito.any(Marker.class))).thenReturn(true); - Assert.assertTrue(log.isEnabled(Level.TRACE, marker)); - Assert.assertFalse(log.isEnabled(Level.DEBUG, marker)); - Mockito.verify(_mockLogger).isEnabled(Mockito.same(Level.DEBUG), Mockito.same(marker)); - Mockito.verify(_mockLogger).isEnabled(Mockito.same(Level.TRACE), Mockito.same(marker)); - Mockito.verifyNoMoreInteractions(_mockLogger); - Mockito.reset(_mockLogger); - - } finally { - _mBean.setDebug(false); - _mBean.setTrace(false); - } - } - -} diff --git a/internal/alpini/common/alpini-common-native/build.gradle b/internal/alpini/common/alpini-common-native/build.gradle deleted file mode 100644 index 73049b3aa03..00000000000 --- a/internal/alpini/common/alpini-common-native/build.gradle +++ /dev/null @@ -1,8 +0,0 @@ -dependencies { - testImplementation libraries.testng - implementation libraries.log4j2api - implementation libraries.jna - implementation libraries.jsr305 -} - - diff --git a/internal/alpini/common/alpini-common-native/src/main/java/com/linkedin/alpini/jna/ThreadUtils.java b/internal/alpini/common/alpini-common-native/src/main/java/com/linkedin/alpini/jna/ThreadUtils.java deleted file mode 100644 index 253d5dbc114..00000000000 --- a/internal/alpini/common/alpini-common-native/src/main/java/com/linkedin/alpini/jna/ThreadUtils.java +++ /dev/null @@ -1,142 +0,0 @@ -package com.linkedin.alpini.jna; - -import com.sun.jna.Library; -import com.sun.jna.Native; -import com.sun.jna.Platform; -import com.sun.jna.WString; -import java.util.concurrent.ThreadFactory; -import javax.annotation.Nonnull; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -public final class ThreadUtils { - private static final Logger LOG = LogManager.getLogger(ThreadUtils.class); - - private ThreadUtils() { - } - - public enum OsPlatform { - LINUX, DARWIN, WINDOWS, UNKNOWN - } - - @Nonnull - public static OsPlatform getPlatform() { - return INTERFACE.getPlatform(); - } - - @Nonnull - public static ThreadFactory decorateName(@Nonnull ThreadFactory factory) { - return r -> factory.newThread(() -> { - setThreadName(); - r.run(); - }); - } - - public static void setThreadName() { - setThreadName(Thread.currentThread().getName()); - } - - public static void setThreadName(@Nonnull String name) { - INTERFACE.setThreadName(name); - } - - private interface NativeInterface { - @Nonnull - OsPlatform getPlatform(); - - void setThreadName(String name); - } - - public interface LinuxCLib extends Library { - int PR_SET_NAME = 15; - - @SuppressWarnings("UnusedReturnValue") - int prctl(int option, String arg2, long arg3, long arg4, long arg5); // SUPPRESS CHECKSTYLE - // RegexpSinglelineJavaCheck - } - - public interface DarwinCLib extends Library { - @SuppressWarnings("UnusedReturnValue") - int pthread_setname_np(String name); // SUPPRESS CHECKSTYLE MethodNameCheck - } - - public interface WindowsCLib extends Library { - int GetCurrentThread(); // SUPPRESS CHECKSTYLE MethodNameCheck - - @SuppressWarnings("UnusedReturnValue") - int SetThreadDescription(int tid, WString name); // SUPPRESS CHECKSTYLE MethodNameCheck - } - - private static final NativeInterface INTERFACE = initNativeInterface(); - - private static NativeInterface initNativeInterface() { - try { - switch (Platform.getOSType()) { - case Platform.LINUX: - LinuxCLib linuxLib = Native.loadLibrary(LinuxCLib.class); - return new NativeInterface() { - @Nonnull - @Override - public OsPlatform getPlatform() { - return OsPlatform.LINUX; - } - - @Override - public void setThreadName(String name) { - linuxLib.prctl(LinuxCLib.PR_SET_NAME, name, 0, 0, 0); - } - }; - - case Platform.WINDOWS: - WindowsCLib windowsLib = Native.loadLibrary(WindowsCLib.class); - return new NativeInterface() { - @Nonnull - @Override - public OsPlatform getPlatform() { - return OsPlatform.WINDOWS; - } - - @Override - public void setThreadName(String name) { - windowsLib.SetThreadDescription(windowsLib.GetCurrentThread(), new WString(name)); - } - }; - - case Platform.MAC: - DarwinCLib macLib = Native.loadLibrary(DarwinCLib.class); - return new NativeInterface() { - @Nonnull - @Override - public OsPlatform getPlatform() { - return OsPlatform.DARWIN; - } - - @Override - public void setThreadName(String name) { - macLib.pthread_setname_np(name); - } - }; - - default: - break; - } - } catch (Throwable ex) { - LOG.debug("Failed to load platform-specific shim", ex); - } - - LOG.warn("Unable to load a native interface"); - return new NativeInterface() { - @Nonnull - @Override - public OsPlatform getPlatform() { - return OsPlatform.UNKNOWN; - } - - @Override - public void setThreadName(String name) { - // do nothing - } - }; - } -} diff --git a/internal/alpini/common/alpini-common-native/src/test/java/com/linkedin/alpini/jna/TestThreadUtils.java b/internal/alpini/common/alpini-common-native/src/test/java/com/linkedin/alpini/jna/TestThreadUtils.java deleted file mode 100644 index f3ea192b716..00000000000 --- a/internal/alpini/common/alpini-common-native/src/test/java/com/linkedin/alpini/jna/TestThreadUtils.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.linkedin.alpini.jna; - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import org.testng.Assert; -import org.testng.annotations.Test; - - -@Test(groups = "unit") -public class TestThreadUtils { - public void testGetPlatform() { - Assert.assertNotEquals(ThreadUtils.getPlatform().toString(), "UNKNOWN"); - } - - public void testSetThreadName() throws Exception { - - ExecutorService executorService = - Executors.newSingleThreadExecutor(ThreadUtils.decorateName(Executors.defaultThreadFactory())); - try { - - executorService.submit(() -> System.out.println("Hello world")).get(); - - } finally { - executorService.shutdown(); - } - } - -} diff --git a/internal/alpini/common/alpini-common-test/build.gradle b/internal/alpini/common/alpini-common-test/build.gradle deleted file mode 100644 index d775fe3abda..00000000000 --- a/internal/alpini/common/alpini-common-test/build.gradle +++ /dev/null @@ -1,10 +0,0 @@ -dependencies { - implementation project(':internal:alpini:common:alpini-common-base') - implementation libraries.mockito - implementation libraries.log4j2api - implementation libraries.testng - - testImplementation libraries.log4j2core -} - - diff --git a/internal/alpini/common/alpini-common-test/src/main/java/com/linkedin/alpini/base/test/ResourceRegistryTestBase.java b/internal/alpini/common/alpini-common-test/src/main/java/com/linkedin/alpini/base/test/ResourceRegistryTestBase.java deleted file mode 100644 index 98a08d0c9d8..00000000000 --- a/internal/alpini/common/alpini-common-test/src/main/java/com/linkedin/alpini/base/test/ResourceRegistryTestBase.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.linkedin.alpini.base.test; - -import com.linkedin.alpini.base.registry.ResourceRegistry; -import com.linkedin.alpini.base.registry.Shutdownable; -import com.linkedin.alpini.base.registry.ShutdownableResource; -import com.linkedin.alpini.base.registry.SyncShutdownable; -import org.testng.annotations.AfterClass; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; - - -/** - * @author Antony T Curtis <acurtis@linkedin.com> - */ -public abstract class ResourceRegistryTestBase { - public static final ThreadLocal REGISTRY_THREAD_LOCAL = new ThreadLocal<>(); - private final ResourceRegistry _resourceRegistry = new ResourceRegistry(); - - public > F factory(Class clazz) { - return _resourceRegistry.factory(clazz); - } - - public R register(R resource) { - return _resourceRegistry.register(resource); - } - - public R register(R resource) { - return _resourceRegistry.register(resource); - } - - @BeforeMethod(alwaysRun = true) - public void setResourceRegistryThreadLocal() { - REGISTRY_THREAD_LOCAL.set(_resourceRegistry); - } - - @AfterMethod(alwaysRun = true) - public void removeResourceRegistryThreadLocal() { - REGISTRY_THREAD_LOCAL.remove(); - } - - @AfterClass(alwaysRun = true) - public void shutdownResourceRegistry() throws InterruptedException { - _resourceRegistry.shutdown(); - _resourceRegistry.waitForShutdown(); - } -} diff --git a/internal/alpini/common/alpini-common-test/src/main/java/com/linkedin/alpini/base/test/TestUtil.java b/internal/alpini/common/alpini-common-test/src/main/java/com/linkedin/alpini/base/test/TestUtil.java deleted file mode 100644 index 1af76a920c6..00000000000 --- a/internal/alpini/common/alpini-common-test/src/main/java/com/linkedin/alpini/base/test/TestUtil.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.linkedin.alpini.base.test; - -import com.linkedin.alpini.base.misc.Time; -import java.util.concurrent.TimeUnit; -import java.util.function.BooleanSupplier; - - -/** - * @author Antony T Curtis {@literal } - */ -public enum TestUtil { - SINGLETON; // Effective Java, Item 3 - Enum singleton - - public static void waitFor(BooleanSupplier test, long duration, TimeUnit unit) { - long timeout = Time.nanoTime() + unit.toNanos(duration); - do { - if (test.getAsBoolean()) { - break; - } - Thread.yield(); - } while (Time.nanoTime() < timeout); - } -} diff --git a/internal/alpini/common/alpini-common-test/src/main/java/com/linkedin/alpini/base/test/package-info.java b/internal/alpini/common/alpini-common-test/src/main/java/com/linkedin/alpini/base/test/package-info.java deleted file mode 100644 index 52dd67a4de6..00000000000 --- a/internal/alpini/common/alpini-common-test/src/main/java/com/linkedin/alpini/base/test/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * @author Antony T Curtis {@literal } - */ -package com.linkedin.alpini.base.test; diff --git a/internal/alpini/common/alpini-common-test/src/test/java/com/linkedin/alpini/base/test/TestResourceRegistryTestBase.java b/internal/alpini/common/alpini-common-test/src/test/java/com/linkedin/alpini/base/test/TestResourceRegistryTestBase.java deleted file mode 100644 index 7881c9e11dd..00000000000 --- a/internal/alpini/common/alpini-common-test/src/test/java/com/linkedin/alpini/base/test/TestResourceRegistryTestBase.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.linkedin.alpini.base.test; - -import com.linkedin.alpini.base.registry.Shutdownable; -import com.linkedin.alpini.base.registry.SyncShutdownable; -import org.mockito.Mockito; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.Test; - - -public class TestResourceRegistryTestBase extends ResourceRegistryTestBase { - private static Shutdownable _shutdownable = Mockito.mock(Shutdownable.class); - private static SyncShutdownable _syncShutdownable = Mockito.mock(SyncShutdownable.class); - - @Test - public void basicTest() { - Assert.assertSame(register(_shutdownable), _shutdownable); - Assert.assertSame(register(_syncShutdownable), _syncShutdownable); - } - - @AfterClass(dependsOnMethods = "shutdownResourceRegistry") - public static void afterClass() throws InterruptedException { - Mockito.verify(_shutdownable).shutdown(); - Mockito.verify(_shutdownable).waitForShutdown(); - Mockito.verify(_syncShutdownable).shutdownSynchronously(); - Mockito.verifyNoMoreInteractions(_shutdownable, _syncShutdownable); - } -} diff --git a/internal/alpini/common/alpini-common-test/src/test/java/com/linkedin/alpini/base/test/TestTestUtil.java b/internal/alpini/common/alpini-common-test/src/test/java/com/linkedin/alpini/base/test/TestTestUtil.java deleted file mode 100644 index 6160cdb6b21..00000000000 --- a/internal/alpini/common/alpini-common-test/src/test/java/com/linkedin/alpini/base/test/TestTestUtil.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.linkedin.alpini.base.test; - -import com.linkedin.alpini.base.misc.Time; -import java.util.concurrent.TimeUnit; -import org.testng.Assert; -import org.testng.annotations.Test; - - -public class TestTestUtil { - @Test - public void basicTest() { - long time = Time.nanoTime(); - TestUtil.waitFor(() -> false, 1, TimeUnit.SECONDS); - Assert.assertEquals((Time.nanoTime() - time) / 1000000000.0, 1, 0.1); - time = Time.nanoTime(); - TestUtil.waitFor(() -> true, 1, TimeUnit.SECONDS); - Assert.assertEquals((Time.nanoTime() - time) / 1000000000.0, 0, 0.1); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/build.gradle b/internal/alpini/netty4/alpini-netty4-base/build.gradle index dfa63f0dd51..e69f4ade682 100644 --- a/internal/alpini/netty4/alpini-netty4-base/build.gradle +++ b/internal/alpini/netty4/alpini-netty4-base/build.gradle @@ -1,6 +1,5 @@ dependencies { implementation project(':internal:alpini:common:alpini-common-base') - implementation project(':internal:alpini:common:alpini-common-const') implementation project(':internal:alpini:common:alpini-common-io') implementation libraries.bouncyCastleBcpkix implementation libraries.commonsIo diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/misc/ByteBufAsciiString.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/misc/ByteBufAsciiString.java deleted file mode 100644 index a0437119413..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/misc/ByteBufAsciiString.java +++ /dev/null @@ -1,1477 +0,0 @@ -package com.linkedin.alpini.base.misc; - -import static io.netty.util.internal.MathUtil.isOutOfBounds; - -import com.linkedin.alpini.netty4.misc.NettyUtils; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; -import io.netty.buffer.ByteBufUtil; -import io.netty.buffer.Unpooled; -import io.netty.buffer.UnpooledByteBufAllocator; -import io.netty.util.AsciiString; -import io.netty.util.ByteProcessor; -import io.netty.util.ReferenceCounted; -import io.netty.util.internal.InternalThreadLocalMap; -import io.netty.util.internal.PlatformDependent; -import java.nio.CharBuffer; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.Collection; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Stream; -import javax.annotation.Nonnull; - - -/** - * A string implementation, similar to {@linkplain AsciiString}, which is backed by a {@linkplain ByteBuf} - * instead of a {@literal byte[]} array. - */ -public final class ByteBufAsciiString implements CharSequence, ReferenceCounted, Comparable { - public static final ByteBufAsciiString EMPTY_STRING = new ByteBufAsciiString(Unpooled.EMPTY_BUFFER, 0, ""); - private static final char MAX_CHAR_VALUE = 255; - - public static final int INDEX_NOT_FOUND = -1; - - private final ByteBuf _buf; - private transient int _hash; - private transient String _string; - - private ByteBufAsciiString(ByteBuf buf) { - _buf = buf; - } - - private ByteBufAsciiString(ByteBuf buf, int hash, String string) { - _buf = buf; - _hash = hash; - _string = string; - } - - public ByteBufAsciiString(@Nonnull ByteBufAllocator alloc, @Nonnull byte[] bytes) { - _buf = alloc.buffer(bytes.length); - _buf.writeBytes(bytes); - } - - public ByteBufAsciiString(@Nonnull ByteBufAllocator alloc, @Nonnull CharSequence charSequence) { - _buf = ByteBufUtil.writeAscii(alloc, charSequence); - _string = charSequence instanceof String ? (String) charSequence : null; - } - - /** - * Create a copy of {@code value} into this instance assuming ASCII encoding. - * The copy will start at index {@code start} and copy {@code length} bytes. - */ - public ByteBufAsciiString(@Nonnull ByteBufAllocator alloc, @Nonnull CharSequence value, int start, int length) { - if (isOutOfBounds(start, length, value.length())) { - throw new IndexOutOfBoundsException( - "expected: " + "0 <= start(" + start + ") <= start + length(" + length + ") <= " + "value.length(" - + value.length() + ')'); - } - - _buf = alloc.buffer(length); - for (int i = 0, j = start; i < length; i++, j++) { - _buf.writeByte(c2b(value.charAt(j))); - } - } - - /** - * Create a copy of {@code value} into this instance assuming ASCII encoding. - */ - public ByteBufAsciiString(@Nonnull ByteBufAllocator alloc, @Nonnull char[] value) { - this(alloc, value, 0, value.length); - } - - /** - * Create a copy of {@code value} into this instance assuming ASCII encoding. - * The copy will start at index {@code start} and copy {@code length} bytes. - */ - public ByteBufAsciiString(@Nonnull ByteBufAllocator alloc, @Nonnull char[] value, int start, int length) { - if (isOutOfBounds(start, length, value.length)) { - throw new IndexOutOfBoundsException( - "expected: " + "0 <= start(" + start + ") <= start + length(" + length + ") <= " + "value.length(" - + value.length + ')'); - } - - _buf = alloc.buffer(length); - for (int i = 0, j = start; i < length; i++, j++) { - _buf.writeByte(c2b(value[j])); - } - } - - /** - * Create a copy of {@code value} into this instance using the encoding type of {@code charset}. - */ - public ByteBufAsciiString(@Nonnull ByteBufAllocator alloc, @Nonnull char[] value, Charset charset) { - this(alloc, value, charset, 0, value.length); - } - - /** - * Create a copy of {@code value} into a this instance using the encoding type of {@code charset}. - * The copy will start at index {@code start} and copy {@code length} bytes. - */ - public ByteBufAsciiString( - @Nonnull ByteBufAllocator alloc, - @Nonnull char[] value, - Charset charset, - int start, - int length) { - this(alloc, CharBuffer.wrap(value, start, length), charset, length); - } - - /** - * Create a copy of {@code value} into this instance using the encoding type of {@code charset}. - */ - public ByteBufAsciiString(@Nonnull ByteBufAllocator alloc, @Nonnull CharSequence value, Charset charset) { - this(alloc, value, charset, 0, value.length()); - } - - /** - * Create a copy of {@code value} into this instance using the encoding type of {@code charset}. - * The copy will start at index {@code start} and copy {@code length} bytes. - */ - public ByteBufAsciiString( - @Nonnull ByteBufAllocator alloc, - @Nonnull CharSequence value, - Charset charset, - int start, - int length) { - this(alloc, CharBuffer.wrap(value, start, start + length), charset, length); - } - - private ByteBufAsciiString(@Nonnull ByteBufAllocator alloc, @Nonnull CharBuffer cbuf, Charset charset, int length) { - _buf = ByteBufUtil.encodeString(alloc, cbuf, charset); - } - - public ByteBufAsciiString(byte[] bytes, int offset, int length, boolean copy) { - _buf = copy ? Unpooled.copiedBuffer(bytes, offset, length) : Unpooled.wrappedBuffer(bytes, offset, length); - } - - public static ByteBufAsciiString readBytes(ByteBuf byteBuf, int length) { - return new ByteBufAsciiString(byteBuf.readBytes(length)); - } - - public static ByteBufAsciiString readRetainedSlice(ByteBuf byteBuf, int length) { - return new ByteBufAsciiString(byteBuf.readRetainedSlice(length)); - } - - public static ByteBufAsciiString read(ByteBuf byteBuf, int length) { - return new ByteBufAsciiString(NettyUtils.read(byteBuf, length)); - } - - public static ByteBufAsciiString copy(ByteBuf byteBuf, int index, int length) { - return new ByteBufAsciiString(byteBuf.copy(index, length)); - } - - public static ByteBufAsciiString slice(ByteBuf byteBuf, int index, int length) { - return new ByteBufAsciiString(byteBuf.slice(index, length)); - } - - /** - * Iterates over the readable bytes of this buffer with the specified {@code processor} in ascending order. - * - * @return {@code -1} if the processor iterated to or beyond the end of the readable bytes. - * The last-visited index If the {@link ByteProcessor#process(byte)} returned {@code false}. - */ - public int forEachByte(ByteProcessor visitor) { - return forEachByte0(0, length(), visitor); - } - - /** - * Iterates over the specified area of this buffer with the specified {@code processor} in ascending order. - * (i.e. {@code index}, {@code (index + 1)}, .. {@code (index + length - 1)}). - * - * @return {@code -1} if the processor iterated to or beyond the end of the specified area. - * The last-visited index If the {@link ByteProcessor#process(byte)} returned {@code false}. - */ - public int forEachByte(int index, int length, ByteProcessor visitor) { - if (isOutOfBounds(index, length, length())) { - throw new IndexOutOfBoundsException( - "expected: " + "0 <= index(" + index + ") <= start + length(" + length + ") <= " + "length(" + length() - + ')'); - } - return forEachByte0(index, length, visitor); - } - - private int forEachByte0(int index, int length, ByteProcessor visitor) { - int ret = _buf.forEachByte(_buf.readerIndex() + index, length, visitor); - return ret >= 0 ? ret - _buf.readerIndex() : -1; - } - - /** - * Iterates over the readable bytes of this buffer with the specified {@code processor} in descending order. - * - * @return {@code -1} if the processor iterated to or beyond the beginning of the readable bytes. - * The last-visited index If the {@link ByteProcessor#process(byte)} returned {@code false}. - */ - public int forEachByteDesc(ByteProcessor visitor) { - return forEachByteDesc0(0, length(), visitor); - } - - /** - * Iterates over the specified area of this buffer with the specified {@code processor} in descending order. - * (i.e. {@code (index + length - 1)}, {@code (index + length - 2)}, ... {@code index}). - * - * @return {@code -1} if the processor iterated to or beyond the beginning of the specified area. - * The last-visited index If the {@link ByteProcessor#process(byte)} returned {@code false}. - */ - public int forEachByteDesc(int index, int length, ByteProcessor visitor) { - if (isOutOfBounds(index, length, length())) { - throw new IndexOutOfBoundsException( - "expected: " + "0 <= index(" + index + ") <= start + length(" + length + ") <= " + "length(" + length() - + ')'); - } - return forEachByteDesc0(index, length, visitor); - } - - private int forEachByteDesc0(int index, int length, ByteProcessor visitor) { - int ret = _buf.forEachByteDesc(index, length, visitor); - return ret >= 0 ? ret - _buf.readerIndex() : -1; - } - - /** - * Determine if this instance has 0 length. - */ - public boolean isEmpty() { - return !_buf.isReadable(); - } - - @Override - public int length() { - return _buf.readableBytes(); - } - - public byte byteAt(int index) { - // We must do a range check here to enforce the access does not go outside our sub region of the array. - // We rely on the array access itself to pick up the array out of bounds conditions - if (index < 0 || index >= length()) { - throw new IndexOutOfBoundsException("index: " + index + " must be in the range [0," + length() + ")"); - } - return _buf.getByte(_buf.readerIndex() + index); - } - - /** - * Converts this string to a byte array. - */ - public byte[] toByteArray() { - return toByteArray(0, length()); - } - - /** - * Converts a subset of this string to a byte array. - * The subset is defined by the range [{@code start}, {@code end}). - */ - public byte[] toByteArray(int start, int end) { - return ByteBufUtil.getBytes(_buf, start + _buf.readerIndex(), end - start); - } - - @Override - public char charAt(int index) { - return b2c(byteAt(index)); - } - - /** - * Determines if this {@code String} contains the sequence of characters in the {@code CharSequence} passed. - * - * @param cs the character sequence to search for. - * @return {@code true} if the sequence of characters are contained in this string, otherwise {@code false}. - */ - public boolean contains(CharSequence cs) { - return indexOf(cs) >= 0; - } - - /** - * Compares the specified string to this string using the ASCII values of the characters. Returns 0 if the strings - * contain the same characters in the same order. Returns a negative integer if the first non-equal character in - * this string has an ASCII value which is less than the ASCII value of the character at the same position in the - * specified string, or if this string is a prefix of the specified string. Returns a positive integer if the first - * non-equal character in this string has a ASCII value which is greater than the ASCII value of the character at - * the same position in the specified string, or if the specified string is a prefix of this string. - * - * @param string the string to compare. - * @return 0 if the strings are equal, a negative integer if this string is before the specified string, or a - * positive integer if this string is after the specified string. - * @throws NullPointerException if {@code string} is {@code null}. - */ - @Override - public int compareTo(@Nonnull CharSequence string) { - if (this == string) { - return 0; - } - - int result; - int length1 = length(); - int length2 = string.length(); - int minLength = Math.min(length1, length2); - for (int i = 0, j = _buf.readerIndex(); i < minLength; i++, j++) { - result = b2c(_buf.getByte(j)) - string.charAt(i); - if (result != 0) { - return result; - } - } - - return length1 - length2; - } - - /** - * Concatenates this string and the specified string. - * - * @param strings the strings to concatenate - * @return a new string which is the concatenation of this string and the specified string. - */ - public ByteBufAsciiString concat(CharSequence... strings) { - ByteBufAsciiString thisString = this; - ByteBuf newValue = null; - for (CharSequence string: strings) { - if (string.length() < 1) { - continue; - } - if (newValue == null) { - int newLen = length() + Stream.of(strings).mapToInt(CharSequence::length).sum(); - if (thisString.isEmpty()) { - if (string.getClass() == ByteBufAsciiString.class) { - thisString = (ByteBufAsciiString) string; - continue; - } - newValue = UnpooledByteBufAllocator.DEFAULT.buffer(newLen); - } else { - ByteBuf buf = thisString._buf; - newValue = buf.alloc().buffer(newLen); - newValue.writeBytes(buf, buf.readerIndex(), buf.readableBytes()); - } - } - - if (string.getClass() == ByteBufAsciiString.class) { - ByteBuf buf = ((ByteBufAsciiString) string)._buf; - newValue.writeBytes(buf, buf.readerIndex(), buf.readableBytes()); - } else if (string.getClass() == AsciiString.class) { - AsciiString asciiString = (AsciiString) string; - newValue.writeBytes(asciiString.array(), asciiString.arrayOffset(), asciiString.length()); - } else { - for (int i = 0; i < string.length(); i++) { - newValue.writeByte(c2b(string.charAt(i))); - } - } - } - if (newValue == null) { - return thisString; - } - return new ByteBufAsciiString(newValue); - } - - /** - * Compares the specified string to this string to determine if the specified string is a suffix. - * - * @param suffix the suffix to look for. - * @return {@code true} if the specified string is a suffix of this string, {@code false} otherwise. - * @throws NullPointerException if {@code suffix} is {@code null}. - */ - public boolean endsWith(CharSequence suffix) { - int suffixLen = suffix.length(); - return regionMatches(length() - suffixLen, suffix, 0, suffixLen); - } - - /** - * Compares the specified string to this string ignoring the case of the characters and returns true if they are - * equal. - * - * @param string the string to compare. - * @return {@code true} if the specified string is equal to this string, {@code false} otherwise. - */ - public boolean contentEqualsIgnoreCase(CharSequence string) { - if (string == null || string.length() != length()) { - return false; - } - - if (string.getClass() == ByteBufAsciiString.class) { - ByteBufAsciiString rhs = (ByteBufAsciiString) string; - for (int i = _buf.readerIndex(), j = rhs._buf.readerIndex(); i < length(); ++i, ++j) { - if (!equalsIgnoreCase(_buf.getByte(i), rhs._buf.getByte(j))) { - return false; - } - } - return true; - } - - for (int i = _buf.readerIndex(), j = 0; i < length(); ++i, ++j) { - if (!equalsIgnoreCase(b2c(_buf.getByte(i)), string.charAt(j))) { - return false; - } - } - return true; - } - - /** - * Copies a range of characters into a new string. - * @param start the offset of the first character (inclusive). - * @return a new string containing the characters from start to the end of the string. - * @throws IndexOutOfBoundsException if {@code start < 0} or {@code start > length()}. - */ - public ByteBufAsciiString subSequence(int start) { - return subSequence(start, length()); - } - - /** - * Copies a range of characters into a new string. - * @param start the offset of the first character (inclusive). - * @param end The index to stop at (exclusive). - * @return a new string containing the characters from start to the end of the string. - * @throws IndexOutOfBoundsException if {@code start < 0} or {@code start > length()}. - */ - @Override - public ByteBufAsciiString subSequence(int start, int end) { - return subSequence(start, end, true); - } - - /** - * Either copy or share a subset of underlying sub-sequence of bytes. - * @param start the offset of the first character (inclusive). - * @param end The index to stop at (exclusive). - * @param copy If {@code true} then a copy of the underlying storage will be made. - * If {@code false} then the underlying storage will be shared. - * @return a new string containing the characters from start to the end of the string. - * @throws IndexOutOfBoundsException if {@code start < 0} or {@code start > length()}. - */ - public ByteBufAsciiString subSequence(int start, int end, boolean copy) { - if (isOutOfBounds(start, end - start, length())) { - throw new IndexOutOfBoundsException( - "expected: 0 <= start(" + start + ") <= end (" + end + ") <= length(" + length() + ')'); - } - - if (start == 0 && end == length()) { - return this; - } - - if (end == start) { - return EMPTY_STRING; - } - - if (copy) { - return copy(_buf, start + _buf.readerIndex(), end - start); - } else { - return slice(_buf, start + _buf.readerIndex(), end - start); - } - } - - /** - * Searches in this string for the first index of the specified string. The search for the string starts at the - * beginning and moves towards the end of this string. - * - * @param string the string to find. - * @return the index of the first character of the specified string in this string, -1 if the specified string is - * not a substring. - * @throws NullPointerException if {@code string} is {@code null}. - */ - public int indexOf(CharSequence string) { - return indexOf(string, 0); - } - - /** - * Searches in this string for the index of the specified string. The search for the string starts at the specified - * offset and moves towards the end of this string. - * - * @param subString the string to find. - * @param start the starting offset. - * @return the index of the first character of the specified string in this string, -1 if the specified string is - * not a substring. - * @throws NullPointerException if {@code subString} is {@code null}. - */ - public int indexOf(CharSequence subString, int start) { - final int thisLen = length(); - final int subCount = subString.length(); - if (start < 0) { - start = 0; - } - if (subCount <= 0) { - return start < thisLen ? start : thisLen; - } - if (subCount > thisLen - start) { - return INDEX_NOT_FOUND; - } - - final char firstChar = subString.charAt(0); - if (firstChar > MAX_CHAR_VALUE) { - return INDEX_NOT_FOUND; - } - final byte firstCharAsByte = c2b0(firstChar); - final int len = _buf.readerIndex() + thisLen - subCount; - for (int i = start + _buf.readerIndex(); i <= len; ++i) { - if (_buf.getByte(i) == firstCharAsByte) { - int o1 = i; - int o2 = 0; - while (++o2 < subCount && b2c(_buf.getByte(++o1)) == subString.charAt(o2)) { - // Intentionally empty - } - if (o2 == subCount) { - return i - _buf.readerIndex(); - } - } - } - return INDEX_NOT_FOUND; - } - - /** - * Searches in this string for the index of the specified char {@code ch}. - * The search for the char starts at the specified offset {@code start} and moves towards the end of this string. - * - * @param ch the char to find. - * @param start the starting offset. - * @return the index of the first occurrence of the specified char {@code ch} in this string, - * -1 if found no occurrence. - */ - public int indexOf(char ch, int start) { - if (start < 0) { - start = 0; - } - - final int thisLen = length(); - - if (ch > MAX_CHAR_VALUE) { - return -1; - } - - return forEachByte(start, thisLen - start, new ByteProcessor.IndexOfProcessor((byte) ch)); - } - - /** - * Searches in this string for the last index of the specified string. The search for the string starts at the end - * and moves towards the beginning of this string. - * - * @param string the string to find. - * @return the index of the first character of the specified string in this string, -1 if the specified string is - * not a substring. - * @throws NullPointerException if {@code string} is {@code null}. - */ - public int lastIndexOf(CharSequence string) { - // Use count instead of count - 1 so lastIndexOf("") answers count - return lastIndexOf(string, length()); - } - - /** - * Searches in this string for the index of the specified string. The search for the string starts at the specified - * offset and moves towards the beginning of this string. - * - * @param subString the string to find. - * @param start the starting offset. - * @return the index of the first character of the specified string in this string , -1 if the specified string is - * not a substring. - * @throws NullPointerException if {@code subString} is {@code null}. - */ - public int lastIndexOf(CharSequence subString, int start) { - final int subCount = subString.length(); - start = Math.min(start, length() - subCount); - if (start < 0) { - return INDEX_NOT_FOUND; - } - if (subCount == 0) { - return start; - } - - final char firstChar = subString.charAt(0); - if (firstChar > MAX_CHAR_VALUE) { - return INDEX_NOT_FOUND; - } - final byte firstCharAsByte = c2b0(firstChar); - final int readerIndex = _buf.readerIndex(); - for (int i = readerIndex + start; i >= readerIndex; --i) { - if (_buf.getByte(i) == firstCharAsByte) { - int o1 = i; - int o2 = 0; - while (++o2 < subCount && b2c(_buf.getByte(++o1)) == subString.charAt(o2)) { - // Intentionally empty - } - if (o2 == subCount) { - return i - readerIndex; - } - } - } - return INDEX_NOT_FOUND; - } - - /** - * Compares the specified string to this string and compares the specified range of characters to determine if they - * are the same. - * - * @param thisStart the starting offset in this string. - * @param string the string to compare. - * @param start the starting offset in the specified string. - * @param length the number of characters to compare. - * @return {@code true} if the ranges of characters are equal, {@code false} otherwise - * @throws NullPointerException if {@code string} is {@code null}. - */ - public boolean regionMatches(int thisStart, CharSequence string, int start, int length) { - if (string == null) { - throw new NullPointerException("string"); - } - - if (start < 0 || string.length() - start < length) { - return false; - } - - final int thisLen = length(); - if (thisStart < 0 || thisLen - thisStart < length) { - return false; - } - - if (length <= 0) { - return true; - } - - final int thatEnd = start + length; - for (int i = start, j = thisStart + _buf.readerIndex(); i < thatEnd; i++, j++) { - if (b2c(_buf.getByte(j)) != string.charAt(i)) { - return false; - } - } - return true; - } - - /** - * Compares the specified string to this string and compares the specified range of characters to determine if they - * are the same. When ignoreCase is true, the case of the characters is ignored during the comparison. - * - * @param ignoreCase specifies if case should be ignored. - * @param thisStart the starting offset in this string. - * @param string the string to compare. - * @param start the starting offset in the specified string. - * @param length the number of characters to compare. - * @return {@code true} if the ranges of characters are equal, {@code false} otherwise. - * @throws NullPointerException if {@code string} is {@code null}. - */ - public boolean regionMatches(boolean ignoreCase, int thisStart, CharSequence string, int start, int length) { - if (!ignoreCase) { - return regionMatches(thisStart, string, start, length); - } - - if (string == null) { - throw new NullPointerException("string"); - } - - final int thisLen = length(); - if (thisStart < 0 || length > thisLen - thisStart) { - return false; - } - if (start < 0 || length > string.length() - start) { - return false; - } - - thisStart += _buf.readerIndex(); - final int thisEnd = thisStart + length; - while (thisStart < thisEnd) { - if (!equalsIgnoreCase(b2c(_buf.getByte(thisStart++)), string.charAt(start++))) { - return false; - } - } - return true; - } - - /** - * Copies this string replacing occurrences of the specified character with another character. - * - * @param oldChar the character to replace. - * @param newChar the replacement character. - * @return a new string with occurrences of oldChar replaced by newChar. - */ - public ByteBufAsciiString replace(char oldChar, char newChar) { - if (oldChar > MAX_CHAR_VALUE) { - return this; - } - - final int index; - final byte oldCharByte = c2b(oldChar); - index = forEachByte(new ByteProcessor.IndexOfProcessor(oldCharByte)); - if (index == -1) { - return this; - } - - final byte newCharByte = c2b(newChar); - final int length = length(); - ByteBuf buffer = _buf.alloc().buffer(length); - for (int i = 0, j = _buf.readerIndex(); i < length; i++, j++) { - byte b = _buf.getByte(j); - if (b == oldCharByte) { - b = newCharByte; - } - buffer.writeByte(b); - } - - return new ByteBufAsciiString(buffer); - } - - /** - * Compares the specified string to this string to determine if the specified string is a prefix. - * - * @param prefix the string to look for. - * @return {@code true} if the specified string is a prefix of this string, {@code false} otherwise - * @throws NullPointerException if {@code prefix} is {@code null}. - */ - public boolean startsWith(CharSequence prefix) { - return startsWith(prefix, 0); - } - - /** - * Compares the specified string to this string to determine if the specified string is a prefix. - * - * @param prefix the string to look for. - * @return {@code true} if the specified string is a prefix of this string, {@code false} otherwise - * @throws NullPointerException if {@code prefix} is {@code null}. - */ - public static boolean startsWith(CharSequence string, CharSequence prefix) { - return startsWith(string, prefix, 0); - } - - /** - * Compares the specified string to this string to determine if the specified string is a prefix. - * - * @param prefix the string to look for. - * @return {@code true} if the specified string is a prefix of this string, {@code false} otherwise - * @throws NullPointerException if {@code prefix} is {@code null}. - */ - public static boolean startsWithIgnoreCase(CharSequence string, CharSequence prefix) { - return startsWithIgnoreCase(string, prefix, 0); - } - - /** - * Compares the specified string to this string, starting at the specified offset, to determine if the specified - * string is a prefix. - * - * @param prefix the string to look for. - * @param start the starting offset. - * @return {@code true} if the specified string occurs in this string at the specified offset, {@code false} - * otherwise. - * @throws NullPointerException if {@code prefix} is {@code null}. - */ - public boolean startsWith(CharSequence prefix, int start) { - return regionMatches(start, prefix, 0, prefix.length()); - } - - /** - * Compares the specified string to this string, starting at the specified offset, to determine if the specified - * string is a prefix. - * - * @param prefix the string to look for. - * @param start the starting offset. - * @return {@code true} if the specified string occurs in this string at the specified offset, {@code false} - * otherwise. - * @throws NullPointerException if {@code prefix} is {@code null}. - */ - public static boolean startsWith(CharSequence string, CharSequence prefix, int start) { - return regionMatches(string, false, start, prefix, 0, prefix.length()); - } - - public static boolean startsWithIgnoreCase(CharSequence string, CharSequence prefix, int start) { - return regionMatches(string, true, start, prefix, 0, prefix.length()); - } - - /** - * Converts the characters in this string to lowercase, using the default Locale. - * - * @return a new string containing the lowercase characters equivalent to the characters in this string. - */ - public ByteBufAsciiString toLowerCase() { - boolean lowercased = true; - int i; - int j; - final int len = length() + _buf.readerIndex(); - for (i = _buf.readerIndex(); i < len; ++i) { - byte b = _buf.getByte(i); - if (b >= 'A' && b <= 'Z') { - lowercased = false; - break; - } - } - - // Check if this string does not contain any uppercase characters. - if (lowercased) { - return this; - } - - final int length = length(); - final ByteBuf newValue = _buf.alloc().buffer(length); - for (i = 0, j = _buf.readerIndex(); i < length; ++i, ++j) { - newValue.writeByte(toLowerCase(_buf.getByte(j))); - } - - return new ByteBufAsciiString(newValue); - } - - /** - * Converts the characters in this string to uppercase, using the default Locale. - * - * @return a new string containing the uppercase characters equivalent to the characters in this string. - */ - public ByteBufAsciiString toUpperCase() { - boolean uppercased = true; - int i; - int j; - final int len = length() + _buf.readerIndex(); - for (i = _buf.readerIndex(); i < len; ++i) { - byte b = _buf.getByte(i); - if (b >= 'a' && b <= 'z') { - uppercased = false; - break; - } - } - - // Check if this string does not contain any lowercase characters. - if (uppercased) { - return this; - } - - final int length = length(); - final ByteBuf newValue = _buf.alloc().buffer(length); - for (i = 0, j = _buf.readerIndex(); i < length; ++i, ++j) { - newValue.writeByte(toUpperCase(_buf.getByte(j))); - } - - return new ByteBufAsciiString(newValue); - } - - /** - * Copies this string removing white space characters from the beginning and end of the string, and tries not to - * copy if possible. - * - * @param c The {@link CharSequence} to trim. - * @return a new string with characters {@code <= \\u0020} removed from the beginning and the end. - */ - public static CharSequence trim(CharSequence c) { - if (c.getClass() == ByteBufAsciiString.class) { - return ((ByteBufAsciiString) c).trim(); - } - return AsciiString.trim(c); - } - - /** - * Duplicates this string removing white space characters from the beginning and end of the - * string, without copying. - * - * @return a new string with characters {@code <= \\u0020} removed from the beginning and the end. - */ - public ByteBufAsciiString trim() { - int start = _buf.readerIndex(); - final int last = start + length() - 1; - final int first = start; - int end = last; - - while (start <= end && _buf.getByte(start) <= ' ') { - start++; - } - while (end >= start && _buf.getByte(end) <= ' ') { - end--; - } - if (start == first && end == last) { - return this; - } - return slice(_buf, start, end - start + 1); - } - - /** - * Compares a {@code CharSequence} to this {@code String} to determine if their contents are equal. - * - * @param a the character sequence to compare to. - * @return {@code true} if equal, otherwise {@code false} - */ - public boolean contentEquals(CharSequence a) { - if (a == null || a.length() != length()) { - return false; - } - if (this == a) { - return true; - } - if (a.getClass() == ByteBufAsciiString.class) { - return equals((ByteBufAsciiString) a); - } - for (int i = _buf.readerIndex(), j = 0; j < a.length(); ++i, ++j) { - if (b2c(_buf.getByte(i)) != a.charAt(j)) { - return false; - } - } - return true; - } - - /** - * Determines whether this string matches a given regular expression. - * - * @param expr the regular expression to be matched. - * @return {@code true} if the expression matches, otherwise {@code false}. - * @throws java.util.regex.PatternSyntaxException if the syntax of the supplied regular expression is not valid. - * @throws NullPointerException if {@code expr} is {@code null}. - */ - public boolean matches(String expr) { - return Pattern.matches(expr, this); - } - - /** - * Splits this string using the supplied regular expression {@code expr}. The parameter {@code max} controls the - * behavior how many times the pattern is applied to the string. - * - * @param expr the regular expression used to divide the string. - * @param max the number of entries in the resulting array. - * @return an array of Strings created by separating the string along matches of the regular expression. - * @throws NullPointerException if {@code expr} is {@code null}. - * @throws java.util.regex.PatternSyntaxException if the syntax of the supplied regular expression is not valid. - * @see Pattern#split(CharSequence, int) - */ - public ByteBufAsciiString[] split(String expr, int max) { - return split(Pattern.compile(expr), max); - } - - public ByteBufAsciiString[] split(@Nonnull Pattern pattern) { - return split(pattern, 0); - } - - public ByteBufAsciiString[] split(@Nonnull Pattern pattern, int limit) { - int index = 0; - boolean matchLimited = limit > 0; - final List matchList = InternalThreadLocalMap.get().arrayList(); - Matcher m = pattern.matcher(this); - - // Add segments before each match found - while (m.find()) { - if (!matchLimited || matchList.size() < limit - 1) { - if (index == 0 && index == m.start() && m.start() == m.end()) { - // no empty leading substring included for zero-width match - // at the beginning of the input char sequence. - continue; - } - ByteBufAsciiString match = subSequence(index, m.start(), false); - matchList.add(match); - index = m.end(); - } else if (matchList.size() == limit - 1) { // last one - ByteBufAsciiString match = subSequence(index, length(), false); - matchList.add(match); - index = m.end(); - } - } - - // If no match was found, return this - if (index == 0) { - return new ByteBufAsciiString[] { this }; - } - - // Add remaining segment - if (!matchLimited || matchList.size() < limit) { - matchList.add(subSequence(index, length(), false)); - } - - // Construct result - int resultSize = matchList.size(); - if (limit == 0) { - while (resultSize > 0 && matchList.get(resultSize - 1).isEmpty()) { - resultSize--; - } - } - return matchList.subList(0, resultSize).toArray(new ByteBufAsciiString[0]); - } - - /** - * Splits the specified {@link String} with the specified delimiter.. - */ - public ByteBufAsciiString[] split(char delim) { - final List res = InternalThreadLocalMap.get().arrayList(); - - int start = 0; - final int length = length(); - for (int i = start; i < length; i++) { - if (charAt(i) == delim) { - if (start == i) { - res.add(EMPTY_STRING); - } else { - res.add(slice(_buf, start + _buf.readerIndex(), i - start)); - } - start = i + 1; - } - } - - if (start == 0) { // If no delimiter was found in the value - res.add(this); - } else { - if (start != length) { - // Add the last element if it's not empty. - res.add(slice(_buf, start + _buf.readerIndex(), length - start)); - } else { - // Truncate trailing empty elements. - for (int i = res.size() - 1; i >= 0; i--) { - if (res.get(i).isEmpty()) { - res.remove(i); - } else { - break; - } - } - } - } - - return res.toArray(new ByteBufAsciiString[0]); - } - - /** - * {@inheritDoc} - *

- * Provides a case-insensitive hash code for Ascii like byte strings. - */ - @Override - public int hashCode() { - int h = _hash; - if (h == 0) { - if (_buf.hasArray()) { - h = PlatformDependent - .hashCodeAscii(_buf.array(), _buf.arrayOffset() + _buf.readerIndex(), _buf.readableBytes()); - } else { - h = PlatformDependent.hashCodeAscii(this); - } - _hash = h; - } - return h; - } - - @Override - public boolean equals(Object obj) { - if (obj == null || obj.getClass() != ByteBufAsciiString.class) { - return false; - } - if (this == obj) { - return true; - } - return equals((ByteBufAsciiString) obj); - } - - private boolean equals(ByteBufAsciiString other) { - return length() == other.length() && hashCode() == other.hashCode() - && ByteBufUtil.equals(_buf, _buf.readerIndex(), other._buf, other._buf.readerIndex(), length()); - } - - @Nonnull - public AsciiString toAsciiString() { - if (isEmpty()) { - return AsciiString.EMPTY_STRING; - } - if (_buf.hasArray()) { - return new AsciiString(_buf.array(), _buf.arrayOffset() + _buf.readerIndex(), _buf.readableBytes(), true); - } else { - byte[] bytes = new byte[length()]; - _buf.getBytes(_buf.readerIndex(), bytes, 0, bytes.length); - return new AsciiString(bytes, 0, bytes.length, false); - } - } - - /** - * Translates the entire byte string to a {@link String}. - * @see #toString(int) - */ - @Override - @Nonnull - public String toString() { - String cache = _string; - if (cache == null) { - cache = toString(0); - _string = cache; - } - return cache; - } - - /** - * Translates the entire byte string to a {@link String} using the {@code charset} encoding. - * @see #toString(int, int) - */ - public String toString(int start) { - return toString(start, length()); - } - - /** - * Translates the [{@code start}, {@code end}) range of this byte string to a {@link String}. - */ - @SuppressWarnings("deprecation") - public String toString(int start, int end) { - int length = end - start; - if (length == 0) { - return ""; - } - - if (isOutOfBounds(start, length, length())) { - throw new IndexOutOfBoundsException( - "expected: " + "0 <= start(" + start + ") <= srcIdx + length(" + length + ") <= srcLen(" + length() + ')'); - } - - final String str; - if (_buf.hasArray()) { - str = new String(_buf.array(), 0, start + _buf.arrayOffset() + _buf.readerIndex(), length); - } else { - str = _buf.toString(start + _buf.readerIndex(), length, StandardCharsets.US_ASCII); - } - return str; - } - - /** - * Determine if {@code collection} contains {@code value} and using - * {@link #contentEqualsIgnoreCase(CharSequence, CharSequence)} to compare values. - * @param collection The collection to look for and equivalent element as {@code value}. - * @param value The value to look for in {@code collection}. - * @return {@code true} if {@code collection} contains {@code value} according to - * {@link #contentEqualsIgnoreCase(CharSequence, CharSequence)}. {@code false} otherwise. - * @see #contentEqualsIgnoreCase(CharSequence, CharSequence) - */ - public static boolean containsContentEqualsIgnoreCase(Collection collection, CharSequence value) { - for (CharSequence v: collection) { - if (contentEqualsIgnoreCase(value, v)) { - return true; - } - } - return false; - } - - /** - * Determine if {@code a} contains all of the values in {@code b} using - * {@link #contentEqualsIgnoreCase(CharSequence, CharSequence)} to compare values. - * @param a The collection under test. - * @param b The values to test for. - * @return {@code true} if {@code a} contains all of the values in {@code b} using - * {@link #contentEqualsIgnoreCase(CharSequence, CharSequence)} to compare values. {@code false} otherwise. - * @see #contentEqualsIgnoreCase(CharSequence, CharSequence) - */ - public static boolean containsAllContentEqualsIgnoreCase(Collection a, Collection b) { - for (CharSequence v: b) { - if (!containsContentEqualsIgnoreCase(a, v)) { - return false; - } - } - return true; - } - - /** - * Returns {@code true} if the content of both {@link CharSequence}'s are equals. This only supports 8-bit ASCII. - */ - public static boolean contentEquals(CharSequence a, CharSequence b) { - if (a == null || b == null) { - return a == b; - } - - if (a.getClass() == ByteBufAsciiString.class) { - return ((ByteBufAsciiString) a).contentEquals(b); - } - - if (b.getClass() == ByteBufAsciiString.class) { - return ((ByteBufAsciiString) b).contentEquals(a); - } - - return AsciiString.contentEquals(a, b); - } - - /** - * Returns the case-insensitive hash code of the specified string. Note that this method uses the same hashing - * algorithm with {@link #hashCode()} so that you can put both {@link AsciiString}s and arbitrary - * {@link CharSequence}s into the same headers. - */ - public static int hashCode(CharSequence value) { - if (value == null) { - return 0; - } - if (value.getClass() == ByteBufAsciiString.class) { - return value.hashCode(); - } - return AsciiString.hashCode(value); - } - - /** - * Determine if {@code a} contains {@code b} in a case sensitive manner. - */ - public static boolean contains(CharSequence a, CharSequence b) { - if (a instanceof ByteBufAsciiString) { - return ((ByteBufAsciiString) a).contains(b); - } - return AsciiString.contains(a, b); - } - - /** - * Determine if {@code a} contains {@code b} in a case insensitive manner. - */ - public static boolean containsIgnoreCase(CharSequence a, CharSequence b) { - return AsciiString.containsIgnoreCase(a, b); - } - - /** - * Returns {@code true} if both {@link CharSequence}'s are equals when ignore the case. This only supports 8-bit - * ASCII. - */ - public static boolean contentEqualsIgnoreCase(CharSequence a, CharSequence b) { - if (a == null || b == null) { - return a == b; - } - - if (a.getClass() == ByteBufAsciiString.class) { - return ((ByteBufAsciiString) a).contentEqualsIgnoreCase(b); - } - if (b.getClass() == ByteBufAsciiString.class) { - return ((ByteBufAsciiString) b).contentEqualsIgnoreCase(a); - } - - return AsciiString.contentEqualsIgnoreCase(a, b); - } - - /** - * This methods make regionMatches operation correctly for any chars in strings - * @param cs the {@code CharSequence} to be processed - * @param ignoreCase specifies if case should be ignored. - * @param csStart the starting offset in the {@code cs} CharSequence - * @param string the {@code CharSequence} to compare. - * @param start the starting offset in the specified {@code string}. - * @param length the number of characters to compare. - * @return {@code true} if the ranges of characters are equal, {@code false} otherwise. - */ - public static boolean regionMatches( - final CharSequence cs, - final boolean ignoreCase, - final int csStart, - final CharSequence string, - final int start, - final int length) { - if (cs == null || string == null) { - return false; - } - - if (cs instanceof ByteBufAsciiString) { - return ((ByteBufAsciiString) cs).regionMatches(ignoreCase, csStart, string, start, length); - } - - return AsciiString.regionMatches(cs, ignoreCase, csStart, string, start, length); - } - - /** - * This is optimized version of regionMatches for string with ASCII chars only - * @param cs the {@code CharSequence} to be processed - * @param ignoreCase specifies if case should be ignored. - * @param csStart the starting offset in the {@code cs} CharSequence - * @param string the {@code CharSequence} to compare. - * @param start the starting offset in the specified {@code string}. - * @param length the number of characters to compare. - * @return {@code true} if the ranges of characters are equal, {@code false} otherwise. - */ - public static boolean regionMatchesAscii( - final CharSequence cs, - final boolean ignoreCase, - final int csStart, - final CharSequence string, - final int start, - final int length) { - if (cs == null || string == null) { - return false; - } - - if (cs instanceof ByteBufAsciiString) { - return ((ByteBufAsciiString) cs).regionMatches(ignoreCase, csStart, string, start, length); - } - - return AsciiString.regionMatchesAscii(cs, ignoreCase, csStart, string, start, length); - } - - /** - *

Case in-sensitive find of the first index within a CharSequence - * from the specified position.

- * - *

A {@code null} CharSequence will return {@code -1}. - * A negative start position is treated as zero. - * An empty ("") search CharSequence always matches. - * A start position greater than the string length only matches - * an empty search CharSequence.

- * - *
-   * AsciiString.indexOfIgnoreCase(null, *, *)          = -1
-   * AsciiString.indexOfIgnoreCase(*, null, *)          = -1
-   * AsciiString.indexOfIgnoreCase("", "", 0)           = 0
-   * AsciiString.indexOfIgnoreCase("aabaabaa", "A", 0)  = 0
-   * AsciiString.indexOfIgnoreCase("aabaabaa", "B", 0)  = 2
-   * AsciiString.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
-   * AsciiString.indexOfIgnoreCase("aabaabaa", "B", 3)  = 5
-   * AsciiString.indexOfIgnoreCase("aabaabaa", "B", 9)  = -1
-   * AsciiString.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
-   * AsciiString.indexOfIgnoreCase("aabaabaa", "", 2)   = 2
-   * AsciiString.indexOfIgnoreCase("abc", "", 9)        = -1
-   * 
- * - * @param str the CharSequence to check, may be null - * @param searchStr the CharSequence to find, may be null - * @param startPos the start position, negative treated as zero - * @return the first index of the search CharSequence (always ≥ startPos), - * -1 if no match or {@code null} string input - */ - public static int indexOfIgnoreCase(final CharSequence str, final CharSequence searchStr, int startPos) { - if (str == null || searchStr == null) { - return INDEX_NOT_FOUND; - } - if (startPos < 0) { - startPos = 0; - } - int searchStrLen = searchStr.length(); - final int endLimit = str.length() - searchStrLen + 1; - if (startPos > endLimit) { - return INDEX_NOT_FOUND; - } - if (searchStrLen == 0) { - return startPos; - } - for (int i = startPos; i < endLimit; i++) { - if (regionMatches(str, true, i, searchStr, 0, searchStrLen)) { - return i; - } - } - return INDEX_NOT_FOUND; - } - - /** - *

Case in-sensitive find of the first index within a CharSequence - * from the specified position. This method optimized and works correctly for ASCII CharSequences only

- * - *

A {@code null} CharSequence will return {@code -1}. - * A negative start position is treated as zero. - * An empty ("") search CharSequence always matches. - * A start position greater than the string length only matches - * an empty search CharSequence.

- * - *
-   * AsciiString.indexOfIgnoreCase(null, *, *)          = -1
-   * AsciiString.indexOfIgnoreCase(*, null, *)          = -1
-   * AsciiString.indexOfIgnoreCase("", "", 0)           = 0
-   * AsciiString.indexOfIgnoreCase("aabaabaa", "A", 0)  = 0
-   * AsciiString.indexOfIgnoreCase("aabaabaa", "B", 0)  = 2
-   * AsciiString.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
-   * AsciiString.indexOfIgnoreCase("aabaabaa", "B", 3)  = 5
-   * AsciiString.indexOfIgnoreCase("aabaabaa", "B", 9)  = -1
-   * AsciiString.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
-   * AsciiString.indexOfIgnoreCase("aabaabaa", "", 2)   = 2
-   * AsciiString.indexOfIgnoreCase("abc", "", 9)        = -1
-   * 
- * - * @param str the CharSequence to check, may be null - * @param searchStr the CharSequence to find, may be null - * @param startPos the start position, negative treated as zero - * @return the first index of the search CharSequence (always ≥ startPos), - * -1 if no match or {@code null} string input - */ - public static int indexOfIgnoreCaseAscii(final CharSequence str, final CharSequence searchStr, int startPos) { - if (str == null || searchStr == null) { - return INDEX_NOT_FOUND; - } - if (startPos < 0) { - startPos = 0; - } - int searchStrLen = searchStr.length(); - final int endLimit = str.length() - searchStrLen + 1; - if (startPos > endLimit) { - return INDEX_NOT_FOUND; - } - if (searchStrLen == 0) { - return startPos; - } - for (int i = startPos; i < endLimit; i++) { - if (regionMatchesAscii(str, true, i, searchStr, 0, searchStrLen)) { - return i; - } - } - return INDEX_NOT_FOUND; - } - - /** - *

Finds the first index in the {@code CharSequence} that matches the - * specified character.

- * - * @param cs the {@code CharSequence} to be processed, not null - * @param searchChar the char to be searched for - * @param start the start index, negative starts at the string start - * @return the index where the search char was found, - * -1 if char {@code searchChar} is not found or {@code cs == null} - */ - // ----------------------------------------------------------------------- - public static int indexOf(final CharSequence cs, final char searchChar, int start) { - if (cs instanceof String) { - return ((String) cs).indexOf(searchChar, start); - } else if (cs instanceof ByteBufAsciiString) { - return ((ByteBufAsciiString) cs).indexOf(searchChar, start); - } - if (cs == null) { - return INDEX_NOT_FOUND; - } - return AsciiString.indexOf(cs, searchChar, start); - } - - private static boolean equalsIgnoreCase(byte a, byte b) { - return a == b || toLowerCase(a) == toLowerCase(b); - } - - private static boolean equalsIgnoreCase(char a, char b) { - return a == b || toLowerCase(a) == toLowerCase(b); - } - - private static byte toLowerCase(byte b) { - return isUpperCase(b) ? (byte) (b + 32) : b; - } - - static char toLowerCase(char c) { - return isUpperCase(c) ? (char) (c + 32) : c; - } - - private static byte toUpperCase(byte b) { - return isLowerCase(b) ? (byte) (b - 32) : b; - } - - private static boolean isLowerCase(byte value) { - return value >= 'a' && value <= 'z'; - } - - public static boolean isUpperCase(byte value) { - return value >= 'A' && value <= 'Z'; - } - - public static boolean isUpperCase(char value) { - return value >= 'A' && value <= 'Z'; - } - - public static byte c2b(char c) { - return (byte) ((c > MAX_CHAR_VALUE) ? '?' : c); - } - - public static byte c2b0(char c) { - return (byte) c; - } - - public static char b2c(byte b) { - return (char) (b & 0xFF); - } - - @Override - public int refCnt() { - return _buf.refCnt(); - } - - @Override - public ByteBufAsciiString retain() { - _buf.retain(); - return this; - } - - @Override - public ByteBufAsciiString retain(int increment) { - _buf.retain(increment); - return this; - } - - @Override - public ReferenceCounted touch() { - _buf.touch(); - return this; - } - - @Override - public ReferenceCounted touch(Object hint) { - _buf.touch(hint); - return this; - } - - @Override - public boolean release() { - return _buf.release(); - } - - @Override - public boolean release(int decrement) { - return _buf.release(decrement); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/misc/HeaderStringCache.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/misc/HeaderStringCache.java deleted file mode 100644 index 50d30b32bb6..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/misc/HeaderStringCache.java +++ /dev/null @@ -1,159 +0,0 @@ -package com.linkedin.alpini.base.misc; - -import io.netty.util.AsciiString; -import java.util.ArrayDeque; -import java.util.Deque; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import javax.annotation.Nonnull; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -public class HeaderStringCache { - private static final Logger LOG = LogManager.getLogger(HeaderStringCache.class); - - /** - * The default initial capacity - MUST be a power of two. - */ - private static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16 - - private static final int EXPIRE_MILLISECONDS = 1000; // A + B Map == 2 seconds retention - - private static final ThreadLocal CACHE_THREAD_LOCAL = ThreadLocal.withInitial(Cache::new); - - private HeaderStringCache() { - // never instantiated - } - - public static Cache getAndExpireOld() { - Cache cache = CACHE_THREAD_LOCAL.get(); - cache.expire(); - return cache; - } - - public static class Cache { - private final Deque> _cache = new ArrayDeque<>(3); - private long _expirationTime; - - private Cache() { - _cache.add(new HashMap<>()); - _cache.add(new HashMap<>()); - } - - /** - * Header names are cached case insensitive. - * @param key CharSequence - * @return cached instance - */ - public CharSequence lookupName(CharSequence key) { - NameKey tmpKey = new NameKey(key); - CharSequence cachedName = _cache.peekFirst().get(tmpKey); - if (cachedName == null) { - cachedName = _cache.peekLast().get(tmpKey); - if (cachedName == null) { - cachedName = key.toString(); - } - _cache.peekFirst().put(new NameKey(cachedName), cachedName); - } - return cachedName; - } - - /** - * Header values are cached case sensitive. - * @param key CharSequence - * @return cached instance - */ - public CharSequence lookupValue(CharSequence key) { - ValueKey tmpKey = new ValueKey(key); - CharSequence cachedValue = _cache.peekFirst().get(tmpKey); - if (cachedValue == null) { - cachedValue = _cache.peekLast().get(tmpKey); - if (cachedValue == null) { - cachedValue = AsciiString.of(key); - } - _cache.peekFirst().put(new ValueKey(cachedValue), cachedValue); - } - return cachedValue; - } - - void expire() { - long now = Time.nanoTime(); - if (now >= _expirationTime) { - _cache.addFirst(new HashMap<>(Math.max(DEFAULT_INITIAL_CAPACITY, _cache.peekFirst().size()))); - int removedSize = _cache.removeLast().size(); - LOG.debug("removing old map (size={})", removedSize); - _expirationTime = now + TimeUnit.MILLISECONDS.toNanos(EXPIRE_MILLISECONDS); - } - } - } - - private static abstract class Key implements CharSequence { - final CharSequence _charSequence; - private final int _hashCode; - - private Key(CharSequence charSequence, int hashCode) { - _charSequence = charSequence; - _hashCode = hashCode; - } - - @Override - public int length() { - return _charSequence.length(); - } - - @Override - public char charAt(int index) { - return _charSequence.charAt(index); - } - - @Override - public CharSequence subSequence(int start, int end) { - return _charSequence.subSequence(start, end); - } - - public int hashCode() { - return _hashCode; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - return test((Key) o); - } - - protected abstract boolean test(Key other); - - @Override - @Nonnull - public String toString() { - return _charSequence.toString(); - } - } - - private static final class NameKey extends Key { - private NameKey(CharSequence charSequence) { - super(charSequence, ByteBufAsciiString.hashCode(LowerCaseAsciiCharSequence.toLowerCase(charSequence))); - } - - protected boolean test(Key other) { - return ByteBufAsciiString.contentEqualsIgnoreCase(_charSequence, other._charSequence); - } - } - - private static final class ValueKey extends Key { - private ValueKey(CharSequence charSequence) { - super(charSequence, ByteBufAsciiString.hashCode(charSequence)); - } - - protected boolean test(Key other) { - return ByteBufAsciiString.contentEquals(_charSequence, other._charSequence); - } - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/misc/LowerCaseAsciiCharSequence.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/misc/LowerCaseAsciiCharSequence.java deleted file mode 100644 index 9c5dc8b8a5c..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/misc/LowerCaseAsciiCharSequence.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.linkedin.alpini.base.misc; - -import io.netty.util.internal.PlatformDependent; -import javax.annotation.Nonnull; -import org.apache.logging.log4j.util.StringBuilderFormattable; - - -public class LowerCaseAsciiCharSequence implements CharSequence, StringBuilderFormattable, Comparable { - private final CharSequence _charSequence; - - public LowerCaseAsciiCharSequence(@Nonnull CharSequence charSequence) { - _charSequence = charSequence; - } - - @Nonnull - public static CharSequence toLowerCase(@Nonnull CharSequence charSequence) { - for (int i = charSequence.length() - 1; i > 0; i--) { - byte b = ByteBufAsciiString.c2b(charSequence.charAt(i)); - if (b >= 'A' && b <= 'Z') { - return new LowerCaseAsciiCharSequence(charSequence); - } - } - return charSequence; - } - - @Override - public int length() { - return _charSequence.length(); - } - - @Override - public char charAt(int index) { - return ByteBufAsciiString.toLowerCase(_charSequence.charAt(index)); - } - - @Override - public CharSequence subSequence(int start, int end) { - CharSequence sub = _charSequence.subSequence(start, end); - if (sub.length() < 1) { - return ""; - } - return new LowerCaseAsciiCharSequence(sub); - } - - @Override - public boolean equals(Object o) { - return this == o || (o instanceof CharSequence && ByteBufAsciiString.contentEquals((CharSequence) o, this)); - } - - @Override - public int hashCode() { - return PlatformDependent.hashCodeAscii(this); - } - - @Override - @Nonnull - public String toString() { - StringBuilder sb = Msg.stringBuilder(); - formatTo(sb); - return sb.toString(); - } - - @Override - public void formatTo(StringBuilder buffer) { - buffer.append(this); - } - - @Override - public int compareTo(@Nonnull CharSequence o) { - if (this == o) { - return 0; - } - - int result; - int length1 = length(); - int length2 = o.length(); - int minLength = Math.min(length1, length2); - for (int i = 0; i < minLength; i++) { - result = charAt(i) - o.charAt(i); - if (result != 0) { - return result; - } - } - return length1 - length2; - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/misc/Netty4ThrowException.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/misc/Netty4ThrowException.java deleted file mode 100644 index b4356a60931..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/misc/Netty4ThrowException.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.linkedin.alpini.base.misc; - -import io.netty.util.internal.PlatformDependent; - - -/** - * Simple wrapper using Netty4 {@linkplain PlatformDependent} implementation - */ -public final class Netty4ThrowException implements ExceptionUtil.ExceptionThrower { - @Override - public void throwException(Throwable throwable) { - PlatformDependent.throwException(throwable); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/misc/PromiseDelegate.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/misc/PromiseDelegate.java deleted file mode 100644 index 83939264ae1..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/misc/PromiseDelegate.java +++ /dev/null @@ -1,169 +0,0 @@ -package com.linkedin.alpini.base.misc; - -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.GenericFutureListener; -import io.netty.util.concurrent.Promise; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - - -/** - * A simple delegate class which wraps an existing {@link Promise} and permits - * overriding of some of its methods. - * - * @author acurtis - * - * @param promise type - */ -public class PromiseDelegate implements Promise { - private final Promise _promise; - - public PromiseDelegate(Promise promise) { - _promise = promise; - } - - @Override - public final Promise setSuccess(V result) { - if (trySuccess(result)) { - return this; - } - throw new IllegalStateException("complete already: " + this); - } - - @Override - public boolean trySuccess(V result) { - return _promise.trySuccess(result); - } - - @Override - public final Promise setFailure(Throwable cause) { - if (tryFailure(cause)) { - return this; - } - throw new IllegalStateException("complete already: " + this); - } - - @Override - public boolean tryFailure(Throwable cause) { - return _promise.tryFailure(cause); - } - - @Override - public boolean setUncancellable() { - return _promise.setUncancellable(); - } - - @Override - public boolean isSuccess() { - return _promise.isSuccess(); - } - - @Override - public final boolean isCancellable() { - return _promise.isCancellable(); - } - - @Override - public final Throwable cause() { - return _promise.cause(); - } - - @Override - public Promise addListener(GenericFutureListener> listener) { - _promise.addListener(listener); - return this; - } - - @Override - public Promise addListeners(GenericFutureListener>... listeners) { - _promise.addListeners(listeners); - return this; - } - - @Override - public Promise removeListener(GenericFutureListener> listener) { - _promise.removeListener(listener); - return this; - } - - @Override - public Promise removeListeners(GenericFutureListener>... listeners) { - _promise.removeListeners(listeners); - return this; - } - - @Override - public Promise await() throws InterruptedException { - _promise.await(); - return this; - } - - @Override - public Promise awaitUninterruptibly() { - _promise.awaitUninterruptibly(); - return this; - } - - @Override - public boolean await(long timeout, TimeUnit unit) throws InterruptedException { - return _promise.await(timeout, unit); - } - - @Override - public boolean await(long timeoutMillis) throws InterruptedException { - return _promise.await(timeoutMillis); - } - - @Override - public boolean awaitUninterruptibly(long timeout, TimeUnit unit) { - return _promise.awaitUninterruptibly(timeout, unit); - } - - @Override - public boolean awaitUninterruptibly(long timeoutMillis) { - return _promise.awaitUninterruptibly(timeoutMillis); - } - - @Override - public V getNow() { - return _promise.getNow(); - } - - @Override - public boolean cancel(boolean mayInterruptIfRunning) { - return _promise.cancel(mayInterruptIfRunning); - } - - @Override - public boolean isCancelled() { - return _promise.isCancelled(); - } - - @Override - public boolean isDone() { - return _promise.isDone(); - } - - @Override - public final V get() throws InterruptedException, ExecutionException { - return _promise.get(); - } - - @Override - public final V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { - return _promise.get(timeout, unit); - } - - @Override - public final Promise sync() throws InterruptedException { - _promise.sync(); - return this; - } - - @Override - public final Promise syncUninterruptibly() { - _promise.syncUninterruptibly(); - return this; - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/safealloc/DerivedMutableByteBuf.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/safealloc/DerivedMutableByteBuf.java deleted file mode 100644 index f20a8e0a90b..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/safealloc/DerivedMutableByteBuf.java +++ /dev/null @@ -1,135 +0,0 @@ -package com.linkedin.alpini.base.safealloc; - -import io.netty.buffer.ByteBuf; -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; -import java.nio.channels.ScatteringByteChannel; - - -/** - * Mutable {@linkplain ByteBuf}. - */ -public final class DerivedMutableByteBuf extends DerivedReadableByteBuf { - public DerivedMutableByteBuf(ByteBuf buf) { - this(buf, 0, -1); - super.setIndex(buf.readerIndex(), buf.writerIndex()); - super.markReaderIndex(); - super.markWriterIndex(); - } - - public DerivedMutableByteBuf(ByteBuf buf, int offset, int length) { - super(buf, offset, length); - } - - @Override - public final boolean isReadOnly() { - return unwrap0().isReadOnly(); - } - - @Override - public final ByteBuf asReadOnly() { - if (isReadOnly()) { - return this; - } - return new DerivedReadOnlyByteBuf(unwrap0(), start(0, capacity()), -1).setIndex(readerIndex(), writerIndex()) - .markReaderIndex() - .markWriterIndex() - .asReadOnly(); - } - - @Override - protected final void _setByte(int index, int value) { - unwrap0().setByte(start(index, 1), value); - } - - @Override - protected final void _setShort(int index, int value) { - unwrap0().setShort(start(index, 2), value); - } - - @Override - protected final void _setShortLE(int index, int value) { - unwrap0().setShortLE(start(index, 2), value); - } - - @Override - protected final void _setMedium(int index, int value) { - unwrap0().setMedium(start(index, 3), value); - } - - @Override - protected final void _setMediumLE(int index, int value) { - unwrap0().setMediumLE(start(index, 3), value); - } - - @Override - protected final void _setInt(int index, int value) { - unwrap0().setInt(start(index, 4), value); - } - - @Override - protected final void _setIntLE(int index, int value) { - unwrap0().setIntLE(start(index, 4), value); - } - - @Override - protected final void _setLong(int index, long value) { - unwrap0().setLong(start(index, 8), value); - } - - @Override - protected final void _setLongLE(int index, long value) { - unwrap0().setLongLE(start(index, 8), value); - } - - protected ByteBuf duplicate0() { - return new DerivedMutableByteBuf(unwrap0(), start(0, capacity()), -1); - } - - @Override - protected ByteBuf slice0(int index, int length) { - return new DerivedMutableByteBuf(unwrap0(), start(index, length), length).markReaderIndex() - .markWriterIndex() - .setIndex(0, length); - } - - @Override - public final ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { - unwrap0().setBytes(start(index, length), src, srcIndex, length); - return this; - } - - @Override - public final ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { - unwrap0().setBytes(start(index, length), src, srcIndex, length); - return this; - } - - @Override - public final ByteBuf setBytes(int index, ByteBuffer src) { - unwrap0().setBytes(start(index, src.remaining()), src); - return this; - } - - @Override - public final int setBytes(int index, InputStream in, int length) throws IOException { - return unwrap0().setBytes(start(index, length), in, length); - } - - @Override - public final int setBytes(int index, ScatteringByteChannel in, int length) throws IOException { - return unwrap0().setBytes(start(index, length), in, length); - } - - @Override - public final int setBytes(int index, FileChannel in, long position, int length) throws IOException { - return unwrap0().setBytes(start(index, length), in, position, length); - } - - @Override - public ByteBuf copy(int index, int length) { - return new DerivedMutableByteBuf(unwrap0().copy(start(index, length), length)); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/safealloc/DerivedReadOnlyByteBuf.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/safealloc/DerivedReadOnlyByteBuf.java deleted file mode 100644 index 260a550b208..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/safealloc/DerivedReadOnlyByteBuf.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.linkedin.alpini.base.safealloc; - -import io.netty.buffer.ByteBuf; - - -/** - * Immutable {@linkplain ByteBuf}. - */ -public final class DerivedReadOnlyByteBuf extends DerivedReadableByteBuf { - public DerivedReadOnlyByteBuf(ByteBuf buf) { - super(buf); - } - - public DerivedReadOnlyByteBuf(ByteBuf buf, int offset, int length) { - super(buf, offset, length); - } - - @Override - public boolean isReadOnly() { - return true; - } - - @Override - public ByteBuf asReadOnly() { - return this; - } - - @Override - public boolean isWritable() { - return false; - } - - @Override - public boolean isWritable(int numBytes) { - return false; - } - - @Override - public int writableBytes() { - return 0; - } - - @Override - public int maxWritableBytes() { - return 0; - } - - @Override - public ByteBuf ensureWritable(int minWritableBytes) { - if (minWritableBytes > 0) { - return readOnly(); - } - return this; - } - - @Override - public int ensureWritable(int minWritableBytes, boolean force) { - return 1; - } - - @Override - protected ByteBuf duplicate0() { - return new DerivedReadOnlyByteBuf(unwrap0(), start(0, capacity()), -1); - } - - @Override - protected ByteBuf slice0(int index, int length) { - return new DerivedReadOnlyByteBuf(unwrap0(), start(index, length), length).setIndex(0, Math.min(capacity(), length)) - .markReaderIndex() - .markWriterIndex(); - } - - @Override - public boolean hasMemoryAddress() { - return false; - } - - @Override - public long memoryAddress() { - throw new UnsupportedOperationException(); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/safealloc/DerivedReadableByteBuf.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/safealloc/DerivedReadableByteBuf.java deleted file mode 100644 index 5bd346188a8..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/safealloc/DerivedReadableByteBuf.java +++ /dev/null @@ -1,455 +0,0 @@ -package com.linkedin.alpini.base.safealloc; - -import io.netty.buffer.AbstractByteBuf; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; -import io.netty.buffer.Unpooled; -import io.netty.util.ByteProcessor; -import io.netty.util.IllegalReferenceCountException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.ReadOnlyBufferException; -import java.nio.channels.FileChannel; -import java.nio.channels.GatheringByteChannel; -import java.nio.channels.ScatteringByteChannel; -import java.nio.charset.Charset; - - -/** - * Abstract base {@linkplain ByteBuf} used to point to either a {@linkplain SafeByteBuf} or another instance of - * {@linkplain DerivedReadableByteBuf}. - */ -abstract class DerivedReadableByteBuf extends AbstractByteBuf { - private ByteBuf _buf; - private int _offset; - private int _length; - - protected DerivedReadableByteBuf(ByteBuf buf) { - this(buf, 0, -1); - } - - protected DerivedReadableByteBuf(ByteBuf buf, int offset, int length) { - super(length >= 0 ? Math.min(buf.maxCapacity() - offset, length) : buf.maxCapacity() - offset); - _buf = buf; - _offset = offset; - _length = length; - } - - protected final int start(int index, int length) { - if (index < 0 || length < 0) { - throw new ArrayIndexOutOfBoundsException(); - } else { - int capacity = capacity(); - if (Math.addExact(index, length) > capacity) { - throw new ArrayIndexOutOfBoundsException("index=" + index + ", length=" + length + ", capacity=" + capacity); - } - } - return Math.addExact(index, _offset); - } - - private ByteBuf checkReaderIndex() { - if (readerIndex() > writerIndex()) { - throw new IndexOutOfBoundsException(); - } - return this; - } - - @Override - public ByteBuf resetReaderIndex() { - super.resetReaderIndex(); - return checkReaderIndex(); - } - - @Override - public ByteBuf resetWriterIndex() { - super.resetWriterIndex(); - return checkReaderIndex(); - } - - @Override - protected final byte _getByte(int index) { - return unwrap0().getByte(start(index, 1)); - } - - @Override - protected final short _getShort(int index) { - return unwrap0().getShort(start(index, 2)); - } - - @Override - protected final short _getShortLE(int index) { - return unwrap0().getShortLE(start(index, 2)); - } - - @Override - protected final int _getUnsignedMedium(int index) { - return unwrap0().getUnsignedMedium(start(index, 3)); - } - - @Override - protected final int _getUnsignedMediumLE(int index) { - return unwrap0().getUnsignedMediumLE(start(index, 3)); - } - - @Override - protected final int _getInt(int index) { - return unwrap0().getInt(start(index, 4)); - } - - @Override - protected final int _getIntLE(int index) { - return unwrap0().getIntLE(start(index, 4)); - } - - @Override - protected final long _getLong(int index) { - return unwrap0().getLong(start(index, 8)); - } - - @Override - protected final long _getLongLE(int index) { - return unwrap0().getLongLE(start(index, 8)); - } - - final T readOnly() { - throw new ReadOnlyBufferException(); - } - - @Override - protected void _setByte(int index, int value) { - readOnly(); - } - - @Override - protected void _setShort(int index, int value) { - readOnly(); - } - - @Override - protected void _setShortLE(int index, int value) { - readOnly(); - } - - @Override - protected void _setMedium(int index, int value) { - readOnly(); - } - - @Override - protected void _setMediumLE(int index, int value) { - readOnly(); - } - - @Override - protected void _setInt(int index, int value) { - readOnly(); - } - - @Override - protected void _setIntLE(int index, int value) { - readOnly(); - } - - @Override - protected void _setLong(int index, long value) { - readOnly(); - } - - @Override - protected void _setLongLE(int index, long value) { - readOnly(); - } - - @Override - public final ByteBuf duplicate() { - return duplicate0().setIndex(readerIndex(), writerIndex()).markReaderIndex().markWriterIndex(); - } - - protected abstract ByteBuf duplicate0(); - - @Override - public final ByteBuf slice(int index, int length) { - if (isReadOnly() && length == 0) { - ensureAccessible(); - return Unpooled.EMPTY_BUFFER.slice(index, length); - } - return slice0(index, length); - } - - protected abstract ByteBuf slice0(int index, int length); - - @Override - public final String toString(int index, int length, Charset charset) { - return unwrap0().toString(start(index, length), length, charset); - } - - @Override - public final int indexOf(int fromIndex, int toIndex, byte value) { - return Math.max(unwrap0().indexOf(start(fromIndex, 0), start(toIndex, 0), value) - _offset, -1); - } - - @Override - public int bytesBefore(byte value) { - return bytesBefore(readableBytes(), value); - } - - @Override - public int bytesBefore(int length, byte value) { - return bytesBefore(readerIndex(), length, value); - } - - @Override - public int bytesBefore(int index, int length, byte value) { - return Math.max(unwrap0().bytesBefore(start(index, length), length, value) - _offset, -1); - } - - @Override - public int forEachByte(ByteProcessor processor) { - return forEachByte(readerIndex(), readableBytes(), processor); - } - - @Override - public int forEachByte(int index, int length, ByteProcessor processor) { - return Math.max(unwrap0().forEachByte(start(index, length), length, processor) - _offset, -1); - } - - @Override - public int forEachByteDesc(ByteProcessor processor) { - return forEachByteDesc(readerIndex(), readableBytes(), processor); - } - - @Override - public int forEachByteDesc(int index, int length, ByteProcessor processor) { - return Math.max(unwrap0().forEachByteDesc(start(index, length), length, processor) - _offset, -1); - } - - @Override - public int capacity() { - if (_length >= 0) { - return _length; - } else { - return Math.max(unwrap0().capacity() - _offset, 0); - } - } - - @Override - public ByteBuf capacity(int newCapacity) { - if (newCapacity > maxCapacity()) { - String message = "cannot increase capacity from " + capacity() + " to " + newCapacity + " (maxCapacity=" - + maxCapacity() + ", length=" + _length + ", unwrap.capacity=" + unwrap0().capacity() + ")"; - if (_length == -1) { - throw new IllegalArgumentException(message); - } else { - throw new UnsupportedOperationException(message); - } - } else if (Math.addExact(newCapacity, _offset) > unwrap0().capacity()) { - unwrap0().capacity(Math.addExact(newCapacity, _offset)); - } else if (newCapacity < 0) { - throw new IllegalArgumentException(); - } else if (newCapacity < _length || _length == -1) { - _length = newCapacity; - } - return this; - } - - @Override - public final ByteBufAllocator alloc() { - return unwrap0().alloc(); - } - - @Override - public final ByteOrder order() { - return unwrap0().order(); - } - - @Override - public ByteBuf unwrap() { - return _offset == 0 ? unwrap0() : unwrap0().slice(_offset, maxCapacity()).setIndex(0, 0); - } - - protected ByteBuf unwrap0() { - if (_buf != null && _buf.refCnt() >= 1) { - return _buf; - } else { - throw new IllegalReferenceCountException(); - } - } - - @Override - public final boolean isDirect() { - return unwrap0().isDirect(); - } - - @Override - public final ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { - unwrap0().getBytes(start(index, length), dst, dstIndex, length); - return this; - } - - @Override - public final ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { - unwrap0().getBytes(start(index, length), dst, dstIndex, length); - return this; - } - - @Override - public final ByteBuf getBytes(int index, ByteBuffer dst) { - unwrap0().getBytes(start(index, dst.remaining()), dst); - return this; - } - - @Override - public final ByteBuf getBytes(int index, OutputStream out, int length) throws IOException { - unwrap0().getBytes(start(index, length), out, length); - return this; - } - - @Override - public final int getBytes(int index, GatheringByteChannel out, int length) throws IOException { - return unwrap0().getBytes(start(index, length), out, length); - } - - @Override - public final int getBytes(int index, FileChannel out, long position, int length) throws IOException { - return unwrap0().getBytes(start(index, length), out, position, length); - } - - @Override - public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { - return readOnly(); - } - - @Override - public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { - return readOnly(); - } - - @Override - public ByteBuf setBytes(int index, ByteBuffer src) { - return readOnly(); - } - - @Override - public int setBytes(int index, InputStream in, int length) throws IOException { - return readOnly(); - } - - @Override - public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException { - return readOnly(); - } - - @Override - public int setBytes(int index, FileChannel in, long position, int length) throws IOException { - return readOnly(); - } - - @Override - public ByteBuf copy(int index, int length) { - if (length == 0) { - return Unpooled.EMPTY_BUFFER; - } - ByteBuf c = new DerivedReadOnlyByteBuf(unwrap0().copy(start(index, length), length)); - c.writerIndex(length); - return c; - } - - @Override - public final int nioBufferCount() { - return unwrap0().nioBufferCount(); - } - - @Override - public final ByteBuffer nioBuffer(int index, int length) { - return unwrap0().nioBuffer(start(index, length), length); - } - - @Override - public final ByteBuffer internalNioBuffer(int index, int length) { - return unwrap0().internalNioBuffer(start(index, length), length); - } - - @Override - public final ByteBuffer[] nioBuffers(int index, int length) { - return unwrap0().nioBuffers(start(index, length), length); - } - - @Override - public final boolean hasArray() { - return _buf != null && _buf.hasArray(); - } - - @Override - public final byte[] array() { - return unwrap0().array(); - } - - @Override - public final int arrayOffset() { - return unwrap0().arrayOffset() + start(0, capacity()); - } - - @Override - public boolean hasMemoryAddress() { - return _buf != null && _buf.hasMemoryAddress(); - } - - @Override - public long memoryAddress() { - return unwrap0().memoryAddress() + start(0, capacity()); - } - - @Override - public ByteBuf retain(int increment) { - unwrap0().retain(increment); - return this; - } - - @Override - public int refCnt() { - return _buf == null ? 0 : _buf.refCnt(); - } - - @Override - public ByteBuf retain() { - unwrap0().retain(); - return this; - } - - @Override - public ByteBuf touch() { - unwrap0().touch(); - return this; - } - - @Override - public ByteBuf touch(Object hint) { - unwrap0().touch(hint); - return this; - } - - @Override - public boolean release() { - return unwrap0().release(); - } - - @Override - public boolean release(int decrement) { - return unwrap0().release(decrement); - } - - @Override - public ByteBuf discardReadBytes() { - ensureAccessible(); - return this; - } - - @Override - public ByteBuf discardSomeReadBytes() { - ensureAccessible(); - return this; - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/safealloc/SafeAllocator.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/safealloc/SafeAllocator.java deleted file mode 100644 index 2953f6b2e23..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/safealloc/SafeAllocator.java +++ /dev/null @@ -1,161 +0,0 @@ -package com.linkedin.alpini.base.safealloc; - -import io.netty.buffer.AbstractByteBufAllocator; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; -import io.netty.buffer.ByteBufAllocatorMetric; -import io.netty.buffer.ByteBufAllocatorMetricProvider; -import io.netty.buffer.PooledByteBufAllocator; -import io.netty.buffer.UnpooledByteBufAllocator; -import io.netty.util.internal.PlatformDependent; -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.LongAdder; -import javax.annotation.Nonnull; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** - * An instance of {@link SafeAllocator} may be used to wrap an existing {@linkplain ByteBufAllocator} - * to provide insurance against slow memory leaks from exceptional conditions by providing a means - * for the leaked {@linkplain ByteBuf} objects to be reclaimed. - * - * Makes use of a reference queue per thread in order to avoid some of the synchronization costs. - */ -public class SafeAllocator extends AbstractByteBufAllocator implements ByteBufAllocatorMetricProvider { - private static final Logger LOG = LogManager.getLogger(SafeAllocator.class); - - public static final SafeAllocator POOLED_ALLOCATOR; - - public static final SafeAllocator UNPOOLED_ALLOCATOR; - - private static final ByteBufAllocatorMetric UNKNOWN_METRICS = new ByteBufAllocatorMetric() { - @Override - public long usedHeapMemory() { - return -1; - } - - @Override - public long usedDirectMemory() { - return -1; - } - }; - - private final ByteBufAllocator _allocator; - private final SafeAllocatorMetric _metric; - private final ThreadLocal _referenceQueue; - final ConcurrentMap _active; - final LongAdder _leakCount; - final LongAdder _referenceCount; - final LongAdder _queuesCount; - - public SafeAllocator(@Nonnull ByteBufAllocator allocator) { - super(PlatformDependent.directBufferPreferred()); - _allocator = allocator; - _referenceQueue = ThreadLocal.withInitial(FinalizableReferenceQueue::new); - _active = new ConcurrentHashMap<>(256, 0.75f, 48); - _leakCount = new LongAdder(); - _referenceCount = new LongAdder(); - _queuesCount = new LongAdder(); - - _metric = new SafeAllocatorMetric( - this, - allocator instanceof ByteBufAllocatorMetricProvider - ? ((ByteBufAllocatorMetricProvider) allocator).metric() - : UNKNOWN_METRICS); - } - - final FinalizableReferenceQueue referenceQueue() { - return _referenceQueue.get(); - } - - private FinalizableReferenceQueue checkReferenceQueue() { - return referenceQueue().check(); - } - - final SafeReference makeReference(SafeByteBuf referent, ReferenceQueue queue, ByteBuf buf) { - SafeReference ref = new SafeReference(referent, queue, buf); - _referenceCount.increment(); - _active.put(ref, Boolean.TRUE); - return ref; - } - - private ByteBuf newBuffer(FinalizableReferenceQueue queue, ByteBuf source) { - ByteBuf buf = new DerivedMutableByteBuf(new SafeByteBuf(this, queue, source)); - buf.setIndex(0, 0); - buf.markReaderIndex(); - buf.markWriterIndex(); - return buf.touch(this); - } - - @Override - protected final ByteBuf newHeapBuffer(int initialCapacity, int maxCapacity) { - return newBuffer(checkReferenceQueue(), _allocator.heapBuffer(initialCapacity, maxCapacity)); - } - - @Override - protected final ByteBuf newDirectBuffer(int initialCapacity, int maxCapacity) { - return newBuffer(checkReferenceQueue(), _allocator.directBuffer(initialCapacity, maxCapacity)); - } - - @Override - public final boolean isDirectBufferPooled() { - return _allocator.isDirectBufferPooled(); - } - - @Override - public SafeAllocatorMetric metric() { - return _metric; - } - - protected void reportLeak(String message, int capacity, ByteBuf buf, Object hint) { - LOG.error(message, capacity, buf, hint); - } - - @Override - public String toString() { - return "SafeAllocator{" + "_allocator=" + _allocator + '}'; - } - - private class FinalizableReferenceQueue extends ReferenceQueue { - FinalizableReferenceQueue() { - _queuesCount.increment(); - } - - FinalizableReferenceQueue check() { - Reference ref; - do { - ref = poll(); - if (ref instanceof SafeReference) { - SafeReference reference = (SafeReference) ref; - _leakCount.increment(); - int capacity = reference.capacity(); - String message; - if (!_active.remove(reference)) { - message = "Missing reference, cap=(), {}, last touched by {}"; - } else if (reference.release()) { - message = "Leak recovered, cap={}, {}, last touched by {}"; - } else { - message = "Unrecovered leak, cap={}, {} last touched by {}"; - } - reportLeak(message, capacity, reference.store(), reference._hint); - } - } while (ref != null); - return this; - } - - @Override - protected void finalize() throws Throwable { - check(); - super.finalize(); - } - } - - static { - POOLED_ALLOCATOR = new SafeAllocator(PooledByteBufAllocator.DEFAULT); - UNPOOLED_ALLOCATOR = new SafeAllocator(UnpooledByteBufAllocator.DEFAULT); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/safealloc/SafeAllocatorMetric.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/safealloc/SafeAllocatorMetric.java deleted file mode 100644 index 14e78d33347..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/safealloc/SafeAllocatorMetric.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.linkedin.alpini.base.safealloc; - -import io.netty.buffer.ByteBufAllocatorMetric; - - -/** - * Metrics regarding the {@link SafeAllocator} - */ -public final class SafeAllocatorMetric implements ByteBufAllocatorMetric { - private final SafeAllocator _allocator; - private final ByteBufAllocatorMetric _metric; - - SafeAllocatorMetric(SafeAllocator allocator, ByteBufAllocatorMetric metric) { - _allocator = allocator; - _metric = metric; - } - - public long totalReferences() { - return _allocator._referenceCount.longValue(); - } - - public long totalQueues() { - return _allocator._queuesCount.longValue(); - } - - public long activeAllocations() { - return _allocator._active.size(); - } - - public long leakedAllocations() { - return _allocator._leakCount.longValue(); - } - - @Override - public long usedHeapMemory() { - return _metric.usedHeapMemory(); - } - - @Override - public long usedDirectMemory() { - return _metric.usedDirectMemory(); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/safealloc/SafeByteBuf.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/safealloc/SafeByteBuf.java deleted file mode 100644 index d19c21b4dc3..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/safealloc/SafeByteBuf.java +++ /dev/null @@ -1,422 +0,0 @@ -package com.linkedin.alpini.base.safealloc; - -import io.netty.buffer.AbstractReferenceCountedByteBuf; -import io.netty.buffer.ByteBuf; -import io.netty.util.ByteProcessor; -import io.netty.util.IllegalReferenceCountException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.lang.ref.ReferenceQueue; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.channels.FileChannel; -import java.nio.channels.GatheringByteChannel; -import java.nio.channels.ScatteringByteChannel; - - -/** - * A {@linkplain AbstractReferenceCountedByteBuf} which maintains the reference count - * for the memory object so that we can {@link #deallocate()} it later when the - * reference count drops to zero. - */ -final class SafeByteBuf extends AbstractReferenceCountedByteBuf { - private final SafeAllocator _alloc; - private SafeReference _ref; - private boolean _hasArray; - private boolean _hasMemoryAddress; - - SafeByteBuf(SafeAllocator alloc, ReferenceQueue queue, ByteBuf buf) { - super(buf.maxCapacity()); - _alloc = alloc; - _ref = alloc.makeReference(this, queue, buf); - _hasArray = buf.hasArray(); - _hasMemoryAddress = buf.hasMemoryAddress(); - } - - SafeByteBuf(SafeByteBuf source) { - super(source._ref.store().maxCapacity()); - _alloc = source._alloc; - _ref = source._ref; - _hasArray = source._hasArray; - _hasMemoryAddress = source._hasMemoryAddress; - super.setIndex(source.readerIndex(), source.writerIndex()); - } - - private SafeByteBuf(SafeAllocator alloc, ByteBuf copy) { - this(alloc, alloc.referenceQueue(), copy); - } - - @Override - public ByteBuf retain() { - touch(); - return super.retain(); - } - - @Override - public ByteBuf retain(int increment) { - touch(); - return super.retain(increment); - } - - private SafeReference ref() { - if (_ref == null) { - throw new IllegalReferenceCountException(); - } - return _ref; - } - - @Override - public ByteBuf touch() { - ref().touch(); - return this; - } - - @Override - public ByteBuf touch(Object hint) { - ref().touch(hint); - return this; - } - - @Override - public boolean release() { - touch(); - return super.release(); - } - - @Override - public boolean release(int decrement) { - touch(); - return super.release(decrement); - } - - @Override - protected void deallocate() { - SafeReference ref = ref(); - ref.clear(); - unwrap0().release(); - alloc()._active.remove(ref); - _ref = null; - } - - private ByteBuf unwrap0() { - return ref().store(); - } - - private ByteBuf unwrap0(ByteBuf store) { - _hasArray = store.hasArray(); - _hasMemoryAddress = store.hasMemoryAddress(); - return ref().store(store); - } - - @Override - public ByteBuf readerIndex(int readerIndex) { - try { - return super.readerIndex(readerIndex); - } finally { - unwrap0().setIndex(readerIndex(), writerIndex()); - } - } - - @Override - public ByteBuf writerIndex(int writerIndex) { - try { - return super.writerIndex(writerIndex); - } finally { - unwrap0().setIndex(readerIndex(), writerIndex()); - } - } - - @Override - public ByteBuf setIndex(int readerIndex, int writerIndex) { - unwrap0().setIndex(readerIndex, writerIndex); - return super.setIndex(readerIndex, writerIndex); - } - - @Override - public ByteBuf discardReadBytes() { - int readerIndex = readerIndex(); - ByteBuf buf = unwrap0().setIndex(readerIndex, writerIndex()); - buf = unwrap0(buf.discardReadBytes()); - super.setIndex(buf.readerIndex(), buf.writerIndex()); - adjustMarkers(readerIndex - readerIndex()); - return this; - } - - @Override - public ByteBuf discardSomeReadBytes() { - int readerIndex = readerIndex(); - ByteBuf buf = unwrap0().setIndex(readerIndex, writerIndex()); - buf = unwrap0(buf.discardSomeReadBytes()); - super.setIndex(buf.readerIndex(), buf.writerIndex()); - adjustMarkers(readerIndex - readerIndex()); - return this; - } - - @Override - public ByteBuf clear() { - unwrap0().clear(); - return super.clear(); - } - - @Override - protected byte _getByte(int index) { - return unwrap0().getByte(index); - } - - @Override - protected short _getShort(int index) { - return unwrap0().getShort(index); - } - - @Override - protected short _getShortLE(int index) { - return unwrap0().getShortLE(index); - } - - @Override - protected int _getUnsignedMedium(int index) { - return unwrap0().getUnsignedMedium(index); - } - - @Override - protected int _getUnsignedMediumLE(int index) { - return unwrap0().getUnsignedMediumLE(index); - } - - @Override - protected int _getInt(int index) { - return unwrap0().getInt(index); - } - - @Override - protected int _getIntLE(int index) { - return unwrap0().getIntLE(index); - } - - @Override - protected long _getLong(int index) { - return unwrap0().getLong(index); - } - - @Override - protected long _getLongLE(int index) { - return unwrap0().getLongLE(index); - } - - @Override - protected void _setByte(int index, int value) { - unwrap0().setByte(index, value); - } - - @Override - protected void _setShort(int index, int value) { - unwrap0().setShort(index, value); - } - - @Override - protected void _setShortLE(int index, int value) { - unwrap0().setShortLE(index, value); - } - - @Override - protected void _setMedium(int index, int value) { - unwrap0().setMedium(index, value); - } - - @Override - protected void _setMediumLE(int index, int value) { - unwrap0().setMediumLE(index, value); - } - - @Override - protected void _setInt(int index, int value) { - unwrap0().setInt(index, value); - } - - @Override - protected void _setIntLE(int index, int value) { - unwrap0().setIntLE(index, value); - } - - @Override - protected void _setLong(int index, long value) { - unwrap0().setLong(index, value); - } - - @Override - protected void _setLongLE(int index, long value) { - unwrap0().setLongLE(index, value); - } - - @Override - public ByteBuf duplicate() { - ByteBuf dup = new DerivedMutableByteBuf(this, 0, -1); - dup.setIndex(readerIndex(), writerIndex()); - dup.markReaderIndex(); - dup.markWriterIndex(); - return dup; - } - - @Override - public int capacity() { - return unwrap0().capacity(); - } - - @Override - public SafeByteBuf capacity(int newCapacity) { - unwrap0(unwrap0().capacity(newCapacity)); - return this; - } - - @Override - public SafeAllocator alloc() { - return _alloc; - } - - @Override - public ByteOrder order() { - return unwrap0().order(); - } - - @Override - public ByteBuf unwrap() { - return unwrap0().unwrap(); - } - - @Override - public boolean isDirect() { - return unwrap0().isDirect(); - } - - @Override - public SafeByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { - unwrap0(unwrap0().getBytes(index, dst, dstIndex, length)); - return this; - } - - @Override - public SafeByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { - unwrap0(unwrap0().getBytes(index, dst, dstIndex, length)); - return this; - } - - @Override - public SafeByteBuf getBytes(int index, ByteBuffer dst) { - unwrap0(unwrap0().getBytes(index, dst)); - return this; - } - - @Override - public SafeByteBuf getBytes(int index, OutputStream out, int length) throws IOException { - unwrap0(unwrap0().getBytes(index, out, length)); - return this; - } - - @Override - public int getBytes(int index, GatheringByteChannel out, int length) throws IOException { - return unwrap0().getBytes(index, out, length); - } - - @Override - public int getBytes(int index, FileChannel out, long position, int length) throws IOException { - return unwrap0().getBytes(index, out, position, length); - } - - @Override - public SafeByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { - unwrap0(unwrap0().setBytes(index, src, srcIndex, length)); - return this; - } - - @Override - public SafeByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { - unwrap0(unwrap0().setBytes(index, src, srcIndex, length)); - return this; - } - - @Override - public SafeByteBuf setBytes(int index, ByteBuffer src) { - unwrap0(unwrap0().setBytes(index, src)); - return this; - } - - @Override - public int setBytes(int index, InputStream in, int length) throws IOException { - return unwrap0().setBytes(index, in, length); - } - - @Override - public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException { - return unwrap0().setBytes(index, in, length); - } - - @Override - public int setBytes(int index, FileChannel in, long position, int length) throws IOException { - return unwrap0().setBytes(index, in, position, length); - } - - @Override - public ByteBuf copy(int index, int length) { - ByteBuf dup = new SafeByteBuf(alloc(), unwrap0().copy(index, length)); - dup.setIndex(0, length); - dup.markReaderIndex(); - dup.markWriterIndex(); - return dup; - } - - @Override - public int nioBufferCount() { - return unwrap0().nioBufferCount(); - } - - @Override - public ByteBuffer nioBuffer(int index, int length) { - return unwrap0().nioBuffer(index, length); - } - - @Override - public ByteBuffer internalNioBuffer(int index, int length) { - return unwrap0().internalNioBuffer(index, length); - } - - @Override - public ByteBuffer[] nioBuffers(int index, int length) { - return unwrap0().nioBuffers(index, length); - } - - @Override - public boolean hasArray() { - return _hasArray; - } - - @Override - public byte[] array() { - return unwrap0().array(); - } - - @Override - public int arrayOffset() { - return unwrap0().arrayOffset(); - } - - @Override - public boolean hasMemoryAddress() { - return _hasMemoryAddress; - } - - @Override - public long memoryAddress() { - return unwrap0().memoryAddress(); - } - - @Override - public int forEachByte(int index, int length, ByteProcessor processor) { - return unwrap0().forEachByte(index, length, processor); - } - - @Override - public int forEachByteDesc(int index, int length, ByteProcessor processor) { - return unwrap0().forEachByteDesc(index, length, processor); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/safealloc/SafeReference.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/safealloc/SafeReference.java deleted file mode 100644 index 05f25f0c269..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/base/safealloc/SafeReference.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.linkedin.alpini.base.safealloc; - -import io.netty.buffer.ByteBuf; -import java.lang.ref.PhantomReference; -import java.lang.ref.ReferenceQueue; -import java.util.Objects; -import java.util.concurrent.ThreadLocalRandom; -import javax.annotation.Nonnull; - - -/** - * A {@linkplain PhantomReference} which holds on to a reference to a {@linkplain ByteBuf} - * so that if the {@link SafeByteBuf} referent were to be garbage collected before the - * object was released, it may be released by the allocator later. - */ -final class SafeReference extends PhantomReference { - Object _hint; - private ByteBuf _store; - private final int _hashCode; - - /** - * Creates a new phantom reference that refers to the given object and - * is registered with the given queue. - * - * @param referent the object the new phantom reference will refer to - * @param q the queue with which the reference is to be registered, - */ - SafeReference(@Nonnull SafeByteBuf referent, @Nonnull ReferenceQueue q, @Nonnull ByteBuf store) { - super(referent, q); - _store = store; - _hashCode = ThreadLocalRandom.current().nextInt(); - } - - ByteBuf store() { - return _store; - } - - ByteBuf store(ByteBuf store) { - _store = store; - return store; - } - - int capacity() { - return _store != null ? _store.capacity() : -1; - } - - boolean release() { - return _store != null && _store.release(); - } - - void touch() { - _store.touch(); - } - - void touch(Object hint) { - _store.touch(hint); - _hint = hint; - } - - @Override - public int hashCode() { - return _hashCode; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - SafeReference that = (SafeReference) o; - return _hashCode == that._hashCode && Objects.equals(_hint, that._hint) && _store.equals(that._store); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/compression/CompressionUtils.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/compression/CompressionUtils.java deleted file mode 100644 index f6d47fb3b5c..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/compression/CompressionUtils.java +++ /dev/null @@ -1,152 +0,0 @@ -package com.linkedin.alpini.netty4.compression; - -import io.netty.channel.ChannelHandler; -import io.netty.handler.codec.compression.SnappyFrameDecoder; -import io.netty.handler.codec.http.HttpHeaderValues; -import io.netty.util.AsciiString; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** - * @author Antony T Curtis {@literal } - */ -public class CompressionUtils { - private static final Logger LOG = LogManager.getLogger(CompressionUtils.class); - - public static final String SNAPPY_ENCODING = "snappy"; - - public static final String X_SNAPPY_ENCODING = "x-snappy"; - - public static final String SNAPPY_FRAMED_ENCODING = "x-snappy-framed"; - - public static final AsciiString SNAPPY = AsciiString.of(SNAPPY_ENCODING); - - public static final AsciiString X_SNAPPY = AsciiString.of(X_SNAPPY_ENCODING); - - /** - * @see x-snappy-framed specification - */ - public static final AsciiString SNAPPY_FRAMED = AsciiString.of(SNAPPY_FRAMED_ENCODING); - - public static final AsciiString GZIP = HttpHeaderValues.GZIP; - public static final AsciiString X_GZIP = HttpHeaderValues.X_GZIP; - public static final AsciiString DEFLATE = HttpHeaderValues.DEFLATE; - public static final AsciiString X_DEFLATE = HttpHeaderValues.X_DEFLATE; - - private CompressionUtils() { - } - - public static ChannelHandler newSnappyDecoder() { - return new SnappyDecoder(); - } - - public static ChannelHandler newSnappyFramedDecoder() { - return new SnappyFrameDecoder(); - } - - private static final float ACCEPTS_THRESHOLD = 0.1f; - - // We cannot use repeated matches because Java's Regexp doesn't support storing repeated matches - private static final Pattern ENCODING_REGEXP = - Pattern.compile("(?:(?:\\A|,)\\s*([^;,]+)|;\\s*([^=;,]+?)(?:\\s*=\\s*([^;,]+)))"); - - /** - * Test if the specific encoding is permitted by the provided list of encodings - * as used in HTTP {@code Accepts-Encoding} header. - * @param encoding specific encoding name. - * @param acceptableEncodings Encoding string as used in HTTP {@code Accepts-Encoding} header. - * @return {@code true} if the specific encoding is permitted by the {@code acceptableEncodings} list. - */ - public static boolean isCompatibleEncoding(CharSequence encoding, CharSequence acceptableEncodings) { - boolean compatible = true; - if (encoding != null) { - if (acceptableEncodings == null) { - return HttpHeaderValues.IDENTITY.contentEquals(encoding); - } - - String accepts = null; - Matcher matcher = ENCODING_REGEXP.matcher(acceptableEncodings); - boolean match; - boolean acceptable = false; - - while ((match = matcher.find()) || accepts != null) { // SUPPRESS CHECKSTYLE InnerAssignment - if (!match || matcher.group(1) != null) { - if (acceptable) { - return true; - } - accepts = null; - if (match) { - accepts = matcher.group(1).trim(); - acceptable = encoding.equals(accepts); - compatible &= acceptable; - } - } else if (acceptable && "q".equals(matcher.group(2))) { - try { - return Float.parseFloat(matcher.group(3).trim()) >= ACCEPTS_THRESHOLD; - } catch (Throwable ex) { - return false; - } - } - } - } - return compatible; - } - - /** - * Test if the specified {@code encoding} names a specific supported encoding. - * @param encoding encoding name - * @return {@code true} if {@code encoding} matches a specific supported implementation. - */ - public static boolean isSupportedSpecificEncoding(CharSequence encoding) { - return SNAPPY.contentEquals(encoding) || SNAPPY_FRAMED.contentEquals(encoding) || GZIP.contentEquals(encoding) - || DEFLATE.contentEquals(encoding) || HttpHeaderValues.IDENTITY.contentEquals(encoding); - } - - /** - * Test if the specified {@code encoding} names an encoding which may be streamed. - * @param encoding encoding name - * @return {@code true} if {@code encoding} matches a known streaming encoding. - */ - public static boolean isStreamingEncoding(CharSequence encoding) { - return SNAPPY_FRAMED.contentEquals(encoding) || GZIP.contentEquals(encoding) || DEFLATE.contentEquals(encoding) - || HttpHeaderValues.IDENTITY.contentEquals(encoding); - } - - /** - * Test if the supplied {@code Accepts-Encoding} string matches any specific - * supported encoding. - * @param encoding Encoding string as used in HTTP {@code Accepts-Encoding} header. - * @return {@code true} if {@code encoding} matches a supported encoding. - */ - public static boolean isSupportedEncoding(CharSequence encoding) { - if (encoding != null) { - String accepts = null; - Matcher matcher = ENCODING_REGEXP.matcher(encoding); - boolean match; - boolean acceptable = false; - - while ((match = matcher.find()) || accepts != null) { // SUPPRESS CHECKSTYLE InnerAssignment - if (!match || matcher.group(1) != null) { - if (acceptable) { - return true; - } - accepts = null; - if (match) { - accepts = matcher.group(1).trim(); - acceptable = isSupportedSpecificEncoding(accepts); - } - } else if (acceptable && "q".equals(matcher.group(2))) { - try { - acceptable = Float.parseFloat(matcher.group(3).trim()) >= ACCEPTS_THRESHOLD; - } catch (Throwable ex) { - acceptable = false; - } - } - } - } - return false; - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/compression/ContentDecompressor.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/compression/ContentDecompressor.java deleted file mode 100644 index 121a72a4679..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/compression/ContentDecompressor.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.linkedin.alpini.netty4.compression; - -import io.netty.channel.embedded.EmbeddedChannel; -import io.netty.handler.codec.http.HttpContentDecompressor; - - -/** - * @author Antony T Curtis {@literal } - */ -public class ContentDecompressor extends HttpContentDecompressor { - @Override - protected EmbeddedChannel newContentDecoder(String contentEncoding) throws Exception { - if (CompressionUtils.SNAPPY_ENCODING.equalsIgnoreCase(contentEncoding) - || CompressionUtils.X_SNAPPY.contentEqualsIgnoreCase(contentEncoding)) { - return new EmbeddedChannel( - ctx.channel().id(), - ctx.channel().metadata().hasDisconnect(), - ctx.channel().config(), - CompressionUtils.newSnappyDecoder()); - } - - if (CompressionUtils.SNAPPY_FRAMED_ENCODING.equalsIgnoreCase(contentEncoding)) { - return new EmbeddedChannel( - ctx.channel().id(), - ctx.channel().metadata().hasDisconnect(), - ctx.channel().config(), - CompressionUtils.newSnappyFramedDecoder()); - } - - return super.newContentDecoder(contentEncoding); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/compression/SnappyDecoder.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/compression/SnappyDecoder.java deleted file mode 100644 index 3fd821a6e95..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/compression/SnappyDecoder.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.linkedin.alpini.netty4.compression; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.CompositeByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.ByteToMessageDecoder; -import io.netty.handler.codec.compression.Snappy; -import java.util.List; - - -/** - * @author Antony T Curtis {@literal } - */ -public class SnappyDecoder extends ByteToMessageDecoder { - private final Snappy _snappy = new Snappy(); - private CompositeByteBuf _buffer; - - @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { - if (_buffer == null) { - _buffer = ctx.alloc().compositeBuffer(); - } - - _buffer.addComponents(true, in.readRetainedSlice(in.readableBytes())); - - // does nothing. Allow it to accumulate the whole message - out.add(Unpooled.EMPTY_BUFFER); - } - - @Override - protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in, List out) { - ByteBuf input; - - if (_buffer == null) { - input = in.readRetainedSlice(in.readableBytes()); - } else { - _buffer.addComponents(true, in.readRetainedSlice(in.readableBytes())); - input = _buffer; - _buffer = null; - } - - CompositeByteBuf buffer = ctx.alloc().compositeHeapBuffer(); - try { - if (input.isReadable()) { - _snappy.decode(input, buffer); - out.add(buffer.retain()); - } - } finally { - _snappy.reset(); - buffer.release(); - input.release(); - } - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/compression/SnappyEncoder.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/compression/SnappyEncoder.java deleted file mode 100644 index a1a4fb4f04d..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/compression/SnappyEncoder.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.linkedin.alpini.netty4.compression; - -import com.linkedin.alpini.netty4.handlers.ReverseHandler; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.CompositeByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.ByteToMessageDecoder; -import io.netty.handler.codec.compression.Snappy; -import java.util.List; - - -/** - * @author Antony T Curtis {@literal } - */ -public class SnappyEncoder extends ReverseHandler { - public SnappyEncoder() { - this(new Snappy()); - } - - private SnappyEncoder(Snappy snappy) { - super(new ByteToMessageDecoder() { - private CompositeByteBuf _buffer; - - @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { - if (_buffer == null) { - _buffer = ctx.alloc().compositeBuffer(); - } - - _buffer.addComponents(true, in.readRetainedSlice(in.readableBytes())); - - // Does nothing to accumulate - out.add(Unpooled.EMPTY_BUFFER); - } - - @Override - protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in, List out) { - ByteBuf input; - if (_buffer == null) { - input = in.readRetainedSlice(in.readableBytes()); - } else { - _buffer.addComponents(true, in.readRetainedSlice(in.readableBytes())); - input = _buffer; - _buffer = null; - } - - CompositeByteBuf buffer = ctx.alloc().compositeBuffer(); - try { - if (input.isReadable()) { - snappy.encode(input, buffer, input.readableBytes()); - out.add(buffer.retain()); - } - } finally { - snappy.reset(); - buffer.release(); - input.release(); - } - } - }); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/ElideDuplicateHeadersHandler.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/ElideDuplicateHeadersHandler.java deleted file mode 100644 index 633a14f863c..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/ElideDuplicateHeadersHandler.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import com.linkedin.alpini.base.misc.Time; -import io.netty.channel.ChannelDuplexHandler; -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelPromise; -import io.netty.handler.codec.http.HttpHeaders; -import io.netty.handler.codec.http.HttpMessage; -import io.netty.util.AsciiString; -import java.util.AbstractMap; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Deque; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** - * A simple cache to reduce the number of duplicate {@linkplain CharSequence}s held by the {@linkplain HttpHeaders} - * instances. The reason is that the HttpObjectDecoder will instantiate a new String for every part of the header - * that it encountered we want to facilitate the garbage collector in reaping short life objects. - * - * The implementation uses a queue of maps per thread instead of maintaining a LRU structure where initially two - * maps are added to the queue and at each expire interval, a new empty map is added at the start and an old map is - * removed from the end. This effectively makes the lifetime of every map to be 2x the expire interval and entries - * referenced would be inserted into only the map at the head of the queue. - */ -@ChannelHandler.Sharable -public class ElideDuplicateHeadersHandler extends ChannelDuplexHandler { - private static final Logger LOG = LogManager.getLogger(ElideDuplicateHeadersHandler.class); - - public static final ChannelDuplexHandler INSTANCE = new ElideDuplicateHeadersHandler(); - - private static final int EXPIRE_MILLISECONDS = 1000; // A + B Map == 2 seconds retention - - private static final ThreadLocal LOCAL = ThreadLocal.withInitial(Cache::new); - - private static class Cache { - private final Deque> _cache = new ArrayDeque<>(2); - private long _expirationTime; - - Cache() { - _cache.add(new HashMap<>()); - _cache.add(new HashMap<>()); - } - - AsciiString dedup(AsciiString source) { - return _cache.peekFirst().computeIfAbsent(source, s -> _cache.peekLast().getOrDefault(s, s)); - } - - void expire() { - long now = Time.nanoTime(); - if (now > _expirationTime) { - _cache.addFirst(new HashMap<>()); - int removedSize = _cache.removeLast().size(); - LOG.debug("removing old map (size={})", removedSize); - _expirationTime = now + TimeUnit.MILLISECONDS.toNanos(EXPIRE_MILLISECONDS); - } - } - - void elideDuplicate(HttpHeaders headers) { - List> entries = new ArrayList<>(headers.size()); - for (Iterator> it = headers.iteratorCharSequence(); it.hasNext();) { - Map.Entry entry = it.next(); - entries.add( - new AbstractMap.SimpleImmutableEntry<>( - dedup(AsciiString.of(entry.getKey())), - dedup(AsciiString.of(entry.getValue())))); - } - headers.clear(); - entries.forEach(entry -> headers.add(entry.getKey(), entry.getValue())); - } - } - - private ElideDuplicateHeadersHandler() { - } - - @Override - public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { - if (msg instanceof HttpMessage) { - Cache cache = LOCAL.get(); - cache.elideDuplicate(((HttpMessage) msg).headers()); - cache.expire(); - } - super.write(ctx, msg, promise); - } - - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - if (msg instanceof HttpMessage) { - Cache cache = LOCAL.get(); - cache.elideDuplicate(((HttpMessage) msg).headers()); - cache.expire(); - } - super.channelRead(ctx, msg); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/HeaderStamp.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/HeaderStamp.java deleted file mode 100644 index b7f72430883..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/HeaderStamp.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelOutboundHandlerAdapter; -import io.netty.channel.ChannelPromise; -import io.netty.handler.codec.http.HttpResponse; -import java.util.Objects; -import javax.annotation.Nonnull; - - -/** - * @author Antony T Curtis {@literal } - */ -@ChannelHandler.Sharable -public class HeaderStamp extends ChannelOutboundHandlerAdapter { - private final String _key; - private final String _value; - - public HeaderStamp(@Nonnull String headerName, @Nonnull String headerValue) { - _key = Objects.requireNonNull(headerName, "headerName"); - _value = Objects.requireNonNull(headerValue, "headerValue"); - } - - /** - * Calls {@link ChannelHandlerContext#write(Object, ChannelPromise)} to forward - * to the next {@link io.netty.channel.ChannelOutboundHandler} in the {@link io.netty.channel.ChannelPipeline}. - *

- * Sub-classes may override this method to change behavior. - */ - @Override - public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { - if (msg instanceof HttpResponse) { - HttpResponse response = (HttpResponse) msg; - response.headers().add(_key, _value); - } - - super.write(ctx, msg, promise); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/Http2PingResponseHandler.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/Http2PingResponseHandler.java deleted file mode 100644 index 0c1c11eaba1..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/Http2PingResponseHandler.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.SimpleChannelInboundHandler; -import io.netty.handler.codec.http2.DefaultHttp2PingFrame; -import io.netty.handler.codec.http2.Http2PingFrame; -import io.netty.util.concurrent.EventExecutor; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/* - * This handler is designed respond to Http2 ping frame. Before sending the ack, - * each I/O worker is required to run a simple task (i.e, ()-> null) to check whether it is blocked. - * - * @author Binbing Hou - * */ -@ChannelHandler.Sharable -public class Http2PingResponseHandler extends SimpleChannelInboundHandler { - private final static Logger LOG = LogManager.getLogger(Http2PingResponseHandler.class); - - private Http2PingFrame _lastPingAckFrame; - - @Override - protected void channelRead0(ChannelHandlerContext ctx, Http2PingFrame http2PingFrame) throws Exception { - - Http2PingFrame pingAckFrame = new DefaultHttp2PingFrame(http2PingFrame.content(), true); - _lastPingAckFrame = pingAckFrame; - - List> futures = new ArrayList<>(); - addPingTasks(futures, ctx); - - CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])) - .thenRun(() -> ctx.writeAndFlush(pingAckFrame).addListener(writeFuture -> { - if (!writeFuture.isSuccess()) { - LOG.warn( - "Failed to send the PING ACK frame={} to Channel={}", - pingAckFrame, - ctx.channel(), - writeFuture.cause()); - } else { - LOG.debug("Succeeded to send the PING ACK frame={} to Channel={}", pingAckFrame, ctx.channel()); - } - })); - } - - public CompletableFuture doSimpleTask(EventExecutor worker) { - return CompletableFuture.supplyAsync(this::simpleTask, worker); - } - - protected Object simpleTask() { - LOG.debug("simple task"); - return null; - } - - protected void addPingTasks(List> taskList, ChannelHandlerContext ctx) { - ctx.channel().eventLoop().parent().forEach(worker -> taskList.add(doSimpleTask(worker))); - } - - /*package-private for test only*/ Http2PingFrame getLastPingAckFrame() { - return _lastPingAckFrame; - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/Http2PingSendHandler.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/Http2PingSendHandler.java deleted file mode 100644 index 178ca690c4e..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/Http2PingSendHandler.java +++ /dev/null @@ -1,117 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import com.linkedin.alpini.base.misc.Time; -import com.linkedin.alpini.netty4.pool.Http2PingCallListener; -import com.linkedin.alpini.netty4.pool.Http2PingHelper; -import io.netty.channel.Channel; -import io.netty.channel.ChannelDuplexHandler; -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelPromise; -import io.netty.handler.codec.http2.Http2PingFrame; -import javax.annotation.Nonnull; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/* -* This handler is designed to handle the http2 ping and update the ping call listener. -* It is sharable since there is only one connection handling http2 ping for each host every ping interval. -* -* @author Binbing Hou -* */ -@ChannelHandler.Sharable -public class Http2PingSendHandler extends ChannelDuplexHandler { - private final static Logger LOG = LogManager.getLogger(Http2PingSendHandler.class); - - private long _lastPingSendTime; - private long _lastPingAckTime; - private long _lastPingId; - private Channel _lastPingChannel; - - private final Http2PingCallListener _http2PingCallListener; - - public Http2PingSendHandler(@Nonnull Http2PingCallListener http2PingCallListener) { - _http2PingCallListener = http2PingCallListener; - } - - @Override - public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { - if (msg instanceof Http2PingFrame) { - long currentTimeNanos = getCurrentTimeNanos(); - Http2PingFrame http2PingFrame = (Http2PingFrame) msg; - - // When writing the ping frame, we check whether the ack of the previous ping is received. - // If not, we consider this as a timeout and take the elapsed time as the ping response time. - // The ack of the previous ping (identified as ping id) will be ignored even if being received later. - if (!_http2PingCallListener.isCallComplete(_lastPingId)) { - _http2PingCallListener.callCloseWithError(_lastPingId, currentTimeNanos); - - LOG.warn( - "Failed to receive PING ACK from last ping send channel={} with elapsed time={} millisecond(s) " - + "ping send handler={} since the last ping, of which sent nano timestamp={}, id={}", - _lastPingChannel, - Http2PingHelper.nanoToMillis(currentTimeNanos - _lastPingSendTime), - this, - _lastPingSendTime, - _lastPingId); - } - - _lastPingId = http2PingFrame.content(); - _lastPingSendTime = currentTimeNanos; - _lastPingAckTime = 0; - _lastPingChannel = ctx.channel(); - - _http2PingCallListener.callStart(_lastPingId, currentTimeNanos); - - LOG.debug( - "Sent PING frame={} to Channel={}, current nano timestamp={}", - http2PingFrame, - ctx.channel(), - _lastPingSendTime); - } - - super.write(ctx, msg, promise); - } - - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - if (msg instanceof Http2PingFrame) { - Http2PingFrame http2PingFrame = (Http2PingFrame) msg; - if (http2PingFrame.ack() && http2PingFrame.content() == _lastPingId) { - long currentTimeNanos = getCurrentTimeNanos(); - _http2PingCallListener.callClose(http2PingFrame.content(), currentTimeNanos); - _lastPingAckTime = currentTimeNanos; - - LOG.debug( - "Received PING ACK frame={} from Channel={}, response time={} nanosecond(s), current nano timestamp={}", - http2PingFrame, - ctx.channel(), - currentTimeNanos - _lastPingSendTime, - currentTimeNanos); - } - } else { - super.channelRead(ctx, msg); - } - } - - public long getCurrentTimeNanos() { - return Time.nanoTime(); - } - - /*package-private for test only*/ long getLastPingSendTime() { - return _lastPingSendTime; - } - - /*package-private for test only*/ long getLastPingAckTime() { - return _lastPingAckTime; - } - - /*package-private for test only*/ long getLastPingId() { - return _lastPingId; - } - - /*package-private for test only*/ Channel getLastPingChannel() { - return _lastPingChannel; - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/HttpContentMultiPartAggregator.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/HttpContentMultiPartAggregator.java deleted file mode 100644 index 993a5d95972..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/HttpContentMultiPartAggregator.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import com.linkedin.alpini.netty4.misc.HttpMultiPart; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.MessageToMessageDecoder; -import io.netty.handler.codec.http.HttpObject; -import io.netty.handler.codec.http.LastHttpContent; -import io.netty.util.ReferenceCountUtil; -import java.util.List; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** - * Aggregates the result of {@link HttpContentMultiPartDecode} into {@link com.linkedin.alpini.netty4.misc.FullHttpMultiPart} - * - * This uses {@link HttpMultiPartContentAggregator} to aggregate the {@linkplain com.linkedin.alpini.netty4.misc.FullHttpMultiPart} - * messages and bypasses the aggregator when not aggregating multipart messages. - * - * @author Antony T Curtis {@literal } - */ - -public class HttpContentMultiPartAggregator extends MessageToMessageDecoder { - private static final Logger LOG = LogManager.getLogger(HttpContentMultiPartAggregator.class); - - private final Aggregator _aggregator; - - private int _inMultiPart; - - public HttpContentMultiPartAggregator(int maxContentLength) { - _aggregator = new Aggregator(maxContentLength); - } - - @Override - protected void decode(ChannelHandlerContext ctx, HttpObject msg, List out) throws Exception { - if (msg instanceof HttpMultiPart) { - _inMultiPart++; - LOG.log(_inMultiPart > 1 ? Level.ERROR : Level.DEBUG, "inMultiPart {} {}", _inMultiPart, msg); - } - if (_inMultiPart > 0) { - if (msg instanceof LastHttpContent) { - try { - LOG.debug("lastMultiPart {} {}", _inMultiPart, msg); - if (_aggregator.acceptInboundMessage(msg)) { - _aggregator.decode(ctx, msg, out); - return; - } - } finally { - _inMultiPart--; - } - } else { - LOG.debug("decode {} {}", _inMultiPart, msg); - if (_aggregator.acceptInboundMessage(msg)) { - _aggregator.decode(ctx, msg, out); - return; - } - } - } - out.add(ReferenceCountUtil.retain(msg)); - } - - private static class Aggregator extends HttpMultiPartContentAggregator { - Aggregator(int maxContentLength) { - super(maxContentLength); - } - - @Override - protected void decode(ChannelHandlerContext ctx, HttpObject msg, List out) throws Exception { - super.decode(ctx, msg, out); - } - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/HttpContentMultiPartDecode.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/HttpContentMultiPartDecode.java deleted file mode 100644 index ec4d00f1828..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/HttpContentMultiPartDecode.java +++ /dev/null @@ -1,302 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import com.linkedin.alpini.netty4.misc.BasicHttpMultiPart; -import com.linkedin.alpini.netty4.misc.BasicHttpObjectDecoder; -import com.linkedin.alpini.netty4.misc.NettyUtils; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufUtil; -import io.netty.buffer.Unpooled; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.http.DefaultHttpHeaders; -import io.netty.handler.codec.http.HttpConstants; -import io.netty.handler.codec.http.HttpMessage; -import io.netty.handler.codec.http.HttpResponse; -import io.netty.handler.codec.http.HttpResponseStatus; -import io.netty.handler.codec.http.HttpVersion; -import io.netty.util.AsciiString; -import io.netty.util.ByteProcessor; -import java.nio.charset.StandardCharsets; -import java.util.List; -import javax.annotation.Nonnull; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** - * Decodes {@linkplain ByteBuf} objects as {@link com.linkedin.alpini.netty4.misc.HttpMultiPart} headers and - * content. - * - * @author Antony T Curtis {@literal } - */ -public class HttpContentMultiPartDecode extends BasicHttpObjectDecoder { - private static final Logger LOG = LogManager.getLogger(HttpContentMultiPartDecode.class); - private static final ByteBuf DUMMY_HEADER = Unpooled.copiedBuffer("1 2 3\r\n", StandardCharsets.US_ASCII); - private static final ByteProcessor FIND_NON_CONTROL_CHARS = value -> (0xff & (int) value) < 32; - - private static final byte CR = HttpConstants.CR; - private static final byte LF = HttpConstants.LF; - - private final HttpContentUnwrap _unwrap; - private final int _maxChunkSize; - private int _lastReadable; - private boolean _inPart; - private int _innerDecodeLast; - private int _decodeLast; - - public HttpContentMultiPartDecode( - @Nonnull HttpContentUnwrap unwrap, - int maxHeaderSize, - int maxChunkSize, - boolean validateHeaders, - int initialBufferSize) { - super( - 10, - checkSize(maxHeaderSize, "maxHeaderSize"), - checkSize(maxChunkSize, "maxChunkSize"), - false, - validateHeaders, - initialBufferSize); - _unwrap = unwrap; - _maxChunkSize = maxChunkSize; - } - - private static int checkSize(int size, String message) { - if (size < 512) { - throw new IllegalArgumentException("expect " + message + " >= 512"); - } - return size; - } - - private void sanityCheckBeforeDecode(ByteBuf in, int size) { - String message; - State currentState = getDecoderState(); - if (State.SKIP_CONTROL_CHARS == currentState) { - if (in.forEachByte(in.readerIndex(), size, FIND_NON_CONTROL_CHARS) < 0) { - return; - } - message = "Missing content boundary, expect control chars: "; - } else if (State.READ_INITIAL == currentState) { - message = "Missing content boundary: "; - } else { - return; - } - throw new IllegalStateException(message + ByteBufUtil.prettyHexDump(in.slice(in.readerIndex(), size))); - } - - private void decodeSlice(ChannelHandlerContext ctx, ByteBuf in, int size, List out) throws Exception { - in.markReaderIndex(); - - // Sanity check the state of the decoder - sanityCheckBeforeDecode(in, size); - - ByteBuf slice = NettyUtils.read(in, size); - try { - super.decode(ctx, slice, out); - } finally { - if (slice.isReadable()) { - in.resetReaderIndex().skipBytes(size - slice.readableBytes()); - } - slice.release(); - } - } - - private void passThroughChunks(ChannelHandlerContext ctx, ByteBuf in, int endPos, List out) throws Exception { - while (endPos - in.readerIndex() > _maxChunkSize) { - if (_inPart) { - decodeSlice(ctx, in, _maxChunkSize, out); - } else { - in.skipBytes(_maxChunkSize); - } - } - } - - private boolean passThroughRemaining(ChannelHandlerContext ctx, ByteBuf in, int boundaryPos, List out) - throws Exception { - if (_inPart) { - while (State.READ_HEADER == getDecoderState() && in.readerIndex() < boundaryPos) { - decodeSlice(ctx, in, boundaryPos - in.readerIndex(), out); - } - - if (State.SKIP_CONTROL_CHARS != getDecoderState()) { - while (in.readerIndex() < boundaryPos) { - decodeSlice(ctx, in, boundaryPos - in.readerIndex(), out); - } - if (State.READ_FIXED_LENGTH_CONTENT == getDecoderState()) { - return true; - } - last(ctx, Unpooled.EMPTY_BUFFER, out); - } - } else { - in.readerIndex(boundaryPos); - } - return false; - } - - private static boolean isCRLF(ByteBuf in, int index) { - return in.getByte(index) == CR && in.getByte(index + 1) == LF; - } - - @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { - if (_innerDecodeLast > 0) { - super.decode(ctx, in, out); - _lastReadable = 0; - } else if (_unwrap._contentType != null && _unwrap._contentType.isMultipart()) { - AsciiString boundary = _unwrap._boundary; - final int startIndex = in.readerIndex(); - int pos = startIndex + Math.max(0, _lastReadable - boundary.length() - 4); - ByteBuf boundaryByteBuf = Unpooled.wrappedBuffer(boundary.array(), boundary.arrayOffset(), boundary.length()); - - while (pos < in.writerIndex()) { - - // If the multipart contained a content length, we should just consume it all without - // looking for part boundaries. - if (State.READ_FIXED_LENGTH_CONTENT == getDecoderState()) { - super.decode(ctx, in, out); - pos = in.readerIndex(); - continue; - } - - int boundaryPos = ByteBufUtil.indexOf(in, pos, in.writerIndex(), (byte) '-'); - - if (boundaryPos < 0) { - passThroughChunks(ctx, in, in.writerIndex() - 2, out); - break; - } - - passThroughChunks(ctx, in, boundaryPos - 2, out); - - if (boundaryPos + boundary.length() + 2 > in.writerIndex()) { - break; - } - - if (in.getByte(boundaryPos + 1) != '-') { - pos = boundaryPos + 1; - continue; - } - - if (startIndex != boundaryPos && (boundaryPos - 2 < startIndex || !isCRLF(in, boundaryPos - 2)) - || !ByteBufUtil.equals(in, boundaryPos + 2, boundaryByteBuf, 0, boundary.length())) { - pos = boundaryPos + 2; - continue; - } - - int boundaryEnd = boundaryPos + 2 + boundary.length(); - - if (boundaryEnd + 2 > in.writerIndex()) { - break; - } - - boolean startBoundary = isCRLF(in, boundaryEnd); - boolean maybeFinalBoundary = - !startBoundary && in.getByte(boundaryEnd) == '-' && in.getByte(boundaryEnd + 1) == '-'; - boolean truncatedFinalBoundary = maybeFinalBoundary && boundaryEnd + 4 > in.writerIndex(); - boolean finalBoundary = maybeFinalBoundary && !truncatedFinalBoundary && isCRLF(in, boundaryEnd + 2); - - if (truncatedFinalBoundary) { - break; - } - - if (startBoundary || finalBoundary) { - if (passThroughRemaining(ctx, in, boundaryPos, out)) { - // nope, it was bogus boundary inside the multipart content - pos = in.readerIndex(); - continue; - } - if (startBoundary) { - pos = in.readerIndex(boundaryEnd + 2).readerIndex(); - } else { - pos = in.readerIndex(boundaryEnd + 4).readerIndex(); - _inPart = false; - continue; - } - super.decode(ctx, DUMMY_HEADER.duplicate(), out); - assert State.READ_HEADER == getDecoderState() : "state: " + getDecoderState(); - _inPart = true; - continue; - } - - pos = boundaryEnd; - } - if (_decodeLast > 0 && in.isReadable()) { - if (passThroughRemaining(ctx, in, in.writerIndex(), out)) { - last(ctx, Unpooled.EMPTY_BUFFER, out); - } - _lastReadable = in.readableBytes(); - } else { - _lastReadable = in.writerIndex() - pos; - } - } else { - out.add(in.readRetainedSlice(in.readableBytes())); - _lastReadable = 0; - } - } - - @Override - protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { - boolean inPart = _inPart; - if (inPart) { - passThroughRemaining(ctx, in, in.writerIndex(), out); - _lastReadable = 0; - } - try { - _decodeLast++; - super.decodeLast(ctx, in, out); - } finally { - _decodeLast--; - internalBuffer().clear(); - } - } - - private void last(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { - try { - _innerDecodeLast++; - super.decodeLast(ctx, in, out); - } finally { - _innerDecodeLast--; - } - } - - @Override - protected boolean isDecodingRequest() { - return false; - } - - @Override - protected HttpMessage createMessage(String[] initialLine) { - return new Part(_unwrap._httpMessage, new DefaultHttpHeaders(validateHeaders)); - } - - @Override - protected HttpMessage createInvalidMessage() { - LOG.warn("Current state: {}", getDecoderState()); - throw new IllegalStateException(); - } - - private static class Part extends BasicHttpMultiPart implements HttpResponse { - Part(HttpMessage httpMessage, DefaultHttpHeaders entries) { - super(httpMessage, entries); - } - - @Override - public HttpResponseStatus getStatus() { - return status(); - } - - @Override - public HttpResponseStatus status() { - return HttpResponseStatus.OK; - } - - @Override - public Part setStatus(HttpResponseStatus status) { - return this; - } - - @Override - public Part setProtocolVersion(HttpVersion version) { - super.setProtocolVersion(version); - return this; - } - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/HttpContentUnwrap.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/HttpContentUnwrap.java deleted file mode 100644 index 8407908bcc4..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/HttpContentUnwrap.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import com.linkedin.alpini.base.misc.HeaderUtils; -import com.linkedin.alpini.netty4.misc.BasicHttpRequest; -import com.linkedin.alpini.netty4.misc.BasicHttpResponse; -import io.netty.buffer.Unpooled; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.MessageToMessageDecoder; -import io.netty.handler.codec.http.DefaultLastHttpContent; -import io.netty.handler.codec.http.HttpContent; -import io.netty.handler.codec.http.HttpHeaderNames; -import io.netty.handler.codec.http.HttpMessage; -import io.netty.handler.codec.http.HttpObject; -import io.netty.handler.codec.http.HttpRequest; -import io.netty.handler.codec.http.HttpResponse; -import io.netty.handler.codec.http.LastHttpContent; -import io.netty.util.AsciiString; -import io.netty.util.ReferenceCountUtil; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - - -/** - * Unwraps the content of messages which have multipart bodies as bare {@linkplain io.netty.buffer.ByteBuf} messages - * which can then be further processed by {@link HttpContentMultiPartDecode}. - * - * @author Antony T Curtis {@literal } - */ -public class HttpContentUnwrap extends MessageToMessageDecoder { - HttpMessage _httpMessage; - AsciiString _boundary; - HeaderUtils.ContentType _contentType; - private boolean _unwrap; - - @Override - public boolean acceptInboundMessage(Object msg) { - return msg instanceof HttpObject; - } - - public boolean acceptBoundary(String boundary) { - return !boundary.isEmpty(); - } - - @Override - protected void decode(ChannelHandlerContext ctx, HttpObject obj, List out) { - if (obj instanceof HttpMessage) { - _httpMessage = (HttpMessage) obj; - _contentType = - HeaderUtils.parseContentType(_httpMessage.headers().get(HttpHeaderNames.CONTENT_TYPE, "text/plain")); - _unwrap = false; - - if (_contentType.isMultipart()) { - Iterator> it = _contentType.parameters(); - while (it.hasNext()) { - Map.Entry entry = it.next(); - if ("boundary".equals(entry.getKey())) { - if (acceptBoundary(entry.getValue())) { - _unwrap = true; - _boundary = AsciiString.of(entry.getValue()); - break; - } - } - } - - if (_unwrap) { - if (obj instanceof HttpRequest) { - out.add(new BasicHttpRequest((HttpRequest) obj)); - if (obj instanceof LastHttpContent) { - obj = new DefaultLastHttpContent(((HttpContent) obj).content()); - } else { - return; - } - } else if (obj instanceof HttpResponse) { - out.add(new BasicHttpResponse((HttpResponse) obj)); - if (obj instanceof LastHttpContent) { - obj = new DefaultLastHttpContent(((HttpContent) obj).content()); - } else { - return; - } - } - } - } - } - - if (_unwrap && obj instanceof HttpContent) { - HttpContent msg = (HttpContent) obj; - - if (msg.content().isReadable()) { - out.add(msg.content().retainedDuplicate()); - } - - if (msg instanceof LastHttpContent) { - _unwrap = false; - if (((LastHttpContent) msg).trailingHeaders().isEmpty()) { - out.add(LastHttpContent.EMPTY_LAST_CONTENT); - } else { - out.add(msg.replace(Unpooled.EMPTY_BUFFER)); - } - } - } else { - out.add(ReferenceCountUtil.retain(obj)); - } - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/HttpMultiPartContentCodec.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/HttpMultiPartContentCodec.java deleted file mode 100644 index 89dcfa293a7..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/HttpMultiPartContentCodec.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import io.netty.channel.Channel; -import java.util.function.IntSupplier; -import javax.annotation.Nonnull; - - -/** - * Created by acurtis on 3/22/17. - */ -public class HttpMultiPartContentCodec extends SimpleChannelInitializer { - private final IntSupplier _maxChunkSize; - private final SimpleChannelInitializer _decoderInitializer; - - public HttpMultiPartContentCodec(int maxContentLength) { - this(Integer.valueOf(8192)::intValue, Integer.valueOf(8192)::intValue, Integer.valueOf(maxContentLength)::intValue); - } - - public HttpMultiPartContentCodec( - @Nonnull IntSupplier maxHeaderSize, - @Nonnull IntSupplier maxChunkSize, - @Nonnull IntSupplier maxContentLength) { - _maxChunkSize = maxChunkSize; - _decoderInitializer = new HttpMultiPartContentDecoder(maxHeaderSize, maxChunkSize, maxContentLength) { - @Override - protected boolean checkUnwrapBoundary(Channel ch, String boundary) { - return HttpMultiPartContentCodec.this.checkUnwrapBoundary(ch, boundary); - } - }; - } - - protected boolean checkUnwrapBoundary(Channel ch, String boundary) { - assert ch != null && boundary != null; - return true; - } - - @Override - protected void initChannel(Channel ch) throws Exception { - int chunkSize = _maxChunkSize.getAsInt(); - addAfter(ch, new HttpMultiPartContentEncoder(chunkSize, chunkSize), _decoderInitializer); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/HttpMultiPartContentDecoder.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/HttpMultiPartContentDecoder.java deleted file mode 100644 index 0076610724a..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/HttpMultiPartContentDecoder.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import io.netty.channel.Channel; -import java.util.function.IntSupplier; -import javax.annotation.Nonnull; - - -/** - * Decodes MIME multipart encoded content bodies by separating them into separate {@link io.netty.handler.codec.http.HttpMessage} objects. - * - * Created by acurtis on 3/22/17. - */ -public class HttpMultiPartContentDecoder extends SimpleChannelInitializer { - private final IntSupplier _maxHeaderSize; - private final IntSupplier _maxChunkSize; - private final IntSupplier _maxContentLength; - private final boolean _validateHeaders; - private final int _initialBufferSize; - - public HttpMultiPartContentDecoder(int maxHeaderSize, int maxChunkSize, int maxContentLength) { - this( - Integer.valueOf(maxHeaderSize)::intValue, - Integer.valueOf(maxChunkSize)::intValue, - Integer.valueOf(maxContentLength)::intValue); - } - - public HttpMultiPartContentDecoder( - @Nonnull IntSupplier maxHeaderSize, - @Nonnull IntSupplier maxChunkSize, - @Nonnull IntSupplier maxContentLength) { - this(maxHeaderSize, maxChunkSize, maxContentLength, false, 128); - } - - public HttpMultiPartContentDecoder( - @Nonnull IntSupplier maxHeaderSize, - @Nonnull IntSupplier maxChunkSize, - @Nonnull IntSupplier maxContentLength, - boolean validateHeaders, - int initialBufferSize) { - _maxHeaderSize = maxHeaderSize; - _maxChunkSize = maxChunkSize; - _maxContentLength = maxContentLength; - _validateHeaders = validateHeaders; - _initialBufferSize = initialBufferSize; - } - - protected boolean checkUnwrapBoundary(Channel ch, String boundary) { - assert ch != null && boundary != null; - return true; - } - - @Override - protected void initChannel(Channel ch) throws Exception { - HttpContentUnwrap unwrap = new HttpContentUnwrap() { - @Override - public boolean acceptBoundary(String boundary) { - return super.acceptBoundary(boundary) && checkUnwrapBoundary(ch, boundary); - } - }; - HttpContentMultiPartDecode decode = new HttpContentMultiPartDecode( - unwrap, - _maxHeaderSize.getAsInt(), - _maxChunkSize.getAsInt(), - _validateHeaders, - _initialBufferSize); - HttpContentMultiPartAggregator aggregator = new HttpContentMultiPartAggregator(_maxContentLength.getAsInt()); - - addAfter(ch, unwrap, decode, aggregator); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/HttpMultiPartContentEncoder.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/HttpMultiPartContentEncoder.java deleted file mode 100644 index be7346c7c57..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/HttpMultiPartContentEncoder.java +++ /dev/null @@ -1,254 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import com.linkedin.alpini.base.misc.HeaderUtils; -import com.linkedin.alpini.base.misc.ImmutableMapEntry; -import com.linkedin.alpini.netty4.misc.BasicFullHttpMultiPart; -import com.linkedin.alpini.netty4.misc.BasicHttpMultiPart; -import com.linkedin.alpini.netty4.misc.FullHttpMultiPart; -import com.linkedin.alpini.netty4.misc.HttpMultiPart; -import com.linkedin.alpini.netty4.misc.NettyUtils; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; -import io.netty.buffer.ByteBufUtil; -import io.netty.buffer.CompositeByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelPromise; -import io.netty.handler.codec.http.DefaultHttpContent; -import io.netty.handler.codec.http.DefaultLastHttpContent; -import io.netty.handler.codec.http.FullHttpMessage; -import io.netty.handler.codec.http.HttpConstants; -import io.netty.handler.codec.http.HttpContent; -import io.netty.handler.codec.http.HttpHeaderNames; -import io.netty.handler.codec.http.HttpHeaders; -import io.netty.handler.codec.http.HttpMessage; -import io.netty.handler.codec.http.HttpObjectEncoder; -import io.netty.handler.codec.http.HttpRequest; -import io.netty.handler.codec.http.HttpResponse; -import io.netty.handler.codec.http.LastHttpContent; -import io.netty.util.AsciiString; -import io.netty.util.AttributeMap; -import java.util.List; -import java.util.Map; -import java.util.Spliterator; -import java.util.Spliterators; -import java.util.UUID; -import java.util.concurrent.ThreadLocalRandom; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; - - -/** - * Encodes a stream of {@link HttpMultiPart} objects into a MIME encoded document. - * - * Created by acurtis on 3/22/17. - */ -public class HttpMultiPartContentEncoder extends HttpObjectEncoder { - private HeaderUtils.ContentType _contentType; - private boolean _encodingMultiPart; - private boolean _hasEmittedMultiPart; - private boolean _previousPartComplete; - private ByteBuf _boundary; - private final int _chunkSize; - private final int _maxChunkSize; - - private static final ByteBuf BOUNDARY_PREFIX = Unpooled.unreleasableBuffer( - Unpooled.wrappedBuffer(new byte[] { HttpConstants.CR, HttpConstants.LF, '-', '-' }).asReadOnly()); - private static final ByteBuf BOUNDARY_SUFFIX = Unpooled - .unreleasableBuffer(Unpooled.wrappedBuffer(new byte[] { HttpConstants.CR, HttpConstants.LF }).asReadOnly()); - private static final ByteBuf TERMINAL_SUFFIX = Unpooled.unreleasableBuffer( - Unpooled.wrappedBuffer(new byte[] { '-', '-', HttpConstants.CR, HttpConstants.LF }).asReadOnly()); - - public HttpMultiPartContentEncoder() { - this(3072, 4096); - } - - public HttpMultiPartContentEncoder(int chunkSize, int maxChunkSize) { - assert !isSharable() : "Not sharable"; - _chunkSize = chunkSize; - _maxChunkSize = maxChunkSize; - } - - @Override - protected void encode(ChannelHandlerContext ctx, Object msg, List out) throws Exception { - if (msg instanceof HttpContent && !(msg instanceof FullHttpMessage)) { - HttpContent httpContent = (HttpContent) msg; - if (httpContent.content().readableBytes() > _maxChunkSize) { - if (httpContent instanceof FullHttpMultiPart) { - FullHttpMultiPart part = (FullHttpMultiPart) httpContent; - super.encode(ctx, new BasicHttpMultiPart(part, part.headers()), out); - httpContent = new DefaultLastHttpContent(httpContent.content()); - } - ByteBuf bytes = httpContent.content().duplicate(); - do { - HttpContent chunk = new DefaultHttpContent(NettyUtils.read(bytes, _chunkSize)); - try { - super.encode(ctx, chunk, out); - } finally { - chunk.release(); - } - } while (bytes.readableBytes() > _chunkSize); - httpContent = httpContent.replace(NettyUtils.read(bytes, bytes.readableBytes())); - try { - super.encode(ctx, httpContent, out); - return; - } finally { - httpContent.release(); - } - } - } - super.encode(ctx, msg, out); - } - - @Override - public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { - if ((msg instanceof HttpRequest || msg instanceof HttpResponse) && !(msg instanceof LastHttpContent)) { - HttpMessage message = (HttpMessage) msg; - _contentType = HeaderUtils.parseContentType(message.headers().get(HttpHeaderNames.CONTENT_TYPE, "text/plain")); - _encodingMultiPart = false; - _hasEmittedMultiPart = false; - - if (_contentType.isMultipart()) { - _boundary = StreamSupport - .stream(Spliterators.spliteratorUnknownSize(_contentType.parameters(), Spliterator.IMMUTABLE), false) - .filter(entry -> "boundary".equals(entry.getKey())) - .map(Map.Entry::getValue) - .findFirst() - .map(AsciiString::of) - .map(boundary -> ByteBufUtil.writeAscii(ctx.alloc(), boundary)) - .orElseGet(() -> generateBoundary(ctx.alloc(), message)) - .asReadOnly(); - } - ctx.write(message, promise); - } else if (msg instanceof HttpMultiPart) { - if (!_contentType.isMultipart()) { - throw new IllegalStateException("Cannot encode multipart objects for content-type: " + _contentType); - } - - if (_hasEmittedMultiPart && !_previousPartComplete) { - super.write(ctx, LastHttpContent.EMPTY_LAST_CONTENT, ctx.newPromise()); - } - _encodingMultiPart = true; - if (msg instanceof FullHttpMultiPart && !(msg instanceof LastHttpContent)) { - msg = new FullMultiPart( - (HttpMessage) msg, - ((FullHttpMultiPart) msg).content(), - ((FullHttpMultiPart) msg).headers()); - } - super.write(ctx, msg, promise); - _encodingMultiPart = !(msg instanceof HttpContent); - _previousPartComplete = msg instanceof LastHttpContent; - _hasEmittedMultiPart = true; - } else if (_encodingMultiPart && msg instanceof LastHttpContent) { - _encodingMultiPart = false; - super.write(ctx, msg, promise); - } else if (_hasEmittedMultiPart && msg instanceof LastHttpContent) { - _hasEmittedMultiPart = false; - CompositeByteBuf buf = ctx.alloc().compositeBuffer(); - buf.addComponents( - true, - BOUNDARY_PREFIX.duplicate(), - _boundary.duplicate(), - TERMINAL_SUFFIX.duplicate(), - ((LastHttpContent) msg).content()); - ctx.write(((LastHttpContent) msg).replace(buf), promise); - _boundary = null; - } else if (_encodingMultiPart) { - super.write(ctx, msg, promise); - } else if (msg instanceof LastHttpContent) { - ctx.write(msg, promise); - if (_boundary != null) { - _boundary.release(); - _boundary = null; - } - } else { - ctx.write(msg, promise); - } - } - - /** - * The HttpObjectEncoder requires receiving LastHttpContent in order for its internal state be correct. - */ - private static final class FullMultiPart extends BasicFullHttpMultiPart implements LastHttpContent { - FullMultiPart(HttpMessage httpMessage, ByteBuf content, HttpHeaders headers) { - super(httpMessage, content, headers); - } - - private FullMultiPart(AttributeMap attributes, ByteBuf content, HttpHeaders headers) { - super(attributes, content, headers); - } - - @Override - public FullMultiPart retain() { - super.retain(); - return this; - } - - @Override - public FullMultiPart retain(int increment) { - super.retain(increment); - return this; - } - - @Override - public FullMultiPart touch() { - super.touch(); - return this; - } - - @Override - public FullMultiPart touch(Object hint) { - super.touch(hint); - return this; - } - - @Override - public FullMultiPart copy() { - return replace(content().copy()); - } - - @Override - public FullMultiPart duplicate() { - return replace(content().duplicate()); - } - - @Override - public FullMultiPart retainedDuplicate() { - return replace(content().retainedDuplicate()); - } - - @Override - public FullMultiPart replace(ByteBuf content) { - return new FullMultiPart((AttributeMap) this, content, headers()); - } - - @Override - public HttpHeaders trailingHeaders() { - return LastHttpContent.EMPTY_LAST_CONTENT.trailingHeaders(); - } - } - - private ByteBuf generateBoundary(ByteBufAllocator alloc, HttpMessage message) { - ThreadLocalRandom random = ThreadLocalRandom.current(); - // Not using securerandom because that drains the entropy pool - String boundary = "--=Part_" + new UUID(random.nextLong(), random.nextLong()).toString(); - String contentType = HeaderUtils.buildContentType( - _contentType.type(), - _contentType.subType(), - Stream.concat( - Stream.of(ImmutableMapEntry.make("boundary", boundary)), - StreamSupport - .stream(Spliterators.spliteratorUnknownSize(_contentType.parameters(), Spliterator.IMMUTABLE), false)) - .iterator()); - _contentType = HeaderUtils.parseContentType(contentType); - message.headers().set(HttpHeaderNames.CONTENT_TYPE, contentType); - return ByteBufUtil.writeAscii(alloc, boundary); - } - - @Override - protected void encodeInitialLine(ByteBuf buf, HttpMultiPart message) throws Exception { - buf.writeBytes(BOUNDARY_PREFIX, BOUNDARY_PREFIX.readerIndex(), BOUNDARY_PREFIX.readableBytes()); - buf.writeBytes(_boundary, _boundary.readerIndex(), _boundary.readableBytes()); - buf.writeBytes(BOUNDARY_SUFFIX, BOUNDARY_SUFFIX.readerIndex(), BOUNDARY_SUFFIX.readableBytes()); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/HttpServerConcurrencyObserver.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/HttpServerConcurrencyObserver.java deleted file mode 100644 index d7cee8559cb..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/HttpServerConcurrencyObserver.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import com.linkedin.alpini.base.monitoring.CallCompletion; -import com.linkedin.alpini.base.monitoring.CallTracker; -import io.netty.channel.ChannelDuplexHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelPromise; -import io.netty.handler.codec.http.HttpRequest; -import io.netty.handler.codec.http.HttpResponse; -import io.netty.handler.codec.http.HttpResponseStatus; -import io.netty.handler.codec.http.HttpStatusClass; -import io.netty.handler.codec.http.LastHttpContent; -import java.util.LinkedList; -import java.util.Objects; -import java.util.Queue; -import javax.annotation.Nonnull; - - -/** - * Created by acurtis on 12/6/17. - */ -public class HttpServerConcurrencyObserver extends ChannelDuplexHandler { - private final CallTracker _callTracker; - private final Queue _callCompletionQueue = new LinkedList<>(); - private HttpResponseStatus _httpResponseStatus; - - public HttpServerConcurrencyObserver(@Nonnull CallTracker callTracker) { - assert !isSharable(); - _callTracker = Objects.requireNonNull(callTracker); - } - - @Override - public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { - if (msg instanceof HttpResponse) { - if (((HttpResponse) msg).status().codeClass() != HttpStatusClass.INFORMATIONAL) { - _httpResponseStatus = ((HttpResponse) msg).status(); - } - } - if (msg instanceof LastHttpContent) { - HttpResponseStatus status = _httpResponseStatus; - CallCompletion callCompletion = _callCompletionQueue.remove(); - promise.addListener(future -> { - if (future.isSuccess() && status != null && status.codeClass() != HttpStatusClass.SERVER_ERROR) { - callCompletion.close(); - } else { - callCompletion.closeWithError(); - } - }); - _httpResponseStatus = null; - } - super.write(ctx, msg, promise); - } - - @Override - public void channelInactive(ChannelHandlerContext ctx) throws Exception { - _callCompletionQueue.forEach(CallCompletion::close); - super.channelInactive(ctx); - } - - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - if (msg instanceof HttpRequest) { - _callCompletionQueue.add(_callTracker.startCall()); - } - super.channelRead(ctx, msg); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/Log4J2FrameLogger.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/Log4J2FrameLogger.java deleted file mode 100644 index 3fa24f146d7..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/Log4J2FrameLogger.java +++ /dev/null @@ -1,235 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import com.linkedin.alpini.base.misc.Msg; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufUtil; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.http2.Http2Flags; -import io.netty.handler.codec.http2.Http2FrameLogger; -import io.netty.handler.codec.http2.Http2Headers; -import io.netty.handler.codec.http2.Http2Settings; -import io.netty.handler.logging.LogLevel; -import io.netty.util.internal.StringUtil; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** - * Created by acurtis on 4/19/18. - */ -public class Log4J2FrameLogger extends Http2FrameLogger { - private static final int BUFFER_LENGTH_THRESHOLD = 64; - private final Logger _logger; - private final Level _level; - - public Log4J2FrameLogger(Level level) { - this(level, Http2FrameLogger.class); - } - - public Log4J2FrameLogger(Level level, String name) { - this(level, LogManager.getLogger(name)); - } - - public Log4J2FrameLogger(Level level, Class clazz) { - this(level, LogManager.getLogger(clazz)); - } - - private Log4J2FrameLogger(Level level, Logger logger) { - super(LogLevel.ERROR); - _logger = setupLogger(logger); - _level = level; - } - - Logger setupLogger(Logger logger) { - return logger; - } - - public void logData( - Direction direction, - ChannelHandlerContext ctx, - int streamId, - ByteBuf data, - int padding, - boolean endStream) { - _logger.log( - _level, - "{} {} DATA: streamId={} padding={} endStream={} length={} bytes={}", - ctx.channel(), - direction.name(), - streamId, - padding, - endStream, - data.readableBytes(), - toMsg(data)); - } - - public void logHeaders( - Direction direction, - ChannelHandlerContext ctx, - int streamId, - Http2Headers headers, - int padding, - boolean endStream) { - _logger.log( - _level, - "{} {} HEADERS: streamId={} headers={} padding={} endStream={}", - ctx.channel(), - direction.name(), - streamId, - headers, - padding, - endStream); - } - - public void logHeaders( - Direction direction, - ChannelHandlerContext ctx, - int streamId, - Http2Headers headers, - int streamDependency, - short weight, - boolean exclusive, - int padding, - boolean endStream) { - _logger.log( - _level, - "{} {} HEADERS: streamId={} headers={} streamDependency={} weight={} exclusive={} " + "padding={} endStream={}", - ctx.channel(), - direction.name(), - streamId, - headers, - streamDependency, - weight, - exclusive, - padding, - endStream); - } - - public void logPriority( - Direction direction, - ChannelHandlerContext ctx, - int streamId, - int streamDependency, - short weight, - boolean exclusive) { - _logger.log( - _level, - "{} {} PRIORITY: streamId={} streamDependency={} weight={} exclusive={}", - ctx.channel(), - direction.name(), - streamId, - streamDependency, - weight, - exclusive); - } - - public void logRstStream(Direction direction, ChannelHandlerContext ctx, int streamId, long errorCode) { - _logger.log( - _level, - "{} {} RST_STREAM: streamId={} errorCode={}", - ctx.channel(), - direction.name(), - streamId, - errorCode); - } - - public void logSettingsAck(Direction direction, ChannelHandlerContext ctx) { - _logger.log(_level, "{} {} SETTINGS: ack=true", ctx.channel(), direction.name()); - } - - public void logSettings(Direction direction, ChannelHandlerContext ctx, Http2Settings settings) { - _logger.log(_level, "{} {} SETTINGS: ack=false settings={}", ctx.channel(), direction.name(), settings); - } - - public void logPing(Direction direction, ChannelHandlerContext ctx, long data) { - _logger.log(_level, "{} {} PING: ack=false bytes={}", ctx.channel(), direction.name(), data); - } - - public void logPingAck(Direction direction, ChannelHandlerContext ctx, long data) { - _logger.log(_level, "{} {} PING: ack=true bytes={}", ctx.channel(), direction.name(), data); - } - - public void logPushPromise( - Direction direction, - ChannelHandlerContext ctx, - int streamId, - int promisedStreamId, - Http2Headers headers, - int padding) { - _logger.log( - _level, - "{} {} PUSH_PROMISE: streamId={} promisedStreamId={} headers={} padding={}", - ctx.channel(), - direction.name(), - streamId, - promisedStreamId, - headers, - padding); - } - - public void logGoAway( - Direction direction, - ChannelHandlerContext ctx, - int lastStreamId, - long errorCode, - ByteBuf debugData) { - _logger.log( - _level, - "{} {} GO_AWAY: lastStreamId={} errorCode={} length={} bytes={}", - ctx.channel(), - direction.name(), - lastStreamId, - errorCode, - debugData.readableBytes(), - toMsg(debugData)); - } - - public void logWindowsUpdate(Direction direction, ChannelHandlerContext ctx, int streamId, int windowSizeIncrement) { - _logger.log( - _level, - "{} {} WINDOW_UPDATE: streamId={} windowSizeIncrement={}", - ctx.channel(), - direction.name(), - streamId, - windowSizeIncrement); - } - - public void logUnknownFrame( - Direction direction, - ChannelHandlerContext ctx, - byte frameType, - int streamId, - Http2Flags flags, - ByteBuf data) { - _logger.log( - _level, - "{} {} UNKNOWN: frameType={} streamId={} flags={} length={} bytes={}", - ctx.channel(), - direction.name(), - frameType & 0xFF, - streamId, - flags.value(), - data.readableBytes(), - toMsg(data)); - } - - private Object toMsg(ByteBuf buf) { - if (!_logger.isEnabled(_level)) { - return StringUtil.EMPTY_STRING; - } - - if (_level == Level.TRACE || buf.readableBytes() <= BUFFER_LENGTH_THRESHOLD) { - // Log the entire buffer. - return Msg.make(buf, ByteBufUtil::hexDump); - } - - // Otherwise just log the first 64 bytes. - return Msg.make(buf, Log4J2FrameLogger::hexDumpInitial); - } - - private static String hexDumpInitial(ByteBuf buf) { - int length = Math.min(buf.readableBytes(), BUFFER_LENGTH_THRESHOLD); - return ByteBufUtil.hexDump(buf, buf.readerIndex(), length) + "..."; - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/Log4J2LoggingHandler.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/Log4J2LoggingHandler.java deleted file mode 100644 index 1d8e04a8392..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/Log4J2LoggingHandler.java +++ /dev/null @@ -1,383 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import static io.netty.buffer.ByteBufUtil.appendPrettyHexDump; -import static io.netty.util.internal.StringUtil.NEWLINE; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufHolder; -import io.netty.buffer.Unpooled; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelPromise; -import io.netty.handler.logging.LogLevel; -import io.netty.handler.logging.LoggingHandler; -import io.netty.util.internal.logging.InternalLogLevel; -import java.net.SocketAddress; -import java.util.EnumMap; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.util.StringBuilderFormattable; - - -/** - * Created by acurtis on 4/20/18. - */ -public class Log4J2LoggingHandler extends LoggingHandler { - private static final EnumMap LEVEL_ENUM_MAP = new EnumMap<>(InternalLogLevel.class); - - static { - LEVEL_ENUM_MAP.put(InternalLogLevel.DEBUG, Level.DEBUG); - LEVEL_ENUM_MAP.put(InternalLogLevel.TRACE, Level.TRACE); - LEVEL_ENUM_MAP.put(InternalLogLevel.INFO, Level.INFO); - LEVEL_ENUM_MAP.put(InternalLogLevel.WARN, Level.WARN); - LEVEL_ENUM_MAP.put(InternalLogLevel.ERROR, Level.ERROR); - } - - private static final LogLevel DEFAULT_LEVEL = LogLevel.DEBUG; - - protected final Logger logger; - protected final Level internalLevel; - - /** - * Creates a new instance whose logger name is the fully qualified class - * name of the instance with hex dump enabled. - */ - public Log4J2LoggingHandler() { - this(DEFAULT_LEVEL); - } - - /** - * Creates a new instance whose logger name is the fully qualified class - * name of the instance. - * - * @param level the log level - */ - public Log4J2LoggingHandler(LogLevel level) { - super(level); - - logger = setupLogger(LogManager.getLogger(getClass())); - internalLevel = LEVEL_ENUM_MAP.get(level().toInternalLevel()); - } - - /** - * Creates a new instance with the specified logger name and with hex dump - * enabled. - * - * @param clazz the class type to generate the logger for - */ - public Log4J2LoggingHandler(Class clazz) { - this(clazz, DEFAULT_LEVEL); - } - - /** - * Creates a new instance with the specified logger name. - * - * @param clazz the class type to generate the logger for - * @param level the log level - */ - public Log4J2LoggingHandler(Class clazz, LogLevel level) { - super(clazz, level); - - logger = setupLogger(LogManager.getLogger(clazz)); - internalLevel = LEVEL_ENUM_MAP.get(level().toInternalLevel()); - } - - /** - * Creates a new instance with the specified logger name using the default log level. - * - * @param name the name of the class to use for the logger - */ - public Log4J2LoggingHandler(String name) { - this(name, DEFAULT_LEVEL); - } - - /** - * Creates a new instance with the specified logger name. - * - * @param name the name of the class to use for the logger - * @param level the log level - */ - public Log4J2LoggingHandler(String name, LogLevel level) { - super(name, level); - - logger = setupLogger(LogManager.getLogger(name)); - internalLevel = LEVEL_ENUM_MAP.get(level().toInternalLevel()); - } - - Logger setupLogger(Logger logger) { - return logger; - } - - @Override - public void channelRegistered(ChannelHandlerContext ctx) throws Exception { - if (logger.isEnabled(internalLevel)) { - logger.log(internalLevel, format0(ctx, "REGISTERED")); - } - ctx.fireChannelRegistered(); - } - - @Override - public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { - if (logger.isEnabled(internalLevel)) { - logger.log(internalLevel, format0(ctx, "UNREGISTERED")); - } - ctx.fireChannelUnregistered(); - } - - @Override - public void channelActive(ChannelHandlerContext ctx) throws Exception { - if (logger.isEnabled(internalLevel)) { - logger.log(internalLevel, format0(ctx, "ACTIVE")); - } - ctx.fireChannelActive(); - } - - @Override - public void channelInactive(ChannelHandlerContext ctx) throws Exception { - if (logger.isEnabled(internalLevel)) { - logger.log(internalLevel, format0(ctx, "INACTIVE")); - } - ctx.fireChannelInactive(); - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { - if (logger.isEnabled(internalLevel)) { - logger.log(internalLevel, format0(ctx, "EXCEPTION", cause), cause); - } - ctx.fireExceptionCaught(cause); - } - - @Override - public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { - if (logger.isEnabled(internalLevel)) { - logger.log(internalLevel, format0(ctx, "USER_EVENT", evt)); - } - ctx.fireUserEventTriggered(evt); - } - - @Override - public void bind(ChannelHandlerContext ctx, SocketAddress localAddress, ChannelPromise promise) throws Exception { - if (logger.isEnabled(internalLevel)) { - logger.log(internalLevel, format0(ctx, "BIND", localAddress)); - } - ctx.bind(localAddress, promise); - } - - @Override - public void connect( - ChannelHandlerContext ctx, - SocketAddress remoteAddress, - SocketAddress localAddress, - ChannelPromise promise) throws Exception { - if (logger.isEnabled(internalLevel)) { - logger.log(internalLevel, format0(ctx, "CONNECT", remoteAddress, localAddress)); - } - ctx.connect(remoteAddress, localAddress, promise); - } - - @Override - public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { - if (logger.isEnabled(internalLevel)) { - logger.log(internalLevel, format0(ctx, "DISCONNECT")); - } - ctx.disconnect(promise); - } - - @Override - public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { - if (logger.isEnabled(internalLevel)) { - logger.log(internalLevel, format0(ctx, "CLOSE")); - } - ctx.close(promise); - } - - @Override - public void deregister(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { - if (logger.isEnabled(internalLevel)) { - logger.log(internalLevel, format0(ctx, "DEREGISTER")); - } - ctx.deregister(promise); - } - - @Override - public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { - if (logger.isEnabled(internalLevel)) { - logger.log(internalLevel, format0(ctx, "READ COMPLETE")); - } - ctx.fireChannelReadComplete(); - } - - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - if (logger.isEnabled(internalLevel)) { - logger.log(internalLevel, format0(ctx, "READ", msg)); - } - ctx.fireChannelRead(msg); - } - - @Override - public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { - if (logger.isEnabled(internalLevel)) { - logger.log(internalLevel, format0(ctx, "WRITE", msg)); - } - ctx.write(msg, promise); - } - - @Override - public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception { - if (logger.isEnabled(internalLevel)) { - logger.log(internalLevel, format0(ctx, "WRITABILITY CHANGED")); - } - ctx.fireChannelWritabilityChanged(); - } - - @Override - public void flush(ChannelHandlerContext ctx) throws Exception { - if (logger.isEnabled(internalLevel)) { - logger.log(internalLevel, format0(ctx, "FLUSH")); - } - ctx.flush(); - } - - /** - * Formats an event and returns the formatted message. - * - * @param eventName the name of the event - */ - private static Object format0(ChannelHandlerContext ctx, String eventName) { - return new Formattable() { - @Override - public void formatTo(StringBuilder buffer) { - buffer.append(ctx.channel()).append(' ').append(eventName); - } - }; - } - - /** - * Formats an event and returns the formatted message. - * - * @param eventName the name of the event - * @param arg the argument of the event - */ - private static Object format0(ChannelHandlerContext ctx, String eventName, Object arg) { - if (arg instanceof ByteBuf) { - return formatByteBuf(ctx, eventName, (ByteBuf) arg); - } else if (arg instanceof ByteBufHolder) { - return formatByteBufHolder(ctx, eventName, (ByteBufHolder) arg); - } else { - return formatSimple(ctx, eventName, arg); - } - } - - /** - * Formats an event and returns the formatted message. This method is currently only used for formatting - * {@link io.netty.channel.ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}. - * - * @param eventName the name of the event - * @param firstArg the first argument of the event - * @param secondArg the second argument of the event - */ - private static Object format0(ChannelHandlerContext ctx, String eventName, Object firstArg, Object secondArg) { - if (secondArg == null) { - return formatSimple(ctx, eventName, firstArg); - } - return new Formattable() { - @Override - public void formatTo(StringBuilder buffer) { - buffer.append(ctx.channel()) - .append(' ') - .append(eventName) - .append(": ") - .append(firstArg) - .append(", ") - .append(secondArg); - } - }; - } - - /** - * Generates the default log message of the specified event whose argument is a {@link ByteBuf}. - */ - private static Object formatByteBuf(ChannelHandlerContext ctx, String eventName, ByteBuf msg) { - int length = msg.readableBytes(); - if (length == 0) { - return new Formattable() { - @Override - public void formatTo(StringBuilder buffer) { - buffer.append(ctx.channel()).append(' ').append(eventName).append(": 0B"); - } - }; - } else { - ByteBuf msgCopy = Unpooled.copiedBuffer(msg); - return new Formattable() { - @Override - public void formatTo(StringBuilder buffer) { - buffer.append(ctx.channel()) - .append(' ') - .append(eventName) - .append(": ") - .append(length) - .append('B') - .append(NEWLINE); - appendPrettyHexDump(buffer, msgCopy); - } - }; - } - } - - /** - * Generates the default log message of the specified event whose argument is a {@link ByteBufHolder}. - */ - private static Object formatByteBufHolder(ChannelHandlerContext ctx, String eventName, ByteBufHolder msg) { - ByteBuf content = msg.content(); - int length = content.readableBytes(); - if (length == 0) { - return new Formattable() { - @Override - public void formatTo(StringBuilder buffer) { - buffer.append(ctx.channel()).append(' ').append(eventName).append(", ").append(msg).append(", 0B"); - } - }; - } else { - assert content.refCnt() > 0; - ByteBuf contentCopy = Unpooled.copiedBuffer(content); - return new Formattable() { - @Override - public void formatTo(StringBuilder buffer) { - buffer.append(ctx.channel()) - .append(' ') - .append(eventName) - .append(": ") - .append(msg) - .append(", ") - .append(length) - .append('B') - .append(NEWLINE); - appendPrettyHexDump(buffer, contentCopy); - } - }; - } - } - - /** - * Generates the default log message of the specified event whose argument is an arbitrary object. - */ - private static Object formatSimple(ChannelHandlerContext ctx, String eventName, Object msg) { - return new Formattable() { - @Override - public void formatTo(StringBuilder buffer) { - buffer.append(ctx.channel()).append(' ').append(eventName).append(": ").append(msg); - } - }; - } - - private static abstract class Formattable implements StringBuilderFormattable { - @Override - public final String toString() { - StringBuilder buf = new StringBuilder(); - formatTo(buf); - return buf.toString(); - } - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/LogSslCipherSuiteHandler.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/LogSslCipherSuiteHandler.java deleted file mode 100644 index 52f0960d182..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/LogSslCipherSuiteHandler.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; -import io.netty.handler.ssl.SslHandler; -import io.netty.handler.ssl.SslHandshakeCompletionEvent; -import java.security.cert.Certificate; -import java.security.cert.X509Certificate; -import javax.net.ssl.SSLSession; -import javax.security.auth.x500.X500Principal; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -@ChannelHandler.Sharable -public class LogSslCipherSuiteHandler extends ChannelInboundHandlerAdapter { - private static final Logger LOG = LogManager.getLogger(LogSslCipherSuiteHandler.class); - - @Override - public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { - if (evt == SslHandshakeCompletionEvent.SUCCESS || evt.toString().equals("READY_EVENT")) { - SslHandler handler = ctx.pipeline().get(SslHandler.class); - SSLSession session = handler.engine().getSession(); - String remoteCN = null; - try { - for (Certificate cert: session.getPeerCertificates()) { - if (cert instanceof X509Certificate) { - X500Principal cn = ((X509Certificate) cert).getSubjectX500Principal(); - if (cn != null) { - remoteCN = cn.getName(); - break; - } - } - } - } catch (Throwable ex) { - LOG.warn("Unable to obtain remote CN for {}", ctx.channel().remoteAddress(), ex); - } - LOG.info( - "Cipher suite used is {}, remote address is {}, remote cn is {}", - session.getCipherSuite(), - ctx.channel().remoteAddress(), - remoteCN); - } - super.userEventTriggered(ctx, evt); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/OutboundByteBufAggregator.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/OutboundByteBufAggregator.java deleted file mode 100644 index 394e19efbbe..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/OutboundByteBufAggregator.java +++ /dev/null @@ -1,173 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; -import io.netty.buffer.CompositeByteBuf; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelOutboundHandlerAdapter; -import io.netty.channel.ChannelPromise; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Deque; -import java.util.List; - - -/** - * SSL uses 16kb application message packets. This handler aims to combine the ByteBuf into packet-sized chunks, - * This is due to limitations in the SSL implementation which prefers contiguous messages to process so we must - * break down composite ByteBuf objects. - * - * This Aggregator includes a constructor which accepts a allocator to avoid memory fragmentation. - * Since we always use 16KB buffers. - */ -public final class OutboundByteBufAggregator extends ChannelOutboundHandlerAdapter { - public static final int SSL_PACKET_SIZE = 16384; - - private final int _packetSize; - private final ByteBufAllocator _alloc; - private final Deque _byteBufs = new ArrayDeque<>(); - private final Deque _promises = new ArrayDeque<>(); - private int _accumulatedLength; - - public OutboundByteBufAggregator() { - this(SSL_PACKET_SIZE); - } - - public OutboundByteBufAggregator(int packetSize) { - this(packetSize, null); - } - - public OutboundByteBufAggregator(int packetSize, ByteBufAllocator alloc) { - _packetSize = packetSize; - _alloc = alloc; - } - - private ByteBufAllocator alloc(ChannelHandlerContext ctx) { - return _alloc == null ? ctx.alloc() : _alloc; - } - - @Override - public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { - if (msg instanceof ByteBuf) { - write0(ctx, (ByteBuf) msg, promise); - } else { - flush0(ctx, false); - ctx.write(msg, promise); - } - } - - private void write0(ChannelHandlerContext ctx, ByteBuf msg, ChannelPromise promise) throws Exception { - if (!_byteBufs.isEmpty() || msg instanceof CompositeByteBuf || msg.readableBytes() < _packetSize) { - _byteBufs.add(msg); - if (!promise.isVoid() || _promises.stream().noneMatch(ChannelPromise::isVoid)) { - _promises.add(promise); - } - _accumulatedLength += msg.readableBytes(); - } else { - ctx.write(msg, promise); - } - if (_accumulatedLength >= _packetSize) { - flush0(ctx, false); - } - } - - private void compose(ChannelHandlerContext ctx, ByteBuf buf, List out) { - if (out.isEmpty()) { - out.add(alloc(ctx).buffer(_packetSize)); - } - ByteBuf last = out.get(out.size() - 1); - if (last.isWritable(buf.readableBytes())) { - last.writeBytes(buf); - } else { - if (last.isWritable()) { - last.writeBytes(buf, last.writableBytes()); - } - if (buf.isReadable()) { - if (buf.readableBytes() >= _packetSize) { - out.add(buf.retainedDuplicate().asReadOnly()); - } else { - ByteBuf next = alloc(ctx).buffer(_packetSize); - out.add(next); - next.writeBytes(buf); - } - } - } - buf.release(); - } - - private boolean isComposite(ByteBuf buf) { - return buf != null && (buf instanceof CompositeByteBuf || isComposite(buf.unwrap())); - } - - private void flush0(ChannelHandlerContext ctx, boolean channelFlush) { - if (_byteBufs.isEmpty()) { - return; - } - - if (_byteBufs.size() == 1 && !isComposite(_byteBufs.getFirst())) { - _accumulatedLength = 0; - if (channelFlush) { - ctx.writeAndFlush(_byteBufs.remove(), _promises.remove()); - } else { - ctx.write(_byteBufs.remove(), _promises.remove()); - } - return; - } - - List buffers = new ArrayList<>(_byteBufs.size()); - - do { - compose(ctx, _byteBufs.remove(), buffers); - } while (!_byteBufs.isEmpty()); - - ChannelPromise[] promises = _promises.toArray(new ChannelPromise[0]); - _promises.clear(); - - ByteBuf out; - if (buffers.size() == 1) { - out = buffers.remove(0); - } else { - out = alloc(ctx).compositeBuffer(buffers.size()).addComponents(true, buffers); - } - - ChannelFuture writeFuture; - - if (channelFlush) { - if (promises.length == 1) { - ctx.writeAndFlush(out, promises[0]); - return; - } - - writeFuture = ctx.writeAndFlush(out); - } else { - if (promises.length == 1) { - ctx.write(out, promises[0]); - return; - } - - writeFuture = ctx.write(out); - } - - writeFuture.addListener(future -> { - if (future.isSuccess()) { - for (ChannelPromise promise: promises) { - promise.trySuccess(); - } - } else { - for (ChannelPromise promise: promises) { - promise.tryFailure(future.cause()); - } - } - }); - } - - @Override - public void flush(ChannelHandlerContext ctx) throws Exception { - if (_byteBufs.isEmpty()) { - super.flush(ctx); - } else { - flush0(ctx, true); - } - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/RateLimitConnectHandler.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/RateLimitConnectHandler.java deleted file mode 100644 index 98d25d75f77..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/RateLimitConnectHandler.java +++ /dev/null @@ -1,168 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import com.linkedin.alpini.base.misc.CollectionUtil; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelOutboundHandlerAdapter; -import io.netty.channel.ChannelPromise; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.util.NoSuchElementException; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ThreadLocalRandom; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.BiConsumer; -import java.util.function.LongSupplier; -import javax.annotation.Nonnull; - - -/** - * Created by acurtis on 3/19/18. - */ -@ChannelHandler.Sharable -public class RateLimitConnectHandler extends ChannelOutboundHandlerAdapter { - private final ScheduledExecutorService _scheduledExecutorService; - private final ConcurrentMap _futures = new ConcurrentHashMap<>(); - private final LongSupplier _betweenConnectDelayMillis; - private final LongSupplier _betweenFailureDelayMillis; - private final LongSupplier _maxConnectDelayMillis; - - public RateLimitConnectHandler( - @Nonnull ScheduledExecutorService scheduledExecutorService, - long betweenConnectDelayMillis, - long betweenFailureDelayMillis) { - this(scheduledExecutorService, constant(betweenConnectDelayMillis), constant(betweenFailureDelayMillis)); - } - - public RateLimitConnectHandler( - @Nonnull ScheduledExecutorService scheduledExecutorService, - @Nonnull LongSupplier betweenConnectDelayMillis, - @Nonnull LongSupplier betweenFailureDelayMillis) { - this(scheduledExecutorService, betweenConnectDelayMillis, betweenFailureDelayMillis, constant(5000)); - } - - public RateLimitConnectHandler( - @Nonnull ScheduledExecutorService scheduledExecutorService, - @Nonnull LongSupplier betweenConnectDelayMillis, - @Nonnull LongSupplier betweenFailureDelayMillis, - @Nonnull LongSupplier maxConnectDelayMillis) { - _scheduledExecutorService = scheduledExecutorService; - _betweenConnectDelayMillis = betweenConnectDelayMillis; - _betweenFailureDelayMillis = betweenFailureDelayMillis; - _maxConnectDelayMillis = maxConnectDelayMillis; - } - - private long getBetweenConnectDelayMillis() { - return Math.max(0L, _betweenConnectDelayMillis.getAsLong()); - } - - private long getBetweenFailureDelayMillis() { - return Math.max(0L, _betweenFailureDelayMillis.getAsLong()); - } - - private long getMaxConnectDelayMillis() { - return Math.max(0, _maxConnectDelayMillis.getAsLong()); - } - - private void scheduleNext(Entry ref, boolean success, Connect next) { - try { - long delay; - if (success) { - delay = getBetweenConnectDelayMillis(); - } else { - delay = ref._delay + getBetweenConnectDelayMillis() - + ThreadLocalRandom.current().nextLong(getBetweenFailureDelayMillis()); - } - ref._delay = Math.min(getMaxConnectDelayMillis(), delay); - } finally { - _scheduledExecutorService.schedule(next, Math.max(0, ref._delay), TimeUnit.MILLISECONDS); - } - } - - @Override - public void connect( - ChannelHandlerContext ctx, - SocketAddress remoteAddress, - SocketAddress localAddress, - ChannelPromise promise) throws Exception { - Entry ref = CollectionUtil.computeIfAbsent(_futures, ((InetSocketAddress) remoteAddress).getAddress(), Entry::new); - Connect future = new Connect(ref, ctx, remoteAddress, localAddress, promise); - CompletableFuture oldValue = ref.get(); - while (!ref.compareAndSet(oldValue, future)) { - oldValue = ref.get(); - } - oldValue.whenCompleteAsync(future, ctx.executor()); - } - - private class Connect extends CompletableFuture - implements Runnable, ChannelFutureListener, BiConsumer { - private final Entry _ref; - private final ChannelHandlerContext _ctx; - private final SocketAddress _remoteAddress; - private final SocketAddress _localAddress; - private final ChannelPromise _connectPromise; - - private Connect( - Entry ref, - ChannelHandlerContext ctx, - SocketAddress remoteAddress, - SocketAddress localAddress, - ChannelPromise connectPromise) { - _ref = ref; - _ctx = ctx; - _remoteAddress = remoteAddress; - _localAddress = localAddress; - _connectPromise = connectPromise; - } - - @Override - public void run() { - complete(null); - } - - @Override - public void operationComplete(ChannelFuture future) throws Exception { - try { - scheduleNext(_ref, future.isSuccess(), this); - } finally { - try { - _ctx.pipeline().remove(RateLimitConnectHandler.this); - } catch (NoSuchElementException ex) { - // ignore - } - } - } - - @Override - public void accept(Void aVoid, Throwable throwable) { - try { - _ctx.connect(_remoteAddress, _localAddress, _connectPromise); - _connectPromise.addListener(this); - } catch (Throwable ex) { - scheduleNext(_ref, false, this); - _connectPromise.tryFailure(ex); - } - } - } - - private static class Entry extends AtomicReference> { - final InetAddress _address; - long _delay; - - public Entry(InetAddress address) { - super(CompletableFuture.completedFuture(null)); - _address = address; - } - } - - private static LongSupplier constant(long value) { - return () -> value; - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/ReverseHandler.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/ReverseHandler.java deleted file mode 100644 index e50854fd52d..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/handlers/ReverseHandler.java +++ /dev/null @@ -1,136 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import com.linkedin.alpini.netty4.misc.NettyUtils; -import io.netty.channel.ChannelDuplexHandler; -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; -import io.netty.channel.ChannelPromise; -import io.netty.channel.embedded.EmbeddedChannel; -import java.util.function.Supplier; -import javax.annotation.Nonnull; - - -/** - * Reverse the polarity of the streams! - * - * Created by acurtis on 6/26/17. - */ -public class ReverseHandler extends ChannelDuplexHandler { - private final Supplier _handlers; - private EmbeddedChannel _embeddedChannel; - - public ReverseHandler(@Nonnull ChannelHandler... handlers) { - this(() -> handlers); - } - - public ReverseHandler(@Nonnull Supplier handlers) { - _handlers = handlers; - } - - @Override - public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { - _embeddedChannel.disconnect().addListener(future -> { - if (future.isSuccess()) { - super.disconnect(ctx, promise); - } else { - promise.setFailure(future.cause()); - } - }); - } - - @Override - public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { - _embeddedChannel.close().addListener(future -> { - if (future.isSuccess()) { - super.close(ctx, promise); - } else { - promise.setFailure(future.cause()); - } - }); - } - - @Override - public void deregister(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { - _embeddedChannel.deregister().addListener(future -> { - if (future.isSuccess()) { - super.deregister(ctx, promise); - } else { - promise.setFailure(future.cause()); - } - }); - } - - @Override - public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { - _embeddedChannel.writeOneInbound(msg, promise); - } - - @Override - public void flush(ChannelHandlerContext ctx) throws Exception { - _embeddedChannel.flushInbound(); - super.flush(ctx); - } - - @Override - public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { - _embeddedChannel.pipeline().fireChannelUnregistered(); - super.channelUnregistered(ctx); - } - - @Override - public void channelActive(ChannelHandlerContext ctx) throws Exception { - _embeddedChannel.pipeline().fireChannelActive(); - super.channelActive(ctx); - } - - @Override - public void channelInactive(ChannelHandlerContext ctx) throws Exception { - _embeddedChannel.pipeline().fireChannelInactive(); - super.channelInactive(ctx); - } - - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - _embeddedChannel.writeOutbound(msg); - } - - @Override - public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { - _embeddedChannel.flushOutbound(); - super.channelReadComplete(ctx); - } - - @Override - public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { - _embeddedChannel.pipeline().fireUserEventTriggered(evt); - super.userEventTriggered(ctx, evt); - } - - @Override - public void handlerAdded(ChannelHandlerContext ctx) throws Exception { - _embeddedChannel = new EmbeddedChannel( - ctx.channel().id(), - ctx.channel().metadata().hasDisconnect(), - ctx.channel().config(), - _handlers.get()) { - @Override - protected void handleOutboundMessage(Object msg) { - ctx.fireChannelRead(msg); - } - - @Override - protected void handleInboundMessage(Object msg) { - ctx.write(msg); - } - }; - _embeddedChannel.pipeline().addLast(NettyUtils.executorGroup(ctx.channel()), new ChannelInboundHandlerAdapter() { - @Override - public void channelReadComplete(ChannelHandlerContext innerCtx) throws Exception { - ctx.flush(); - super.channelReadComplete(innerCtx); - } - }); - super.handlerAdded(ctx); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/misc/AsciiStringURLCodec.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/misc/AsciiStringURLCodec.java deleted file mode 100644 index 14a76ce661d..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/misc/AsciiStringURLCodec.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.linkedin.alpini.netty4.misc; - -import com.linkedin.alpini.base.misc.URLCodec; -import io.netty.util.AsciiString; -import java.nio.charset.Charset; -import javax.annotation.Nonnull; - - -/** - * @author Antony T Curtis {@literal } - */ -public enum AsciiStringURLCodec { - SINGLETON; // Effective Java, Item 3 - Enum singleton - - /** - * Translates a string into {@code application/x-www-form-urlencoded} - * format using a specific encoding scheme. This method uses the - * supplied encoding scheme to obtain the bytes for unsafe - * characters. - *

- * Note: The - * World Wide Web Consortium Recommendation states that - * UTF-8 should be used. Not doing so may introduce - * incompatibilities. - * - * @param s {@code CharSequence} to be translated. - * @param enc The name of a supported - * character - * encoding. - * @return the translated {@code AsciiString}. - * @see java.net.URLEncoder#encode(java.lang.String, java.lang.String) - */ - public static @Nonnull AsciiString encode(@Nonnull CharSequence s, @Nonnull Charset enc) { - return AsciiString.of(URLCodec.encode(s, enc)); - } - - /** - * Decodes a {@code application/x-www-form-urlencoded} string using a specific - * encoding scheme. - * The supplied encoding is used to determine - * what characters are represented by any consecutive sequences of the - * form "{@code %xy}". - *

- * Note: The - * World Wide Web Consortium Recommendation states that - * UTF-8 should be used. Not doing so may introduce - * incompatibilities. - * - * @param s the {@code AsciiString} to decode - * @param enc The name of a supported - * character - * encoding. - * @return the newly decoded {@code CharSequence} - * @see java.net.URLDecoder#decode(java.lang.String, java.lang.String) - */ - public static @Nonnull CharSequence decode(@Nonnull AsciiString s, @Nonnull Charset enc) { - return URLCodec.decode(s, enc); - } - -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/misc/BasicHttpObjectDecoder.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/misc/BasicHttpObjectDecoder.java deleted file mode 100644 index 229caa8ab84..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/misc/BasicHttpObjectDecoder.java +++ /dev/null @@ -1,850 +0,0 @@ -package com.linkedin.alpini.netty4.misc; - -import com.linkedin.alpini.base.misc.ByteBufAsciiString; -import com.linkedin.alpini.base.misc.HeaderStringCache; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.DecoderResult; -import io.netty.handler.codec.PrematureChannelClosureException; -import io.netty.handler.codec.TooLongFrameException; -import io.netty.handler.codec.http.DefaultHttpContent; -import io.netty.handler.codec.http.DefaultLastHttpContent; -import io.netty.handler.codec.http.HttpConstants; -import io.netty.handler.codec.http.HttpContent; -import io.netty.handler.codec.http.HttpExpectationFailedEvent; -import io.netty.handler.codec.http.HttpHeaderNames; -import io.netty.handler.codec.http.HttpHeaderValues; -import io.netty.handler.codec.http.HttpHeaders; -import io.netty.handler.codec.http.HttpMessage; -import io.netty.handler.codec.http.HttpObjectDecoder; -import io.netty.handler.codec.http.HttpResponse; -import io.netty.handler.codec.http.HttpResponseStatus; -import io.netty.handler.codec.http.HttpUtil; -import io.netty.handler.codec.http.HttpVersion; -import io.netty.handler.codec.http.LastHttpContent; -import io.netty.util.ByteProcessor; -import java.util.List; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -public abstract class BasicHttpObjectDecoder extends HttpObjectDecoder { - private static final Logger LOG = LogManager.getLogger(BasicHttpObjectDecoder.class); - - private final int maxChunkSize; - private final boolean chunkedSupported; - protected final boolean validateHeaders; - private final HeaderParser headerParser; - private final LineParser lineParser; - - private HttpMessage message; - private long chunkSize; - private long contentLength = Long.MIN_VALUE; - private volatile boolean resetRequested; - - // These will be updated by splitHeader(...) - private ByteBufAsciiString name; - private ByteBufAsciiString value; - - private LastHttpContent trailer; - - /** - * The internal state of {@link BasicHttpObjectDecoder}. - * Internal use only. - */ - public enum State { - SKIP_CONTROL_CHARS, READ_INITIAL, READ_HEADER, READ_VARIABLE_LENGTH_CONTENT, READ_FIXED_LENGTH_CONTENT, - READ_CHUNK_SIZE, READ_CHUNKED_CONTENT, READ_CHUNK_DELIMITER, READ_CHUNK_FOOTER, BAD_MESSAGE, UPGRADED - } - - private State currentState = State.SKIP_CONTROL_CHARS; - - /** - * Creates a new instance with the default - * {@code maxInitialLineLength (4096}}, {@code maxHeaderSize (8192)}, and - * {@code maxChunkSize (8192)}. - */ - protected BasicHttpObjectDecoder() { - this(4096, 8192, 8192, true); - } - - /** - * Creates a new instance with the specified parameters. - */ - protected BasicHttpObjectDecoder( - int maxInitialLineLength, - int maxHeaderSize, - int maxChunkSize, - boolean chunkedSupported) { - this(maxInitialLineLength, maxHeaderSize, maxChunkSize, chunkedSupported, true); - } - - /** - * Creates a new instance with the specified parameters. - */ - protected BasicHttpObjectDecoder( - int maxInitialLineLength, - int maxHeaderSize, - int maxChunkSize, - boolean chunkedSupported, - boolean validateHeaders) { - this(maxInitialLineLength, maxHeaderSize, maxChunkSize, chunkedSupported, validateHeaders, 128); - } - - protected BasicHttpObjectDecoder( - int maxInitialLineLength, - int maxHeaderSize, - int maxChunkSize, - boolean chunkedSupported, - boolean validateHeaders, - int initialBufferSize) { - if (maxInitialLineLength <= 0) { - throw new IllegalArgumentException("maxInitialLineLength must be a positive integer: " + maxInitialLineLength); - } - if (maxHeaderSize <= 0) { - throw new IllegalArgumentException("maxHeaderSize must be a positive integer: " + maxHeaderSize); - } - if (maxChunkSize <= 0) { - throw new IllegalArgumentException("maxChunkSize must be a positive integer: " + maxChunkSize); - } - lineParser = new LineParser(maxInitialLineLength); - headerParser = new HeaderParser(maxHeaderSize); - this.maxChunkSize = maxChunkSize; - this.chunkedSupported = chunkedSupported; - this.validateHeaders = validateHeaders; - } - - public final State getDecoderState() { - return currentState; - } - - @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List out) throws Exception { - if (resetRequested) { - resetNow(); - } - - switch (currentState) { - case SKIP_CONTROL_CHARS: { - if (!skipControlCharacters(buffer)) { - return; - } - currentState = State.READ_INITIAL; - } - case READ_INITIAL: - try { // SUPPRESS CHECKSTYLE FallThroughCheck - ByteBufAsciiString line = lineParser.parse(buffer); - if (line == null) { - return; - } - ByteBufAsciiString[] initialLine = splitInitialLine(line); - if (initialLine.length < 3) { - // Invalid initial line - ignore. - currentState = State.SKIP_CONTROL_CHARS; - return; - } - - try { - message = createMessage(initialLine); - currentState = State.READ_HEADER; - } finally { - line.release(); - } - // fall-through - } catch (Exception e) { - out.add(invalidMessage(buffer, e)); - return; - } - case READ_HEADER: - try { // SUPPRESS CHECKSTYLE FallThroughCheck - State nextState = readHeaders(buffer); - if (nextState == null) { - return; - } - currentState = nextState; - switch (nextState) { - case SKIP_CONTROL_CHARS: - // fast-path - // No content is expected. - out.add(message); - out.add(LastHttpContent.EMPTY_LAST_CONTENT); - resetNow(); - return; - case READ_CHUNK_SIZE: - if (!chunkedSupported) { - throw new IllegalArgumentException("Chunked messages not supported"); - } - // Chunked encoding - generate HttpMessage first. HttpChunks will follow. - out.add(message); - return; - default: - /* - * RFC 7230, 3.3.3 states that if a - * request does not have either a transfer-encoding or a content-length header then the message body - * length is 0. However for a response the body length is the number of octets received prior to the - * server closing the connection. So we treat this as variable length chunked encoding. - */ - long contentLength = contentLength(); - if (contentLength == 0 || contentLength == -1 && isDecodingRequest()) { - out.add(message); - out.add(LastHttpContent.EMPTY_LAST_CONTENT); - resetNow(); - return; - } - - assert nextState == State.READ_FIXED_LENGTH_CONTENT || nextState == State.READ_VARIABLE_LENGTH_CONTENT; - - out.add(message); - - if (nextState == State.READ_FIXED_LENGTH_CONTENT) { - // chunkSize will be decreased as the READ_FIXED_LENGTH_CONTENT state reads data chunk by chunk. - chunkSize = contentLength; - } - - // We return here, this forces decode to be called again where we will decode the content - return; - } - } catch (Exception e) { - out.add(invalidMessage(buffer, e)); - return; - } - case READ_VARIABLE_LENGTH_CONTENT: { - // Keep reading data as a chunk until the end of connection is reached. - int toRead = Math.min(buffer.readableBytes(), maxChunkSize); - if (toRead > 0) { - ByteBuf content = buffer.readRetainedSlice(toRead); - out.add(new DefaultHttpContent(content)); - } - return; - } - case READ_FIXED_LENGTH_CONTENT: { - int readLimit = buffer.readableBytes(); - - // Check if the buffer is readable first as we use the readable byte count - // to create the HttpChunk. This is needed as otherwise we may end up with - // create a HttpChunk instance that contains an empty buffer and so is - // handled like it is the last HttpChunk. - // - // See https://github.com/netty/netty/issues/433 - if (readLimit == 0) { - return; - } - - int toRead = Math.min(readLimit, maxChunkSize); - if (toRead > chunkSize) { - toRead = (int) chunkSize; - } - ByteBuf content = buffer.readRetainedSlice(toRead); - chunkSize -= toRead; - - if (chunkSize == 0) { - // Read all content. - out.add(new DefaultLastHttpContent(content, validateHeaders)); - resetNow(); - } else { - out.add(new DefaultHttpContent(content)); - } - return; - } - /* - * everything else after this point takes care of reading chunked content. basically, read chunk size, - * read chunk, read and ignore the CRLF and repeat until 0 - */ - case READ_CHUNK_SIZE: - try { - ByteBufAsciiString line = lineParser.parse(buffer); - if (line == null) { - return; - } - int chunkSize; - try { - chunkSize = getChunkSize(line); - } finally { - line.release(); - } - this.chunkSize = chunkSize; - if (chunkSize == 0) { - currentState = State.READ_CHUNK_FOOTER; - return; - } - currentState = State.READ_CHUNKED_CONTENT; - // fall-through - } catch (Exception e) { - out.add(invalidChunk(buffer, e)); - return; - } - case READ_CHUNKED_CONTENT: { // SUPPRESS CHECKSTYLE FallThroughCheck - assert chunkSize <= Integer.MAX_VALUE; - int toRead = Math.min((int) chunkSize, maxChunkSize); - toRead = Math.min(toRead, buffer.readableBytes()); - if (toRead == 0) { - return; - } - HttpContent chunk = new DefaultHttpContent(buffer.readRetainedSlice(toRead)); - chunkSize -= toRead; - - out.add(chunk); - - if (chunkSize != 0) { - return; - } - currentState = State.READ_CHUNK_DELIMITER; - // fall-through - } - case READ_CHUNK_DELIMITER: { // SUPPRESS CHECKSTYLE FallThroughCheck - final int wIdx = buffer.writerIndex(); - int rIdx = buffer.readerIndex(); - while (wIdx > rIdx) { - byte next = buffer.getByte(rIdx++); - if (next == HttpConstants.LF) { - currentState = State.READ_CHUNK_SIZE; - break; - } - } - buffer.readerIndex(rIdx); - return; - } - case READ_CHUNK_FOOTER: - try { - LastHttpContent trailer = readTrailingHeaders(buffer); - if (trailer == null) { - return; - } - out.add(trailer); - resetNow(); - return; - } catch (Exception e) { - out.add(invalidChunk(buffer, e)); - return; - } - case BAD_MESSAGE: { - // Keep discarding until disconnection. - buffer.skipBytes(buffer.readableBytes()); - break; - } - case UPGRADED: { - int readableBytes = buffer.readableBytes(); - if (readableBytes > 0) { - // Keep on consuming as otherwise we may trigger an DecoderException, - // other handler will replace this codec with the upgraded protocol codec to - // take the traffic over at some point then. - // See https://github.com/netty/netty/issues/2173 - out.add(buffer.readBytes(readableBytes)); - } - break; - } - default: - throw new IllegalStateException(); - } - } - - @Override - protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { - super.decodeLast(ctx, in, out); - - if (resetRequested) { - // If a reset was requested by decodeLast() we need to do it now otherwise we may produce a - // LastHttpContent while there was already one. - resetNow(); - } - // Handle the last unfinished message. - if (message != null) { - boolean chunked = HttpUtil.isTransferEncodingChunked(message); - if (currentState == State.READ_VARIABLE_LENGTH_CONTENT && !in.isReadable() && !chunked) { - // End of connection. - out.add(LastHttpContent.EMPTY_LAST_CONTENT); - resetNow(); - return; - } - - if (currentState == State.READ_HEADER) { - // If we are still in the state of reading headers we need to create a new invalid message that - // signals that the connection was closed before we received the headers. - out.add( - invalidMessage( - Unpooled.EMPTY_BUFFER, - new PrematureChannelClosureException("Connection closed before received headers"))); - resetNow(); - return; - } - - // Check if the closure of the connection signifies the end of the content. - boolean prematureClosure; - if (isDecodingRequest() || chunked) { - // The last request did not wait for a response. - prematureClosure = true; - } else { - // Compare the length of the received content and the 'Content-Length' header. - // If the 'Content-Length' header is absent, the length of the content is determined by the end of the - // connection, so it is perfectly fine. - prematureClosure = contentLength() > 0; - } - - if (!prematureClosure) { - out.add(LastHttpContent.EMPTY_LAST_CONTENT); - } - resetNow(); - } - } - - @Override - public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { - if (evt instanceof HttpExpectationFailedEvent) { - switch (currentState) { - case READ_FIXED_LENGTH_CONTENT: - case READ_VARIABLE_LENGTH_CONTENT: - case READ_CHUNK_SIZE: - reset(); - break; - default: - break; - } - } - super.userEventTriggered(ctx, evt); - } - - protected boolean isContentAlwaysEmpty(HttpMessage msg) { - if (msg instanceof HttpResponse) { - HttpResponse res = (HttpResponse) msg; - int code = res.status().code(); - - // Correctly handle return codes of 1xx. - // - // See: - // - http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html Section 4.4 - // - https://github.com/netty/netty/issues/222 - if (code >= 100 && code < 200) { - // One exception: Hixie 76 websocket handshake response - return !(code == 101 && !res.headers().contains(HttpHeaderNames.SEC_WEBSOCKET_ACCEPT) - && res.headers().contains(HttpHeaderNames.UPGRADE, HttpHeaderValues.WEBSOCKET, true)); - } - - switch (code) { - case 204: - case 304: - return true; - default: - break; - } - } - return false; - } - - /** - * Returns true if the server switched to a different protocol than HTTP/1.0 or HTTP/1.1, e.g. HTTP/2 or Websocket. - * Returns false if the upgrade happened in a different layer, e.g. upgrade from HTTP/1.1 to HTTP/1.1 over TLS. - */ - protected boolean isSwitchingToNonHttp1Protocol(HttpResponse msg) { - if (msg.status().code() != HttpResponseStatus.SWITCHING_PROTOCOLS.code()) { - return false; - } - String newProtocol = msg.headers().get(HttpHeaderNames.UPGRADE); - return newProtocol == null - || !newProtocol.contains(HttpVersion.HTTP_1_0.text()) && !newProtocol.contains(HttpVersion.HTTP_1_1.text()); - } - - /** - * Resets the state of the decoder so that it is ready to decode a new message. - * This method is useful for handling a rejected request with {@code Expect: 100-continue} header. - */ - public void reset() { - resetRequested = true; - } - - private void resetHeaderName() { - if (name != null) { - name.release(); - } - if (value != null) { - value.release(); - } - name = null; - value = null; - } - - private void resetNow() { - HttpMessage message = this.message; - this.message = null; - resetHeaderName(); - contentLength = Long.MIN_VALUE; - lineParser.reset(); - headerParser.reset(); - trailer = null; - if (!isDecodingRequest()) { - HttpResponse res = (HttpResponse) message; - if (res != null && isSwitchingToNonHttp1Protocol(res)) { - currentState = State.UPGRADED; - return; - } - } - - resetRequested = false; - currentState = State.SKIP_CONTROL_CHARS; - } - - private HttpMessage invalidMessage(ByteBuf in, Exception cause) { - LOG.error("invalidMessage", cause); - currentState = State.BAD_MESSAGE; - - // Advance the readerIndex so that ByteToMessageDecoder does not complain - // when we produced an invalid message without consuming anything. - in.skipBytes(in.readableBytes()); - - if (message == null) { - message = createInvalidMessage(); - } - message.setDecoderResult(DecoderResult.failure(cause)); - - HttpMessage ret = message; - message = null; - return ret; - } - - private HttpContent invalidChunk(ByteBuf in, Exception cause) { - LOG.error("invalidChunk", cause); - currentState = State.BAD_MESSAGE; - - // Advance the readerIndex so that ByteToMessageDecoder does not complain - // when we produced an invalid message without consuming anything. - in.skipBytes(in.readableBytes()); - - HttpContent chunk = new DefaultLastHttpContent(Unpooled.EMPTY_BUFFER); - chunk.setDecoderResult(DecoderResult.failure(cause)); - message = null; - trailer = null; - return chunk; - } - - private static boolean skipControlCharacters(ByteBuf buffer) { - boolean skiped = false; - final int wIdx = buffer.writerIndex(); - int rIdx = buffer.readerIndex(); - while (wIdx > rIdx) { - int c = buffer.getUnsignedByte(rIdx++); - if (!Character.isISOControl(c) && !Character.isWhitespace(c)) { - rIdx--; - skiped = true; - break; - } - } - buffer.readerIndex(rIdx); - return skiped; - } - - private static void addHeader( - HeaderStringCache.Cache cache, - HttpHeaders headers, - CharSequence name, - CharSequence value) { - name = cache.lookupName(name); - value = cache.lookupValue(value); - headers.add(name, value); - } - - private State readHeaders(ByteBuf buffer) { - final HttpMessage message = this.message; - final HttpHeaders headers = message.headers(); - final HeaderStringCache.Cache cache = HeaderStringCache.getAndExpireOld(); - - ByteBufAsciiString line = headerParser.parse(buffer); - if (line == null) { - return null; - } - try { - if (line.length() > 0) { - do { - char firstChar = line.charAt(0); - if (name != null && (firstChar == ' ' || firstChar == '\t')) { - ByteBufAsciiString oldValue = value; - - value = oldValue.concat(" ", line.trim()); - oldValue.release(); - } else { - if (name != null) { - addHeader(cache, headers, name, value); - } - splitHeader(line); - } - - ByteBufAsciiString newLine = headerParser.parse(buffer); - if (newLine == null) { - return null; - } - ByteBufAsciiString oldLine = line; - line = newLine; - oldLine.release(); - } while (line.length() > 0); - } - } finally { - line.release(); - } - - // Add the last header. - if (name != null) { - addHeader(cache, headers, name, value); - } - // reset name and value fields - resetHeaderName(); - - State nextState; - - if (isContentAlwaysEmpty(message)) { - HttpUtil.setTransferEncodingChunked(message, false); - nextState = State.SKIP_CONTROL_CHARS; - } else if (HttpUtil.isTransferEncodingChunked(message)) { - nextState = State.READ_CHUNK_SIZE; - } else if (contentLength() >= 0) { - nextState = State.READ_FIXED_LENGTH_CONTENT; - } else { - nextState = State.READ_VARIABLE_LENGTH_CONTENT; - } - return nextState; - } - - private long contentLength() { - if (contentLength == Long.MIN_VALUE) { - contentLength = HttpUtil.getContentLength(message, -1L); - } - return contentLength; - } - - private LastHttpContent readTrailingHeaders(ByteBuf buffer) { - ByteBufAsciiString line = headerParser.parse(buffer); - if (line == null) { - return null; - } - try { - ByteBufAsciiString lastHeader = null; - if (line.length() > 0) { - HeaderStringCache.Cache cache = HeaderStringCache.getAndExpireOld(); - LastHttpContent trailer = this.trailer; - if (trailer == null) { - trailer = new DefaultLastHttpContent(Unpooled.EMPTY_BUFFER, validateHeaders); - this.trailer = trailer; - } - do { - char firstChar = line.charAt(0); - if (lastHeader != null && (firstChar == ' ' || firstChar == '\t')) { - List current = trailer.trailingHeaders().getAll(lastHeader); - if (!current.isEmpty()) { - int lastPos = current.size() - 1; - // please do not make one line from below code - // as it breaks +XX:OptimizeStringConcat optimization - ByteBufAsciiString lineTrimmed = line.trim(); - String currentLastPos = current.get(lastPos); - current.set(lastPos, currentLastPos + lineTrimmed); - } - } else { - splitHeader(line); - ByteBufAsciiString headerName = name; - if (!HttpHeaderNames.CONTENT_LENGTH.contentEqualsIgnoreCase(headerName) - && !HttpHeaderNames.TRANSFER_ENCODING.contentEqualsIgnoreCase(headerName) - && !HttpHeaderNames.TRAILER.contentEqualsIgnoreCase(headerName)) { - addHeader(cache, trailer.trailingHeaders(), headerName, value); - } - lastHeader = name; - // reset name and value fields - resetHeaderName(); - } - - ByteBufAsciiString newLine = headerParser.parse(buffer); - if (newLine == null) { - return null; - } - ByteBufAsciiString oldLine = line; - line = newLine; - oldLine.release(); - } while (line.length() > 0); - - this.trailer = null; - return trailer; - } - } finally { - line.release(); - } - - return LastHttpContent.EMPTY_LAST_CONTENT; - } - - protected abstract boolean isDecodingRequest(); - - protected HttpMessage createMessage(ByteBufAsciiString[] initialLine) throws Exception { - return createMessage( - new String[] { initialLine[0].toString(), initialLine[1].toString(), initialLine[2].toString() }); - } - - protected abstract HttpMessage createMessage(String[] initialLine) throws Exception; - - protected abstract HttpMessage createInvalidMessage(); - - private static int getChunkSize(ByteBufAsciiString hex) { - hex = hex.trim(); - for (int i = 0; i < hex.length(); i++) { - char c = hex.charAt(i); - if (c == ';' || Character.isWhitespace(c) || Character.isISOControl(c)) { - hex = hex.subSequence(0, i); - break; - } - } - - return Integer.parseUnsignedInt(hex.toString(), 16); - } - - private static ByteBufAsciiString[] splitInitialLine(ByteBufAsciiString sb) { - int aStart; - int aEnd; - int bStart; - int bEnd; - int cStart; - int cEnd; - - aStart = findNonWhitespace(sb, 0); - aEnd = findWhitespace(sb, aStart); - - bStart = findNonWhitespace(sb, aEnd); - bEnd = findWhitespace(sb, bStart); - - cStart = findNonWhitespace(sb, bEnd); - cEnd = findEndOfString(sb); - - return new ByteBufAsciiString[] { sb.subSequence(aStart, aEnd, false), sb.subSequence(bStart, bEnd, false), - cStart < cEnd ? sb.subSequence(cStart, cEnd, false) : ByteBufAsciiString.EMPTY_STRING }; - } - - private void splitHeader(ByteBufAsciiString sb) { - final int length = sb.length(); - int nameStart; - int nameEnd; - int colonEnd; - int valueStart; - int valueEnd; - - nameStart = findNonWhitespace(sb, 0); - for (nameEnd = nameStart; nameEnd < length; nameEnd++) { - char ch = sb.charAt(nameEnd); - if (ch == ':' || Character.isWhitespace(ch)) { - break; - } - } - - for (colonEnd = nameEnd; colonEnd < length; colonEnd++) { - if (sb.charAt(colonEnd) == ':') { - colonEnd++; - break; - } - } - - resetHeaderName(); - - name = sb.subSequence(nameStart, nameEnd, false); - valueStart = findNonWhitespace(sb, colonEnd); - if (valueStart == length) { - value = ByteBufAsciiString.EMPTY_STRING; - } else { - valueEnd = findEndOfString(sb); - value = sb.subSequence(valueStart, valueEnd, false); - } - - name.retain(); - value.retain(); - } - - private static int findNonWhitespace(ByteBufAsciiString sb, int offset) { - for (int result = offset; result < sb.length(); ++result) { - if (!Character.isWhitespace(sb.charAt(result))) { - return result; - } - } - return sb.length(); - } - - private static int findWhitespace(ByteBufAsciiString sb, int offset) { - for (int result = offset; result < sb.length(); ++result) { - if (Character.isWhitespace(sb.charAt(result))) { - return result; - } - } - return sb.length(); - } - - private static int findEndOfString(ByteBufAsciiString sb) { - for (int result = sb.length() - 1; result > 0; --result) { - if (!Character.isWhitespace(sb.charAt(result))) { - return result + 1; - } - } - return 0; - } - - private static class HeaderParser implements ByteProcessor { - private final int maxLength; - private int size; - - HeaderParser(int maxLength) { - this.maxLength = maxLength; - } - - public ByteBufAsciiString parse(ByteBuf buffer) { - final int oldSize = size; - int start = buffer.readerIndex(); - int i = buffer.forEachByte(this); - if (i == -1) { - size = oldSize; - return null; - } - int length = i - start; - while (length > 0 && buffer.getByte(start + length - 1) == HttpConstants.CR) { - length--; - } - ByteBufAsciiString result = ByteBufAsciiString.read(buffer, length); - buffer.readerIndex(i + 1); - return result; - } - - public void reset() { - size = 0; - } - - @Override - public boolean process(byte value) { - char nextByte = (char) (value & 0xFF); - if (nextByte == HttpConstants.CR) { - return true; - } - if (nextByte == HttpConstants.LF) { - return false; - } - - if (++size > maxLength) { - // TODO: Respond with Bad Request and discard the traffic - // or close the connection. - // No need to notify the upstream handlers - just log. - // If decoding a response, just throw an exception. - throw newException(maxLength); - } - return true; - } - - protected TooLongFrameException newException(int maxLength) { - return new TooLongFrameException("HTTP header is larger than " + maxLength + " bytes."); - } - } - - private static final class LineParser extends HeaderParser { - LineParser(int maxLength) { - super(maxLength); - } - - @Override - public ByteBufAsciiString parse(ByteBuf buffer) { - reset(); - return super.parse(buffer); - } - - @Override - protected TooLongFrameException newException(int maxLength) { - return new TooLongFrameException("An HTTP line is larger than " + maxLength + " bytes."); - } - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/misc/DefaultFileChannelHttpResponse.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/misc/DefaultFileChannelHttpResponse.java deleted file mode 100644 index cca28833d63..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/misc/DefaultFileChannelHttpResponse.java +++ /dev/null @@ -1,195 +0,0 @@ -package com.linkedin.alpini.netty4.misc; - -import com.linkedin.alpini.io.IOUtils; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; -import io.netty.buffer.Unpooled; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.http.DefaultHttpContent; -import io.netty.handler.codec.http.DefaultHttpResponse; -import io.netty.handler.codec.http.DefaultLastHttpContent; -import io.netty.handler.codec.http.FullHttpResponse; -import io.netty.handler.codec.http.HttpHeaders; -import io.netty.handler.codec.http.HttpResponseStatus; -import io.netty.handler.codec.http.HttpVersion; -import io.netty.handler.codec.http.LastHttpContent; -import io.netty.util.concurrent.Promise; -import java.io.IOException; -import java.nio.channels.FileChannel; -import java.util.Objects; -import javax.annotation.Nonnull; - - -/** - * @author Antony T Curtis {@literal } - */ -public class DefaultFileChannelHttpResponse extends DefaultHttpResponse implements ChunkedHttpResponse { - private static final int IO_CHUNK_SIZE = 8192; - - private final ByteBufAllocator _alloc; - private final FileChannel _fileChannel; - private final LastHttpContent _lastHttpContent; - private long _position; - - public DefaultFileChannelHttpResponse( - @Nonnull HttpVersion version, - @Nonnull HttpResponseStatus status, - boolean validateHeaders, - boolean singleFieldHeaders, - @Nonnull ByteBufAllocator alloc, - @Nonnull FileChannel fileChannel) { - this( - Objects.requireNonNull(version, "version"), - Objects.requireNonNull(status, "status"), - validateHeaders, - singleFieldHeaders, - Objects.requireNonNull(alloc, "alloc"), - Objects.requireNonNull(fileChannel, "fileChannel"), - new DefaultLastHttpContent(Unpooled.EMPTY_BUFFER, validateHeaders)); - } - - private DefaultFileChannelHttpResponse( - @Nonnull HttpVersion version, - @Nonnull HttpResponseStatus status, - boolean validateHeaders, - boolean singleFieldHeaders, - @Nonnull ByteBufAllocator alloc, - @Nonnull FileChannel fileChannel, - @Nonnull LastHttpContent lastHttpContent) { - super(version, status, validateHeaders, singleFieldHeaders); - _alloc = alloc; - _fileChannel = fileChannel; - _lastHttpContent = lastHttpContent; - } - - @Override - public void writeChunkedContent(ChannelHandlerContext ctx, Promise writePromise) throws IOException { - ByteBuf buffer = _alloc.ioBuffer(); - int bytes; - - try { - bytes = buffer.writeBytes(_fileChannel, _position, IO_CHUNK_SIZE); - } catch (IOException ex) { - IOUtils.closeQuietly(_fileChannel); - writePromise.setFailure(ex); - return; - } - - _position += bytes; - - if (bytes > 0) { - ctx.writeAndFlush(new DefaultHttpContent(buffer)).addListener(future -> { - if (future.isSuccess()) { - writeChunkedContent(ctx, writePromise); - } else { - IOUtils.closeQuietly(_fileChannel); - writePromise.setFailure(future.cause()); - } - }); - } else { - buffer.release(); - IOUtils.closeQuietly(_fileChannel); - LastHttpContent lastHttpContent; - if (trailingHeaders().isEmpty()) { - lastHttpContent = LastHttpContent.EMPTY_LAST_CONTENT; - } else { - lastHttpContent = new DefaultLastHttpContent(); - lastHttpContent.trailingHeaders().set(trailingHeaders()); - } - writePromise.setSuccess(lastHttpContent); - } - } - - @Override - public HttpHeaders trailingHeaders() { - return _lastHttpContent.trailingHeaders(); - } - - @Override - public ByteBuf content() { - return _lastHttpContent.content(); - } - - @Override - public FullHttpResponse copy() { - return this; - } - - @Override - public FullHttpResponse duplicate() { - return this; - } - - @Override - public FullHttpResponse retainedDuplicate() { - return this; - } - - @Override - public FullHttpResponse replace(ByteBuf content) { - return this; - } - - @Override - public FullHttpResponse retain(int increment) { - return this; - } - - /** - * Returns the reference count of this object. If {@code 0}, it means this object has been deallocated. - */ - @Override - public int refCnt() { - return _fileChannel.isOpen() ? 1 : 0; - } - - @Override - public FullHttpResponse retain() { - return this; - } - - @Override - public FullHttpResponse touch() { - return this; - } - - @Override - public FullHttpResponse touch(Object hint) { - return this; - } - - /** - * Decreases the reference count by {@code 1} and deallocates this object if the reference count reaches at - * {@code 0}. - * - * @return {@code true} if and only if the reference count became {@code 0} and this object has been deallocated - */ - @Override - public boolean release() { - return false; - } - - /** - * Decreases the reference count by the specified {@code decrement} and deallocates this object if the reference - * count reaches at {@code 0}. - * - * @param decrement - * @return {@code true} if and only if the reference count became {@code 0} and this object has been deallocated - */ - @Override - public boolean release(int decrement) { - return false; - } - - @Override - public FullHttpResponse setStatus(HttpResponseStatus status) { - super.setStatus(status); - return this; - } - - @Override - public FullHttpResponse setProtocolVersion(HttpVersion version) { - super.setProtocolVersion(version); - return this; - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/misc/EventGroupLoopSupplier.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/misc/EventGroupLoopSupplier.java deleted file mode 100644 index 03c94676ac1..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/misc/EventGroupLoopSupplier.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.linkedin.alpini.netty4.misc; - -import io.netty.channel.EventLoopGroup; -import javax.annotation.Nonnull; - - -/** - * Created by acurtis on 12/22/17. - */ -public interface EventGroupLoopSupplier { - @Nonnull - EventLoopGroup getEventLoopGroup(); -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/misc/Http2Utils.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/misc/Http2Utils.java index f4b34873e8e..e826a1dbd42 100644 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/misc/Http2Utils.java +++ b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/misc/Http2Utils.java @@ -1,23 +1,9 @@ package com.linkedin.alpini.netty4.misc; -import com.linkedin.alpini.netty4.pool.Http2AwareChannelPool; -import io.netty.channel.Channel; import io.netty.channel.ChannelPipeline; -import io.netty.handler.codec.http2.EspressoHttp2MultiplexHandler; -import io.netty.handler.codec.http2.Http2ChannelDuplexHandler; -import io.netty.handler.codec.http2.Http2Connection; import io.netty.handler.codec.http2.Http2ConnectionHandler; import io.netty.handler.codec.http2.Http2Error; import io.netty.handler.codec.http2.Http2Exception; -import io.netty.handler.codec.http2.Http2FrameStream; -import io.netty.handler.codec.http2.Http2LocalFlowController; -import io.netty.handler.codec.http2.Http2MultiplexHandler; -import io.netty.handler.codec.http2.Http2StreamChannel; -import io.netty.util.AttributeKey; -import io.netty.util.AttributeMap; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Future; -import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -27,33 +13,12 @@ * @author Yaoming Zhan */ public final class Http2Utils { - public static final AttributeKey> FRAME_STREAM_KEY = - AttributeKey.valueOf("frameStream"); - // Netty doesn't have this exposed as a constant - public static final String MAXIMUM_ACTIVE_STREAMS_VIOLATED_MSG = "Maximum active streams violated for this endpoint."; private static final String MAX_ACTIVE_STREAMS_VIOLATED_MSG_PREFIX = "Maximum active streams"; private Http2Utils() { throw new UnsupportedOperationException(); } - public static Http2Connection http2Connection(Channel parentChannel) { - return parentChannel.attr(Http2AwareChannelPool.HTTP2_CONNECTION).get(); - } - - public static Http2Connection.Endpoint localEndpoint(Channel parentChannel) { - return http2Connection(parentChannel).local(); - } - - /** - * Checks if the local HTTP/2 endpoint can open a new stream. - * @param parentChannel Parent HTTP/2 channel - * @return true if it can open new stream - */ - public static boolean canOpenLocalStream(Channel parentChannel) { - return localEndpoint(parentChannel).canOpenStream(); - } - /** * Checks if an exception is thrown because of too many active streams. * @param t Exception @@ -70,24 +35,6 @@ public static boolean isTooManyActiveStreamsError(Throwable t) { return false; } - public static void closeStreamChannel(Http2StreamChannel streamChannel) { - try { - if (!streamChannel.closeFuture().isDone()) { - streamChannel.close(); - } - } catch (Exception ex) { - // eat this - } - } - - public static Http2ChannelDuplexHandler http2MultiplexHandler(boolean channelReuse, ChannelPipeline pipeline) { - return channelReuse ? pipeline.get(EspressoHttp2MultiplexHandler.class) : pipeline.get(Http2MultiplexHandler.class); - } - - public static boolean isHttp2MultiplexPipeline(boolean channelReuse, ChannelPipeline pipeline) { - return http2MultiplexHandler(channelReuse, pipeline) != null; - } - @Deprecated public static boolean isHttp2Pipeline(ChannelPipeline pipeline) { return isHttp2ParentChannelPipeline(pipeline); @@ -97,54 +44,6 @@ public static boolean isHttp2ParentChannelPipeline(ChannelPipeline pipeline) { return pipeline.context(Http2ConnectionHandler.class) != null; } - /** - * Checks if a stream channel is currently available for reuse. - * @param streamChannel Stream channel - * @return true if available for reuse - */ - public static boolean channelAvailableForReuse(Http2StreamChannel streamChannel) { - return NettyUtils.isTrue(streamChannel, Http2AwareChannelPool.HTTP2_STREAM_CHANNEL_AVAILABLE_FOR_REUSE); - } - - /** - * Checks if a stream channel is a previously reused channel. - * @param streamChannel Stream channel - * @return true if reused - */ - public static boolean isReusedChannel(Http2StreamChannel streamChannel) { - return NettyUtils.isTrue(streamChannel, Http2AwareChannelPool.HTTP2_REUSED_STREAM_CHANNEL); - } - - /** - * Mark a stream to indicate that it will be reused. - * @param streamChannel Stream channel - */ - public static void markChannelForReuse(Http2StreamChannel streamChannel) { - streamChannel.attr(Http2AwareChannelPool.HTTP2_STREAM_CHANNEL_AVAILABLE_FOR_REUSE).set(Boolean.FALSE); - streamChannel.attr(Http2AwareChannelPool.HTTP2_REUSED_STREAM_CHANNEL).set(Boolean.TRUE); - } - - /** - * Unmark a stream channel to indicate that reuse is completed. - * @param streamChannel Stream channel - */ - public static void unmarkReusedStream(Http2StreamChannel streamChannel) { - streamChannel.attr(Http2AwareChannelPool.HTTP2_REUSED_STREAM_CHANNEL).set(null); - } - - public static void markChannelAvailableForReuse(Http2StreamChannel streamChannel) { - streamChannel.attr(Http2AwareChannelPool.HTTP2_STREAM_CHANNEL_AVAILABLE_FOR_REUSE).set(Boolean.TRUE); - } - - /** - * Creates an {@link Http2Exception} for having too many concurrent requests. - * @param msg Exception message - * @return Exception - */ - public static Http2Exception tooManyStreamsException(String msg) { - return new Http2Exception(Http2Error.REFUSED_STREAM, MAXIMUM_ACTIVE_STREAMS_VIOLATED_MSG + " " + msg); - } - public static boolean isUnexpectedError(long errorCode, boolean fromRemote) { return isUnexpectedError(Http2Error.valueOf(errorCode), fromRemote); } @@ -182,24 +81,4 @@ public static boolean isUnexpectedError(@Nullable Http2Error errorEnum, boolean } return true; } - - /** - * Check whether the channel is a http2 connection that has been configured. - * @param parentChannel http Channel - */ - public static boolean isConfiguredHttp2Connection(@Nonnull Channel parentChannel) { - return parentChannel.hasAttr(Http2AwareChannelPool.HTTP2_CONNECTION) - && null != parentChannel.attr(Http2AwareChannelPool.HTTP2_CONNECTION).get(); - } - - public static Future frameStream(AttributeMap map) { - return map.hasAttr(FRAME_STREAM_KEY) ? map.attr(FRAME_STREAM_KEY).get() : null; - } - - public static void setFrameStream(AttributeMap map, Http2FrameStream frameStream) { - if (map.hasAttr(FRAME_STREAM_KEY) && map.attr(FRAME_STREAM_KEY).get() != null - && !map.attr(FRAME_STREAM_KEY).get().isDone()) { - map.attr(FRAME_STREAM_KEY).get().complete(frameStream); - } - } } diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/misc/NettyUtils.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/misc/NettyUtils.java index d31f2014081..14aca91c3c4 100644 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/misc/NettyUtils.java +++ b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/misc/NettyUtils.java @@ -3,25 +3,9 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import io.netty.channel.ChannelPipeline; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.epoll.EpollDatagramChannel; -import io.netty.channel.epoll.EpollEventLoopGroup; -import io.netty.channel.epoll.EpollServerSocketChannel; -import io.netty.channel.epoll.EpollSocketChannel; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.DatagramChannel; -import io.netty.channel.socket.ServerSocketChannel; -import io.netty.channel.socket.SocketChannel; -import io.netty.channel.socket.nio.NioDatagramChannel; -import io.netty.channel.socket.nio.NioServerSocketChannel; -import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.util.AttributeKey; import io.netty.util.AttributeMap; import io.netty.util.concurrent.EventExecutorGroup; -import java.util.Objects; -import java.util.concurrent.Executor; -import java.util.concurrent.ThreadFactory; -import javax.annotation.Nonnull; /** @@ -32,143 +16,8 @@ private NettyUtils() { throw new UnsupportedOperationException("Never instantiated"); } - public enum Mode { - NIO { - @Override - public Class socketChannel() { - return NioSocketChannel.class; - } - - @Override - public Class serverSocketChannel() { - return NioServerSocketChannel.class; - } - - @Override - public Class datagramChannel() { - return NioDatagramChannel.class; - } - - @Override - public NioEventLoopGroup newEventLoopGroup(int nThreads, ThreadFactory threadFactory) { - return new NioEventLoopGroup(nThreads, threadFactory); - } - - @Override - public NioEventLoopGroup newEventLoopGroup(int nThreads, Executor executor) { - return new NioEventLoopGroup(nThreads, executor); - } - }, - - EPOLL { - @Override - public Class socketChannel() { - return EpollSocketChannel.class; - } - - @Override - public Class serverSocketChannel() { - return EpollServerSocketChannel.class; - } - - @Override - public Class datagramChannel() { - return EpollDatagramChannel.class; - } - - @Override - public EpollEventLoopGroup newEventLoopGroup(int nThreads, ThreadFactory threadFactory) { - return new EpollEventLoopGroup(nThreads, threadFactory); - } - - @Override - public EpollEventLoopGroup newEventLoopGroup(int nThreads, Executor executor) { - return new EpollEventLoopGroup(nThreads, executor); - } - }; - - public abstract Class socketChannel(); - - public abstract Class serverSocketChannel(); - - public abstract Class datagramChannel(); - - public abstract EventLoopGroup newEventLoopGroup(int nThreads, ThreadFactory threadFactory); - - public abstract EventLoopGroup newEventLoopGroup(int nThreads, Executor executor); - } - - public enum ReadMode { - COPY { - @Override - public ByteBuf read(ByteBuf in, int length) { - return in.readBytes(length); - } - }, - SLICE { - @Override - public ByteBuf read(ByteBuf in, int length) { - return in.readRetainedSlice(length); - } - }; - - public abstract ByteBuf read(ByteBuf in, int length); - } - - @Nonnull - private static Mode _mode = Mode.NIO; - - @Nonnull - private static ReadMode _readMode = ReadMode.COPY; - - public static void setMode(String mode) { - setMode(Mode.valueOf(mode)); - } - - public static void setMode(Mode mode) { - _mode = Objects.requireNonNull(mode); - } - - @Nonnull - public static Mode mode() { - return _mode; - } - - public static void setReadMode(String mode) { - setReadMode(ReadMode.valueOf(mode)); - } - - public static void setReadMode(ReadMode mode) { - _readMode = Objects.requireNonNull(mode); - } - - @Nonnull - public static ReadMode readMode() { - return _readMode; - } - public static ByteBuf read(ByteBuf in, int length) { - return readMode().read(in, length); - } - - public static EventLoopGroup newEventLoopGroup(int nThreads, ThreadFactory threadFactory) { - return mode().newEventLoopGroup(nThreads, threadFactory); - } - - public static EventLoopGroup newEventLoopGroup(int nThreads, Executor executor) { - return mode().newEventLoopGroup(nThreads, executor); - } - - public static Class socketChannel() { - return mode().socketChannel(); - } - - public static Class serverSocketChannel() { - return mode().serverSocketChannel(); - } - - public static Class datagramChannel() { - return mode().datagramChannel(); + return in.readBytes(length); } public static final AttributeKey EXECUTOR_GROUP_ATTRIBUTE_KEY = diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/BasicDnsResolver.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/BasicDnsResolver.java deleted file mode 100644 index c112898b76d..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/BasicDnsResolver.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.Promise; -import java.net.InetSocketAddress; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import javax.annotation.Nonnull; - - -/** - * A simple asynchronous resolver which uses the default JVM blocking resolver. - * - * @author acurtis on 3/30/17. - */ -public class BasicDnsResolver implements ChannelPoolResolver { - private final ThreadLocal _executor = ThreadLocal.withInitial(Executors::newSingleThreadExecutor); - - @Override - @Nonnull - public Future resolve( - @Nonnull InetSocketAddress address, - @Nonnull Promise promise) { - if (address.isUnresolved()) { - _executor.get().execute(() -> { - try { - if (!promise.isDone()) { - promise.setSuccess(new InetSocketAddress(address.getHostString(), address.getPort())); - } - } catch (Exception e) { - promise.setFailure(e); - } - }); - return promise; - } else { - return promise.setSuccess(address); - } - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/ChannelPoolFactory.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/ChannelPoolFactory.java deleted file mode 100644 index e291c7d481c..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/ChannelPoolFactory.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import com.linkedin.alpini.netty4.handlers.Http2PingSendHandler; -import io.netty.channel.Channel; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.pool.ChannelPoolHandler; -import java.net.InetSocketAddress; -import java.util.function.Function; -import javax.annotation.CheckReturnValue; -import javax.annotation.Nonnull; - - -/** - * An interface to construct {@link ManagedChannelPool} instances for the {@link ChannelPoolManager}. - * - * @author acurtis on 3/29/17. - */ -public interface ChannelPoolFactory { - /** - * Constructs a new ChannelPool which must connect to the specified {@code address}. - * @param manager The channel pool manager which will manage the pool. - * @param handler A handler to be notified of events. - * @param eventLoop The eventloop for the connection pool. - * @param address Target address/port for the connection pool. - * @return New instance of {@link ManagedChannelPool} - */ - @CheckReturnValue - ManagedChannelPool construct( - @Nonnull ChannelPoolManager manager, - @Nonnull ChannelPoolHandler handler, - @Nonnull EventLoopGroup eventLoop, - @Nonnull InetSocketAddress address); - - default void setHttp2PingSendHandlerFunction(Function pingSendHandlerFn) { - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/ChannelPoolManager.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/ChannelPoolManager.java deleted file mode 100644 index 5d3e125e2a1..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/ChannelPoolManager.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import com.linkedin.alpini.consts.QOS; -import io.netty.channel.Channel; -import io.netty.channel.EventLoop; -import io.netty.util.AttributeKey; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.ImmediateEventExecutor; -import io.netty.util.concurrent.Promise; -import javax.annotation.CheckReturnValue; -import javax.annotation.Nonnull; - - -/** - * The interface which describes the public methods of a channel pool manager. - * - * @author acurtis on 3/30/17. - */ -public interface ChannelPoolManager { - AttributeKey FAILED_HEALTH_CHECK = AttributeKey.valueOf(ChannelPoolManager.class, "failedHealthCheck"); - - /** - * The number of threads in the eventloopgroup used by this class. - * @return thread count - * @deprecated due to confusing name. Use {@link #subpoolCount} - */ - @Deprecated - int executorCount(); - - /** - * The number of subpool threads used per pool by this class. - * Must be less than or equal to the number of threads in the eventloopgroup. - * Must be greater than zero. - * @return thread count - */ - default int subpoolCount() { - return executorCount(); - } - - /** - * Acquire a channel from the pool. - * @param hostNameAndPort host name and port - * @param queueName queue name - * @param qos priority - * @return future for acquired channel - */ - @CheckReturnValue - @Nonnull - Future acquire(@Nonnull String hostNameAndPort, @Nonnull String queueName, @Nonnull QOS qos); - - /** - * Acquire a channel from the pool. - * @param hostNameAndPort host name and port - * @param queueName queue name - * @param qos priority - * @return future for acquired channel - */ - @CheckReturnValue - @Nonnull - Future acquire( - @Nonnull EventLoop eventLoop, - @Nonnull String hostNameAndPort, - @Nonnull String queueName, - @Nonnull QOS qos); - - /** - * Release the channel to the pool. - * @param channel channel - * @return future which is completed when done - */ - @Nonnull - Future release(@Nonnull Channel channel); - - /** - * Open the connection pool to the specified host and port. - * The default implementation simply acquires a channel from the pool and then immediately releases it. - * @param hostNameAndPort Host and port string - * @return future which is completed when done - */ - @Nonnull - default Future open(@Nonnull String hostNameAndPort) { - Promise promise = ImmediateEventExecutor.INSTANCE.newPromise(); - acquire(hostNameAndPort, "default", QOS.NORMAL).addListener((Future future) -> { - if (future.isSuccess()) { - release(future.getNow()).addListener(released -> { - if (released.isSuccess()) { - promise.setSuccess(null); - } else { - promise.setFailure(released.cause()); - } - }); - } else { - promise.setFailure(future.cause()); - } - }); - return promise; - } - - /** - * Close the connection pool to the specified host and port. - * @param hostNameAndPort Host and port string - * @return future which is completed when done - */ - @Nonnull - Future close(@Nonnull String hostNameAndPort); -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/ChannelPoolManagerImpl.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/ChannelPoolManagerImpl.java deleted file mode 100755 index f196fe0c2e6..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/ChannelPoolManagerImpl.java +++ /dev/null @@ -1,1061 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import com.linkedin.alpini.base.concurrency.Executors; -import com.linkedin.alpini.base.concurrency.Lazy; -import com.linkedin.alpini.base.concurrency.NamedThreadFactory; -import com.linkedin.alpini.base.misc.CollectionUtil; -import com.linkedin.alpini.base.misc.ExceptionUtil; -import com.linkedin.alpini.base.misc.Time; -import com.linkedin.alpini.base.monitoring.CallCompletion; -import com.linkedin.alpini.base.monitoring.CallTracker; -import com.linkedin.alpini.base.monitoring.NullCallTracker; -import com.linkedin.alpini.consts.QOS; -import com.linkedin.alpini.netty4.handlers.Http2PingSendHandler; -import com.linkedin.alpini.netty4.misc.ExceptionWithResponseStatus; -import com.linkedin.alpini.netty4.misc.Futures; -import com.linkedin.alpini.netty4.misc.Http2Utils; -import com.linkedin.alpini.netty4.misc.LocalThreadEventLoopGroup; -import com.linkedin.alpini.netty4.misc.SingleThreadEventLoopGroupSupplier; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.EventLoop; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.MultithreadEventLoopGroup; -import io.netty.channel.SingleThreadEventLoop; -import io.netty.channel.group.ChannelGroup; -import io.netty.channel.pool.ChannelPool; -import io.netty.channel.pool.ChannelPoolHandler; -import io.netty.handler.codec.http.HttpResponseStatus; -import io.netty.handler.codec.http2.Http2StreamChannel; -import io.netty.util.AttributeKey; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.FutureListener; -import io.netty.util.concurrent.GenericFutureListener; -import io.netty.util.concurrent.ImmediateEventExecutor; -import io.netty.util.concurrent.Promise; -import io.netty.util.concurrent.ScheduledFuture; -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.net.UnknownHostException; -import java.util.Collection; -import java.util.Collections; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.Map; -import java.util.Objects; -import java.util.Queue; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionException; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedDeque; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.CopyOnWriteArraySet; -import java.util.concurrent.Executor; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.ThreadLocalRandom; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.LongAdder; -import java.util.function.BooleanSupplier; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.IntSupplier; -import java.util.function.Supplier; -import javax.annotation.Nonnegative; -import javax.annotation.Nonnull; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** - * An implementation of a {@link ChannelPoolManager}. - * - * @author acurtis on 3/29/17. - */ -public class ChannelPoolManagerImpl implements ChannelPoolManager { - private static final ImmediateEventExecutor IMMEDIATE = ImmediateEventExecutor.INSTANCE; - private static final Future COMPLETED_VOID_FUTURE = IMMEDIATE.newSucceededFuture(null); - - private static final QOS[] QOS_HIGH_NORMAL_LOW = { QOS.HIGH, QOS.NORMAL, QOS.LOW }; - private static final QOS[] QOS_NORMAL_HIGH_LOW = { QOS.NORMAL, QOS.HIGH, QOS.LOW }; - private static final QOS[] QOS_LOW_HIGH_NORMAL = { QOS.LOW, QOS.HIGH, QOS.NORMAL }; - public static final String DEFAULT_DB_QUEUE = "default"; - - private static final Exception TOO_MANY_REQUESTS_EXCEPTION = ExceptionUtil.withoutStackTrace( - new ExceptionWithResponseStatus(HttpResponseStatus.TOO_MANY_REQUESTS, "Too many requests in queue")); - private static final Exception UNABLE_TO_ENQUEUE_REQUEST_EXCEPTION = ExceptionUtil.withoutStackTrace( - new ExceptionWithResponseStatus(HttpResponseStatus.TOO_MANY_REQUESTS, "Unable to enqueue request")); - private static final Exception POOL_CLOSED_EXCEPTION = ExceptionUtil.withoutStackTrace( - new ExceptionWithResponseStatus(HttpResponseStatus.SERVICE_UNAVAILABLE, "Connection pool closed")); - - private final Logger _log = LogManager.getLogger(getClass()); - - private final AttributeKey _ownerKey = AttributeKey.valueOf(getClass(), "ownerKey:" + toString()); - private final AttributeKey> _busyKey = - AttributeKey.valueOf(getClass(), "busyKey:" + toString()); - - private final SingleThreadEventLoopGroupSupplier _localThreadGroup; - private final ChannelPoolFactory _channelPoolFactory; - private final ChannelPoolResolver _channelPoolResolver; - private final ConcurrentMap _pools = new ConcurrentHashMap<>(); - private final IntSupplier _eventLoopConcurrency; - private final EventLoopGroup _workerEventLoopGroup; - private final Consumer _runInEveryThread; - - private final int _maxWaitersPerPool; - - private final BooleanSupplier _enableFairScheduling = () -> true; - private final BooleanSupplier _enableDeferredExecution = () -> false; - - /** Use a named thread factory for the handling channel released */ - private static final ThreadFactory CHANNEL_RELEASED_FACTORY = new NamedThreadFactory("channel-released"); - - /** To reduce contention in the worker queue, we have seperate worker queues for each io worker */ - private static final ThreadLocal CHANNEL_RELEASED_EXECUTOR = - ThreadLocal.withInitial(() -> Executors.newSingleThreadExecutor(CHANNEL_RELEASED_FACTORY)); - - // Global Pool - private boolean _useH2GlobalPool = false; - private boolean _createConnectionsOnWorkerGroup = false; - private boolean _enableSimpleAcquire = false; - - // Http2 ping - private ScheduledFuture _periodicPing; - private int _pingIntervalSeconds; - - public ChannelPoolManagerImpl( - @Nonnull E eventLoopGroup, - @Nonnull ChannelPoolFactory channelPoolFactory, - @Nonnull ChannelPoolResolver channelPoolResolver, - @Nonnegative int maxWaitersPerPool) { - _localThreadGroup = new LocalThreadEventLoopGroup<>(Objects.requireNonNull(eventLoopGroup, "eventLoopGroup")); - _channelPoolFactory = Objects.requireNonNull(channelPoolFactory, "channelPoolFactory"); - _channelPoolResolver = Objects.requireNonNull(channelPoolResolver, "channelPoolResolver"); - _workerEventLoopGroup = eventLoopGroup; - _eventLoopConcurrency = () -> _useH2GlobalPool ? 1 : eventLoopGroup.executorCount(); - _maxWaitersPerPool = maxWaitersPerPool; - _runInEveryThread = - command -> eventLoopGroup.iterator().forEachRemaining(eventExecutor -> eventExecutor.execute(command)); - } - - public ChannelPoolManagerImpl( - @Nonnull E eventLoopGroup, - @Nonnull ChannelPoolFactory channelPoolFactory, - @Nonnull ChannelPoolResolver channelPoolResolver, - @Nonnegative int maxWaitersPerPool, - boolean useH2GlobalPool, - boolean createConnectionsOnWorkerGroup, - boolean enableSimpleAcquire) { - this( - eventLoopGroup, - channelPoolFactory, - channelPoolResolver, - maxWaitersPerPool, - useH2GlobalPool, - createConnectionsOnWorkerGroup, - enableSimpleAcquire, - 0); - } - - public ChannelPoolManagerImpl( - @Nonnull E eventLoopGroup, - @Nonnull ChannelPoolFactory channelPoolFactory, - @Nonnull ChannelPoolResolver channelPoolResolver, - @Nonnegative int maxWaitersPerPool, - boolean useH2GlobalPool, - boolean createConnectionsOnWorkerGroup, - boolean enableSimpleAcquire, - int pingIntervalSeconds) { - this(eventLoopGroup, channelPoolFactory, channelPoolResolver, maxWaitersPerPool); - this._useH2GlobalPool = useH2GlobalPool; - this._createConnectionsOnWorkerGroup = createConnectionsOnWorkerGroup; - this._enableSimpleAcquire = enableSimpleAcquire; - this._pingIntervalSeconds = pingIntervalSeconds; - this.updateChannelPoolFactoryWithHttp2PingEnabled(); - } - - @Deprecated - @Override - public int executorCount() { - return subpoolCount(); - } - - private void updateChannelPoolFactoryWithHttp2PingEnabled() { - if (enablePeriodicPing()) { - Function http2PingSendHandlerFn = channel -> { - Pool pool = FixedChannelPoolFactory.getChannelPoolHandler(channel); - return pool != null ? pool.getHttp2PingSendHandler() : null; - }; - _channelPoolFactory.setHttp2PingSendHandlerFunction(http2PingSendHandlerFn); - } - } - - public synchronized void startPeriodicPing() { - if (enablePeriodicPing() && _periodicPing == null) { - _periodicPing = - _workerEventLoopGroup.scheduleAtFixedRate(this::sendPing, 0, _pingIntervalSeconds, TimeUnit.SECONDS); - } - } - - public void sendPing() { - getPools().forEach(pool -> _workerEventLoopGroup.execute(pool::sendPing)); - } - - public boolean enablePeriodicPing() { - return _pingIntervalSeconds > 0; - } - - public Collection getPools() { - return _pools.values(); - } - - public synchronized void stopPeriodicPing() { - if (_periodicPing != null) { - _periodicPing.cancel(false); - _periodicPing = null; - } - } - - @Override - public int subpoolCount() { - return _eventLoopConcurrency.getAsInt(); - } - - @Nonnull - protected CallTracker createHostAcquireCallTracker() { - return NullCallTracker.INSTANCE; - } - - @Nonnull - protected CallTracker createHostBusyCallTracker() { - return NullCallTracker.INSTANCE; - } - - @Nonnull - @Deprecated - protected CallTracker createQueueAcquireCallTracker() { - return NullCallTracker.INSTANCE; - } - - @Nonnull - @Deprecated - protected CallTracker createQueueBusyCallTracker() { - return NullCallTracker.INSTANCE; - } - - private class Pool implements ChannelPoolHandler { - final String _hostAndPort; - final InetSocketAddress _address; - final Set _all = new CopyOnWriteArraySet<>(); - // Single Queue for all threads. - private final ThreadQueue _globalThreadQueue; - private final ThreadLocal _local; - private final LongAdder _waitingCount = new LongAdder(); - private final Http2PingHelper _http2PingHelper; - private Iterator _channelPoolIterator = Collections.emptyIterator(); - private boolean _isClosing = false; - - private final ChannelFutureListener _closeCountListener = future -> { - channelClosed(future.channel()); - }; - - private final CallTracker _acquireCallTracker; - private final CallTracker _busyCallTracker; - - Pool(InetSocketAddress address) { - assert address.isUnresolved(); - _address = address; - _hostAndPort = address.getHostString() + ":" + address.getPort(); - _acquireCallTracker = createHostAcquireCallTracker(); - _busyCallTracker = createHostBusyCallTracker(); - if (enablePeriodicPing()) { - _http2PingHelper = new Http2PingHelper(); - } else { - _http2PingHelper = null; - } - if (_useH2GlobalPool) { - _globalThreadQueue = newThreadQueue(); - _local = null; - } else { - _local = ThreadLocal.withInitial(this::newThreadQueue); - _globalThreadQueue = null; - } - } - - private void initialize() { - if (!_useH2GlobalPool) { - ChannelPool channelPool = _local.get()._pool; - channelPool.acquire().addListener((Future future) -> { - if (future.isSuccess()) { - channelPool.release(future.getNow()); - } - }); - } - } - - private Channel getHttp2ChannelToPingFromChannelPool() { - if (!isHealthy() || isClosing()) { - return null; - } - if (_useH2GlobalPool) { - return _globalThreadQueue.getHttp2ChannelToPingFromChannelGroup(); - } - synchronized (this) { - if (!_channelPoolIterator.hasNext()) { - _channelPoolIterator = _all.iterator(); - } - return _channelPoolIterator.hasNext() - ? _channelPoolIterator.next().getHttp2ChannelToPingFromChannelGroup() - : null; - } - } - - private void sendPing() { - if (_http2PingHelper != null) { - Channel channel = getHttp2ChannelToPingFromChannelPool(); - if (channel != null && channel.isActive()) { - _http2PingHelper.sendPing(channel); - } - } - } - - public Http2PingSendHandler getHttp2PingSendHandler() { - return _http2PingHelper == null ? null : _http2PingHelper.getHttp2PingSendHandler(); - } - - Future close() { - _isClosing = true; - Future[] futures = _all.stream().map(ThreadQueue::close).toArray(Future[]::new); - return Futures.allOf(futures); - } - - private ThreadQueue newThreadQueue() { - ThreadQueue pool = new ThreadQueue(_address, this); - _all.add(pool); - return pool; - } - - private ThreadQueue get() { - return _useH2GlobalPool ? _globalThreadQueue : _local.get(); - } - - private void channelClosed(Channel ch) { - _log.debug("channelClosed({}/{})", ch.id(), ch.eventLoop()); - channelReleased(ch); - } - - void incrementWait() { - _waitingCount.increment(); - } - - void incrementDone() { - _waitingCount.decrement(); - } - - @Override - public void channelReleased(Channel ch) { - // TODO: Uncomment after we fix logging - // _log.debug("channelReleased({}/{})", ch.id(), ch.eventLoop()); - complete(Time.nanoTime(), ch.attr(_busyKey).getAndSet(null)); // atomic - } - - void complete(long now, Supplier callCompletion) { - if (callCompletion != null) { - // Offload the call graphs to a different thread - CHANNEL_RELEASED_EXECUTOR.get().execute(() -> callCompletion.get().close(now)); - } - } - - @Override - public void channelAcquired(Channel ch) { - // _log.debug("channelAcquired({}/{})", ch.id(), ch.eventLoop()); - } - - @Override - public void channelCreated(Channel ch) { - if (!(ch instanceof Http2StreamChannel)) { - _log.debug("channelCreated({}/{})", ch.id(), ch.eventLoop()); - ch.closeFuture().addListener(_closeCountListener); - } - } - - public SocketAddress remoteAddress() { - return _address; - } - - public boolean isHealthy() { - for (ThreadQueue q: _all.toArray(new ThreadQueue[0])) { - // The concurrentHashMap can't have a null q. - if (!q.isHealthy()) { - return false; - } - } - return true; - } - - public boolean isClosing() { - return _isClosing; - } - - public int waitingCount() { - return _waitingCount.intValue(); - } - - @Nonnull - public CallTracker acquireCallTracker() { - return _acquireCallTracker; - } - - @Nonnull - public CallTracker busyCallTracker() { - return _busyCallTracker; - } - } - - /** - * To ensure fairness of scheduling connections to all the DB's. ThreadQueue maintains a circular buffer of DB queues (PoolQueue). - * - * (DB3) PQ --> PQ (DB1) - * ^ ^ - * | | - * PQ --> PQ (DB2) - * / - * TQ (One per ioWorker / in case of a global pool - one per SN) - * - * ThreadQueue - Maintains a map - * PoolQueue - Maintains a map > - */ - private class ThreadQueue { - final ManagedChannelPool _pool; - final Map _perDBPoolQueue = _useH2GlobalPool ? new ConcurrentHashMap<>() : new HashMap<>(); - Supplier> _close; - private PoolQueue _head; - private AtomicInteger _inFlight = new AtomicInteger(); - private final String _threadName; - private Iterator _channelIterator = Collections.emptyIterator(); - - ThreadQueue(InetSocketAddress address, Pool pool) { - _threadName = Thread.currentThread().getName(); - EventLoopGroup eventLoopGroup = Objects.requireNonNull(localThreadGroup().syncUninterruptibly().getNow()); - EventLoop eventLoop = eventLoopGroup.next(); - /* - When using a H2 global pool, using BalancedEventLoopGroup ensures the connections are distributed across - all the worker threads evenly. - */ - _pool = _channelPoolFactory.construct( - ChannelPoolManagerImpl.this, - pool, - _createConnectionsOnWorkerGroup ? _workerEventLoopGroup : eventLoopGroup, - Objects.requireNonNull(address)); - - Supplier> closeNow = Lazy.of(() -> { - _pool.close(); - return _pool.closeFuture(); - }); - - _close = Lazy.of(() -> { - Promise future = IMMEDIATE.newPromise(); - CompletableFuture.supplyAsync(closeNow, eventLoop).whenComplete(Futures.completeFuture(future)); - return future; - }); - - eventLoop.terminationFuture().addListener(future -> { - _close = () -> COMPLETED_VOID_FUTURE; - closeNow.get(); - }); - } - - boolean isHealthy() { - return _pool.isHealthy(); - } - - private Channel getHttp2ChannelToPingFromChannelGroup() { - if (!_pool.isHealthy() || _pool.isClosing()) { - return null; - } - synchronized (this) { - if (!_channelIterator.hasNext()) { - ChannelGroup channelGroup = _pool.getHttp2ChannelGroup(); - if (channelGroup == null) { - return null; - } - _channelIterator = channelGroup.iterator(); - } - return _channelIterator.hasNext() ? _channelIterator.next() : null; - } - } - - public boolean isClosing() { - return _pool.isClosing(); - } - - Future close() { - return _close.get(); - } - - PoolQueue get(String queueName) { - return _perDBPoolQueue.computeIfAbsent(queueName, this::newPoolQueue); - } - - PoolQueue newPoolQueue(String queueName) { - return new PoolQueue(this, _pool, _useH2GlobalPool); - } - - // Randomly chooses a DB from the circular buffer and assigns the connection to a promise in the queue. - void dispatch(Pool pool, Future future) { - PoolQueue oldHead = _head; - - if (future.isSuccess()) { - future.getNow().attr(_ownerKey).setIfAbsent(_pool); - } - - do { // Loop through the circular buffer of DB's - PoolQueue head = _head; - _head = _head._next; - for (QOS qos: qosArray()) { - Queue queue = head._qosQueueEnumMap.get(qos); - PromiseHolder promise; - while (queue != null && (promise = queue.poll()) != null) { // SUPPRESS CHECKSTYLE InnerAssignment - head.incrementDone(); - pool.incrementDone(); - if (future.isSuccess()) { - if (promise.trySuccess(future.getNow())) { - return; - } - } else if (promise.tryFailure(mapException(future.cause()))) { - return; - } - // loop to try the next promise - } - // loop to try the next QOS - } - // loop to try the next DB - } while (oldHead != _head); // Loops through the circular buffer once - - if (future.isSuccess()) { - _log.debug("Returning connection immediately to pool: {}", future.getNow().id()); - _pool.release(future.getNow()); - } else { - _log.debug("Failed to propagate exception", future.cause()); - } - } - - void clearDoneWaiters(Pool pool) { - _perDBPoolQueue.values() - .forEach(poolQueue -> poolQueue._qosQueueEnumMap.values().forEach(queue -> queue.removeIf(promise -> { - if (promise.isDone()) { - poolQueue.incrementDone(); - pool.incrementDone(); - return true; - } - return false; - }))); - } - } - - /** - * This class holds the promise which is returned to the caller. - * When the channel is successfully transferred to the caller, we start busy call tracker - * at the same time. - */ - private final class PromiseHolder implements Runnable { - private final Promise _promise; - private final Supplier _completion; - private final Pool _pool; - private long _completionTime; - private Supplier _busyCallCompletion; - - private PromiseHolder(@Nonnull Promise promise, @Nonnull Supplier completion, Pool pool) { - _promise = promise; - _completion = Lazy.of(completion); - _pool = pool; - } - - boolean isDone() { - return _promise.isDone(); - } - - private CallCompletion completion() { - return _completion.get() != null ? _completion.get() : CallTracker.nullTracker().startCall(); - } - - Future getFuture() { - completion(); - if (!_promise.isSuccess()) { - /** If the promise is killed, before it can get a connection. This usually happens, if the request timeout - before it can get a connection. */ - _promise.addListener(f -> { - if (!f.isSuccess()) { - closeCompletionWithError(Time.nanoTime(), f.cause()); - } - }); - } - return _promise; - } - - private boolean closeCompletionWithError(long now, Throwable ex) { - completion().closeWithError(now, ex); - return true; - } - - public void run() { - _busyCallCompletion.get(); - completion().close(_completionTime); - } - - boolean trySuccess(Channel channel) { - if (isDone()) { - return false; - } - long now = Time.nanoTime(); - Supplier supplier = Lazy.of(() -> _pool.busyCallTracker().startCall(now)); - _pool.complete(now, channel.attr(_busyKey).getAndSet(supplier)); - if (_promise.trySuccess(channel)) { - _completionTime = now; - _busyCallCompletion = supplier; - CHANNEL_RELEASED_EXECUTOR.get().execute(this); // calls run() - return true; - } else { - channel.attr(_busyKey).set(null); - return false; - } - } - - boolean tryFailure(Throwable ex) { - long now = Time.nanoTime(); - return _promise.tryFailure(ex) && closeCompletionWithError(now, ex); - } - } - - /** - * Instead of having a final reference to a LongAdder for waitCount, we simply make the PoolQueue - * class extend LongAdder and save on an object reference. - */ - private static class PoolQueue extends LongAdder { - final ChannelPool _pool; - final EnumMap> _qosQueueEnumMap = new EnumMap<>(QOS.class); - boolean _useH2GlobalPool; - - PoolQueue _prev = this; - PoolQueue _next = this; - - private PoolQueue(ThreadQueue threadPool, ChannelPool pool, boolean useH2GlobalPool) { - this(threadPool, pool); - _useH2GlobalPool = useH2GlobalPool; - } - - private PoolQueue(ThreadQueue threadPool, ChannelPool pool) { - _pool = pool; - - if (threadPool._head != null) { - _prev = threadPool._head; - _next = _prev._next; - _prev._next = this; - _next._prev = this; - } - threadPool._head = this; - reset(); - } - - boolean add(QOS qos, PromiseHolder promise) { - return _qosQueueEnumMap.computeIfAbsent(qos, this::newQueue).add(promise); - } - - private Queue newQueue(QOS qos) { - return _useH2GlobalPool ? new ConcurrentLinkedDeque<>() : new LinkedList<>(); - } - - void incrementWait() { - // waitCount is number of waiters for a IoWorker per DB - increment(); - } - - void incrementDone() { - // waitCount is number of waiters for a IoWorker per DB - decrement(); - } - - int waitingCount() { - return intValue(); - } - } - - @Nonnull - private QOS[] qosArray() { - // To ensure fairness for QOS LOW - ThreadLocalRandom random = ThreadLocalRandom.current(); - int percent = random.nextInt(100); - - if (percent < 80) { - return QOS_HIGH_NORMAL_LOW; - } else if (percent < 95) { - return QOS_NORMAL_HIGH_LOW; - } else { - return QOS_LOW_HIGH_NORMAL; - } - } - - @Nonnull - protected InetSocketAddress createUnresolved(@Nonnull String hostAndPort) { - int pos = hostAndPort.indexOf(':'); - if (pos == -1) { - throw new IllegalArgumentException("Bad hostname. Should be host:port."); - } - - String host = hostAndPort.substring(0, pos); - int port = Integer.parseInt(hostAndPort.substring(pos + 1)); - return InetSocketAddress.createUnresolved(host, port); - } - - @Nonnull - protected InetSocketAddress createUnresolved(@Nonnull InetSocketAddress inetSocketAddress) { - if (inetSocketAddress.isUnresolved()) { - return inetSocketAddress; - } else { - return InetSocketAddress.createUnresolved(inetSocketAddress.getHostString(), inetSocketAddress.getPort()); - } - } - - @Override - @Nonnull - public Future close(@Nonnull String hostName) { - return close0(hostName); - } - - private Future close0(@Nonnull String hostName) { - Pool pool = _pools.remove(hostName); - if (pool == null) { - return COMPLETED_VOID_FUTURE; - } else { - return pool.close(); - } - } - - protected Future localThreadGroup() { - return _localThreadGroup.singleThreadGroup(); - } - - protected Future localThreadGroup(@Nonnull EventLoop eventLoop) { - return _localThreadGroup.singleThreadGroup(eventLoop); - } - - @Override - @Nonnull - public Future acquire(@Nonnull String hostName, @Nonnull String queueName, @Nonnull QOS qos) { - long startTime = Time.nanoTime(); - Future group = localThreadGroup(); - return acquire( - startTime, - hostName, - Objects.requireNonNull(queueName, "queueName"), - Objects.requireNonNull(qos, "qos"), - group, - IMMEDIATE.newPromise()); - } - - @Override - @Nonnull - public Future acquire( - @Nonnull EventLoop eventLoop, - @Nonnull String hostName, - @Nonnull String queueName, - @Nonnull QOS qos) { - long startTime = Time.nanoTime(); - Future group = localThreadGroup(eventLoop); - return acquire( - startTime, - hostName, - Objects.requireNonNull(queueName, "queueName"), - Objects.requireNonNull(qos, "qos"), - group, - eventLoop.newPromise()); - } - - private Future acquire( - long startTime, - String hostName, - String queueName, - QOS qos, - Future group, - Promise promise) { - - // Check if the pool already exists - Pool pool = _pools.get(hostName); - if (pool != null) { - return acquireWithHostName(startTime, hostName, pool, queueName, qos, group, promise); - } - - // Pool doesn't exist, resolve the host to IP and create the pool - InetSocketAddress unresolved = createUnresolved(hostName); - - Future addressFuture = _channelPoolResolver - .resolve(unresolved, group.isSuccess() ? group.getNow().next().newPromise() : IMMEDIATE.newPromise()); - - if (addressFuture.isSuccess()) { - return acquireResolved(startTime, hostName, addressFuture.getNow(), queueName, qos, group, promise); - } else { - addressFuture.addListener((Future future) -> { - if (future.isSuccess()) { - acquireResolved(startTime, hostName, future.getNow(), queueName, qos, group, promise); - } else { - _log.log( - promise.tryFailure(future.cause()) ? Level.DEBUG : Level.INFO, - "Unable to resolve {}", - unresolved, - future.cause()); - } - }); - return promise; - } - } - - private Future acquireWithHostName( - long startTime, - String hostName, - Pool pool, - String queueName, - QOS qos, - Future group, - Promise promise) { - - if (group.isSuccess()) { - return acquireResolved(startTime, pool, queueName, qos, group.getNow(), promise); - } else { - group.addListener((Future future) -> { - if (group.isSuccess()) { - acquireResolved(startTime, pool, queueName, qos, future.getNow(), promise); - } else { - pool._acquireCallTracker.trackCallWithError(Time.nanoTime() - startTime); - if (!promise.tryFailure(group.cause())) { - _log.debug("acquire failure {} {} {}", hostName, queueName, qos, group.cause()); - } - } - }); - return promise; - } - } - - private Future acquireResolved( - long startTime, - String hostName, - InetSocketAddress address, - String queueName, - QOS qos, - Future group, - Promise promise) { - - if (address.isUnresolved()) { - Exception exception = new UnknownHostException(address.getHostString()); - _log.log(promise.tryFailure(exception) ? Level.DEBUG : Level.INFO, "Unresolved hostname", exception); - return promise; - } - - Pool pool = CollectionUtil.computeIfAbsent( - _pools, - hostName, - (k) -> new Pool(createUnresolved(address)), - (key, newPool) -> _runInEveryThread.accept(newPool::initialize)); - - if (group.isSuccess()) { - return acquireResolved(startTime, pool, queueName, qos, group.getNow(), promise); - } else { - group.addListener((Future future) -> { - if (group.isSuccess()) { - acquireResolved(startTime, pool, queueName, qos, future.getNow(), promise); - } else { - pool._acquireCallTracker.trackCallWithError(Time.nanoTime() - startTime); - if (!promise.tryFailure(group.cause())) { - _log.debug("acquire failure {} {} {}", address.getHostString(), queueName, qos, group.cause()); - } - } - }); - return promise; - } - } - - private Future acquireResolved( - long startTime, - Pool pool, - String queueName, - QOS qos, - EventLoopGroup group, - Promise promise) { - if (promise.isDone()) { - _log.debug("promise completed before acquire"); - return promise; - } - - EventLoop loop = group.next(); - - if (loop.inEventLoop()) { - return acquireInEventLoop(startTime, loop, pool, queueName, qos, promise); - } else { - loop.execute(() -> acquireInEventLoop(startTime, loop, pool, queueName, qos, promise)); - return promise; - } - } - - private Future acquireInEventLoop( - long startTime, - EventLoop loop, - Pool pool, - String queueName, - QOS qos, - Promise promise) { - if (promise.isDone()) { - _log.debug("promise completed before acquire"); - return promise; - } - - // Get thread local pool or Global Pool for the SN - ThreadQueue threadQueue = pool.get(); - // Get the queue for the DB - PoolQueue queue = threadQueue.get(_enableFairScheduling.getAsBoolean() ? queueName : DEFAULT_DB_QUEUE); - - pool.incrementWait(); - queue.incrementWait(); - - PromiseHolder promiseHolder = - new PromiseHolder(promise, () -> pool.acquireCallTracker().startCall(startTime), pool); - - if (threadQueue._inFlight.get() > _maxWaitersPerPool / 2) { - threadQueue.clearDoneWaiters(pool); - } - - /* - Simple acquire, avoids all the Pool and Thread Queue complexities when acquiring a connection. - */ - if (_useH2GlobalPool && _enableSimpleAcquire) { - Promise acquirePromise = IMMEDIATE.newPromise(); - threadQueue._pool.acquire(acquirePromise); - acquirePromise.addListener((GenericFutureListener>) channelFuture -> { - pool.incrementDone(); - queue.incrementDone(); - if (channelFuture.isSuccess()) { - channelFuture.getNow().attr(_ownerKey).setIfAbsent(threadQueue._pool); - promiseHolder.trySuccess(channelFuture.getNow()); - } else { - promiseHolder.tryFailure(channelFuture.cause()); - } - }); - return promiseHolder.getFuture(); - } - - // A request to acquire a connection is always added to a queue of the corresponding DB. - if (threadQueue._inFlight.get() < _maxWaitersPerPool && queue.add(qos, promiseHolder)) { - class Listener implements FutureListener, Runnable { - private final Executor deferred = _enableDeferredExecution.getAsBoolean() - ? ((SingleThreadEventLoop) loop)::executeAfterEventLoopIteration - : loop::execute; - - public void run() { - Promise acquirePromise = loop.newPromise(); - acquirePromise.addListener(this); - deferred.execute(() -> threadQueue._pool.acquire(acquirePromise)); - } - - @Override - public void operationComplete(Future future) throws Exception { - decrementInFlightCount(threadQueue); - if (!future.isSuccess() && pool.waitingCount() > 0) { - if (isReschedulableError(future.cause())) { - _log.debug("Retrying because {}", future.cause().getMessage()); - threadQueue.clearDoneWaiters(pool); - int waiters = threadQueue._perDBPoolQueue.values().stream().mapToInt(PoolQueue::waitingCount).sum(); - // Reschedule only if the waiters are greater than the number of requests inflight. - if (threadQueue._inFlight.get() < waiters) { - // small back-off - incrementInFlightCount(threadQueue); - loop.schedule(this, 100, TimeUnit.MICROSECONDS); - } - return; - } - _log.debug("Exception in acquire", future.cause()); - } - // when a connection is available, the dispatch assigns the connection to random DB. - threadQueue.dispatch(pool, future); - } - } - incrementInFlightCount(threadQueue); - new Listener().run(); - } else { - pool.incrementDone(); - queue.incrementDone(); - - Exception exception = UNABLE_TO_ENQUEUE_REQUEST_EXCEPTION; - _log.warn( - "Unable to acquire connection for SN {}, db {}, inflight {}, waitingCount {}, maxWaiterPerPool {}, ioWorker {}", - pool._hostAndPort, - queueName, - threadQueue._inFlight, - queue.waitingCount(), - _maxWaitersPerPool, - Thread.currentThread().getName()); - promiseHolder.tryFailure(exception); - } - return promiseHolder.getFuture(); - } - - private static boolean isReschedulableError(Throwable t) { - return t instanceof TimeoutException || Http2Utils.isTooManyActiveStreamsError(t); - } - - private void incrementInFlightCount(ThreadQueue threadQueue) { - threadQueue._inFlight.incrementAndGet(); - } - - private void decrementInFlightCount(ThreadQueue threadQueue) { - threadQueue._inFlight.decrementAndGet(); - } - - static Throwable mapException(Throwable ex) { - while ((ex instanceof CompletionException || ex instanceof RuntimeException) && ex.getCause() != null - && ex.getCause() != ex) { - ex = ex.getCause(); - } - if (ex instanceof IllegalStateException && String.valueOf(ex.getMessage()).startsWith("Too many")) { - return TOO_MANY_REQUESTS_EXCEPTION; - } - if (ex instanceof IllegalStateException && String.valueOf(ex.getMessage()).endsWith("was closed")) { - return POOL_CLOSED_EXCEPTION; - } - return ex; - } - - @Override - @Nonnull - public Future release(@Nonnull Channel channel) { - ChannelPool pool = Objects.requireNonNull(channel.attr(_ownerKey).get()); - EventLoop eventLoop = channel.eventLoop(); - Promise promise = eventLoop.newPromise(); - if (eventLoop.inEventLoop()) { - return release0(pool, channel, promise); - } else { - eventLoop.submit(() -> release0(pool, channel, promise)); - } - return promise; - } - - private Future release0(ChannelPool pool, Channel channel, Promise promise) { - try { - return pool.release(channel, promise); - } catch (Exception ex) { - if (!promise.tryFailure(ex)) { - _log.warn("Exception in release:", ex); - } - return promise; - } - } - - /** - * Used for unit-test verification - */ - ScheduledFuture getPeriodicPingScheduledFuture() { - return _periodicPing; - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/ChannelPoolResolver.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/ChannelPoolResolver.java deleted file mode 100644 index 0d5b5470153..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/ChannelPoolResolver.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.Promise; -import java.net.InetSocketAddress; -import javax.annotation.CheckReturnValue; -import javax.annotation.Nonnull; - - -/** - * A simple interface for an asynchronous {@link InetSocketAddress} resolver. - * - * @author acurtis on 3/29/17. - */ -public interface ChannelPoolResolver { - /** - * Asynchronously resolves the supplied {@link InetSocketAddress} and completes the promise when done. - * @param address address to resolve. - * @param promise promise to complete. - * @return promise - */ - @CheckReturnValue - @Nonnull - Future resolve(@Nonnull InetSocketAddress address, @Nonnull Promise promise); -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/ChannelPoolWithStats.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/ChannelPoolWithStats.java deleted file mode 100644 index e19be119fd7..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/ChannelPoolWithStats.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import io.netty.channel.pool.ChannelPool; - - -/** - * A simple interface which extends ChannelPool to expose various stats. - */ -public interface ChannelPoolWithStats extends ChannelPool { - String name(); - - int getMaxConnections(); - - int getMaxPendingAcquires(); - - int getAcquiredChannelCount(); - - int getPendingAcquireCount(); - - boolean isClosed(); -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/EspressoFixedChannelPool.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/EspressoFixedChannelPool.java deleted file mode 100644 index 6de0f06e2d9..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/EspressoFixedChannelPool.java +++ /dev/null @@ -1,554 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import io.netty.bootstrap.Bootstrap; -import io.netty.channel.Channel; -import io.netty.channel.pool.ChannelHealthChecker; -import io.netty.channel.pool.ChannelPoolHandler; -import io.netty.util.concurrent.EventExecutor; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.FutureListener; -import io.netty.util.concurrent.GlobalEventExecutor; -import io.netty.util.concurrent.Promise; -import io.netty.util.internal.ObjectUtil; -import java.nio.channels.ClosedChannelException; -import java.util.ArrayDeque; -import java.util.Queue; -import java.util.concurrent.Callable; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicInteger; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** - * Forked from Netty's FixedChannelPool - * - * {ChannelPool} implementation that takes another {ChannelPool} implementation and enforce a maximum - * number of concurrent connections. - */ -public class EspressoFixedChannelPool extends EspressoSimpleChannelPool implements ChannelPoolWithStats { - private static final Logger LOG = LogManager.getLogger(FixedChannelPoolImpl.class); - - private final String _name; - private final EventExecutor executor; - private final long acquireTimeoutNanos; - private final Runnable timeoutTask; - - // There is no need to worry about synchronization as everything that modified the queue or counts is done - // by the above EventExecutor. - private final Queue pendingAcquireQueue = new ArrayDeque(); - private final int maxConnections; - private final int maxPendingAcquires; - private final AtomicInteger acquiredChannelCount = new AtomicInteger(); - private int pendingAcquireCount; - volatile private boolean closed; - - public boolean isPoolClosed() { - return closed; - } - - /** - * Creates a new instance using the {@link ChannelHealthChecker#ACTIVE}. - * - * @param bootstrap the {@link Bootstrap} that is used for connections - * @param handler the {@link ChannelPoolHandler} that will be notified for the different pool actions - * @param maxConnections the number of maximal active connections, once this is reached new tries to acquire - * a {@link Channel} will be delayed until a connection is returned to the pool again. - */ - public EspressoFixedChannelPool(Bootstrap bootstrap, ChannelPoolHandler handler, int maxConnections) { - this(bootstrap, handler, maxConnections, Integer.MAX_VALUE); - } - - /** - * Creates a new instance using the {@link ChannelHealthChecker#ACTIVE}. - * - * @param bootstrap the {@link Bootstrap} that is used for connections - * @param handler the {@link ChannelPoolHandler} that will be notified for the different pool actions - * @param maxConnections the number of maximal active connections, once this is reached new tries to - * acquire a {@link Channel} will be delayed until a connection is returned to the - * pool again. - * @param maxPendingAcquires the maximum number of pending acquires. Once this is exceed acquire tries will - * be failed. - */ - public EspressoFixedChannelPool( - Bootstrap bootstrap, - ChannelPoolHandler handler, - int maxConnections, - int maxPendingAcquires) { - this(bootstrap, handler, ChannelHealthChecker.ACTIVE, null, -1, maxConnections, maxPendingAcquires); - } - - /** - * Creates a new instance. - * - * @param bootstrap the {@link Bootstrap} that is used for connections - * @param handler the {@link ChannelPoolHandler} that will be notified for the different pool actions - * @param healthCheck the {@link ChannelHealthChecker} that will be used to check if a {@link Channel} is - * still healthy when obtain from the {ChannelPool} - * @param action the {@link io.netty.channel.pool.FixedChannelPool.AcquireTimeoutAction} to use or {@code null} if non should be used. - * In this case {@param acquireTimeoutMillis} must be {@code -1}. - * @param acquireTimeoutMillis the time (in milliseconds) after which an pending acquire must complete or - * the {@link io.netty.channel.pool.FixedChannelPool.AcquireTimeoutAction} takes place. - * @param maxConnections the number of maximal active connections, once this is reached new tries to - * acquire a {@link Channel} will be delayed until a connection is returned to the - * pool again. - * @param maxPendingAcquires the maximum number of pending acquires. Once this is exceed acquire tries will - * be failed. - */ - public EspressoFixedChannelPool( - Bootstrap bootstrap, - ChannelPoolHandler handler, - ChannelHealthChecker healthCheck, - io.netty.channel.pool.FixedChannelPool.AcquireTimeoutAction action, - final long acquireTimeoutMillis, - int maxConnections, - int maxPendingAcquires) { - this(bootstrap, handler, healthCheck, action, acquireTimeoutMillis, maxConnections, maxPendingAcquires, true); - } - - /** - * Creates a new instance. - * - * @param bootstrap the {@link Bootstrap} that is used for connections - * @param handler the {@link ChannelPoolHandler} that will be notified for the different pool actions - * @param healthCheck the {@link ChannelHealthChecker} that will be used to check if a {@link Channel} is - * still healthy when obtain from the {ChannelPool} - * @param action the {@link io.netty.channel.pool.FixedChannelPool.AcquireTimeoutAction} to use or {@code null} if non should be used. - * In this case {@literal acquireTimeoutMillis} must be {@code -1}. - * @param acquireTimeoutMillis the time (in milliseconds) after which an pending acquire must complete or - * the {@link io.netty.channel.pool.FixedChannelPool.AcquireTimeoutAction} takes place. - * @param maxConnections the number of maximal active connections, once this is reached new tries to - * acquire a {@link Channel} will be delayed until a connection is returned to the - * pool again. - * @param maxPendingAcquires the maximum number of pending acquires. Once this is exceed acquire tries will - * be failed. - * @param releaseHealthCheck will check channel health before offering back if this parameter set to - * {@code true}. - */ - public EspressoFixedChannelPool( - Bootstrap bootstrap, - ChannelPoolHandler handler, - ChannelHealthChecker healthCheck, - io.netty.channel.pool.FixedChannelPool.AcquireTimeoutAction action, - final long acquireTimeoutMillis, - int maxConnections, - int maxPendingAcquires, - final boolean releaseHealthCheck) { - this( - bootstrap, - handler, - healthCheck, - action, - acquireTimeoutMillis, - maxConnections, - maxPendingAcquires, - releaseHealthCheck, - true); - } - - /** - * Creates a new instance. - * - * @param bootstrap the {@link Bootstrap} that is used for connections - * @param handler the {@link ChannelPoolHandler} that will be notified for the different pool actions - * @param healthCheck the {@link ChannelHealthChecker} that will be used to check if a {@link Channel} is - * still healthy when obtain from the {ChannelPool} - * @param action the {@link io.netty.channel.pool.FixedChannelPool.AcquireTimeoutAction} to use or {@code null} if non should be used. - * In this case {@literal acquireTimeoutMillis} must be {@code -1}. - * @param acquireTimeoutMillis the time (in milliseconds) after which an pending acquire must complete or - * the {@link io.netty.channel.pool.FixedChannelPool.AcquireTimeoutAction} takes place. - * @param maxConnections the number of maximal active connections, once this is reached new tries to - * acquire a {@link Channel} will be delayed until a connection is returned to the - * pool again. - * @param maxPendingAcquires the maximum number of pending acquires. Once this is exceed acquire tries will - * be failed. - * @param releaseHealthCheck will check channel health before offering back if this parameter set to - * {@code true}. - * @param lastRecentUsed {@code true} {@link Channel} selection will be LIFO, if {@code false} FIFO. - */ - public EspressoFixedChannelPool( - Bootstrap bootstrap, - ChannelPoolHandler handler, - ChannelHealthChecker healthCheck, - io.netty.channel.pool.FixedChannelPool.AcquireTimeoutAction action, - final long acquireTimeoutMillis, - int maxConnections, - int maxPendingAcquires, - boolean releaseHealthCheck, - boolean lastRecentUsed) { - super(bootstrap, handler, healthCheck, releaseHealthCheck, lastRecentUsed); - if (maxConnections < 1) { - throw new IllegalArgumentException("maxConnections: " + maxConnections + " (expected: >= 1)"); - } - if (maxPendingAcquires < 1) { - throw new IllegalArgumentException("maxPendingAcquires: " + maxPendingAcquires + " (expected: >= 1)"); - } - if (action == null && acquireTimeoutMillis == -1) { - timeoutTask = null; - acquireTimeoutNanos = -1; - } else if (action == null && acquireTimeoutMillis != -1) { - throw new NullPointerException("action"); - } else if (action != null && acquireTimeoutMillis < 0) { - throw new IllegalArgumentException("acquireTimeoutMillis: " + acquireTimeoutMillis + " (expected: >= 0)"); - } else { - acquireTimeoutNanos = TimeUnit.MILLISECONDS.toNanos(acquireTimeoutMillis); - switch (action) { - case FAIL: - timeoutTask = new TimeoutTask() { - @Override - public void onTimeout(AcquireTask task) { - // Fail the promise as we timed out. - task.promise - .setFailure(new TimeoutException("Acquire operation took longer then configured maximum time") { - @Override - public synchronized Throwable fillInStackTrace() { - return this; - } - }); - } - }; - break; - case NEW: - timeoutTask = new TimeoutTask() { - @Override - public void onTimeout(AcquireTask task) { - // Increment the acquire count and delegate to super to actually acquire a Channel which will - // create a new connection. - task.acquired(); - - EspressoFixedChannelPool.super.acquire(task.promise); - } - }; - break; - default: - throw new Error(); - } - } - executor = bootstrap.config().group().next(); - _name = bootstrap.config().remoteAddress().toString(); - this.maxConnections = maxConnections; - this.maxPendingAcquires = maxPendingAcquires; - } - - @Override - public String name() { - return _name; - } - - /** Returns the number of acquired channels that this pool thinks it has. */ - public int acquiredChannelCount() { - return acquiredChannelCount.get(); - } - - public void incrementAcquiredChannelCount() { - acquiredChannelCount.incrementAndGet(); - } - - @Override - public Future acquire(final Promise promise) { - try { - if (executor.inEventLoop()) { - acquire0(promise); - } else { - executor.execute(new Runnable() { - @Override - public void run() { - acquire0(promise); - } - }); - } - } catch (Throwable cause) { - promise.setFailure(cause); - } - return promise; - } - - private void acquire0(final Promise promise) { - assert executor.inEventLoop(); - - if (closed) { - promise.setFailure(new IllegalStateException("FixedChannelPool was closed")); - return; - } - if (acquiredChannelCount() < maxConnections) { - assert acquiredChannelCount() >= 0; - - // We need to create a new promise as we need to ensure the AcquireListener runs in the correct - // EventLoop - Promise p = executor.newPromise(); - AcquireListener l = new AcquireListener(promise); - l.acquired(); - p.addListener(l); - super.acquire(p); - } else { - if (pendingAcquireCount >= maxPendingAcquires) { - tooManyOutstanding(promise); - } else { - AcquireTask task = new AcquireTask(promise); - if (pendingAcquireQueue.offer(task)) { - ++pendingAcquireCount; - - if (timeoutTask != null) { - task.timeoutFuture = executor.schedule(timeoutTask, acquireTimeoutNanos, TimeUnit.NANOSECONDS); - } - } else { - tooManyOutstanding(promise); - } - } - - assert pendingAcquireCount > 0; - } - } - - private void tooManyOutstanding(Promise promise) { - promise.setFailure(new IllegalStateException("Too many outstanding acquire operations")); - } - - @Override - public Future release(final Channel channel, final Promise promise) { - ObjectUtil.checkNotNull(promise, "promise"); - final Promise p = executor.newPromise(); - super.release(channel, p.addListener(new FutureListener() { - @Override - public void operationComplete(Future future) throws Exception { - assert executor.inEventLoop(); - - if (closed) { - // Since the pool is closed, we have no choice but to close the channel - channel.close(); - promise.setFailure(new IllegalStateException("FixedChannelPool was closed")); - return; - } - - if (future.isSuccess()) { - decrementAndRunTaskQueue(); - promise.setSuccess(null); - } else { - Throwable cause = future.cause(); - // Check if the exception was not because of we passed the Channel to the wrong pool. - if (!(cause instanceof IllegalArgumentException)) { - decrementAndRunTaskQueue(); - } - promise.setFailure(future.cause()); - } - } - })); - return promise; - } - - private void decrementAndRunTaskQueue() { - int currentCount = acquiredChannelCount.decrementAndGet(); - - // We should never have a negative value. - assert currentCount >= 0; - - // Run the pending acquire tasks before notify the original promise so if the user would - // try to acquire again from the ChannelFutureListener and the pendingAcquireCount is >= - // maxPendingAcquires we may be able to run some pending tasks first and so allow to add - // more. - runTaskQueue(); - } - - private void runTaskQueue() { - while (acquiredChannelCount() < maxConnections) { - AcquireTask task = pendingAcquireQueue.poll(); - if (task == null) { - break; - } - - // Cancel the timeout if one was scheduled - ScheduledFuture timeoutFuture = task.timeoutFuture; - if (timeoutFuture != null) { - timeoutFuture.cancel(false); - } - - --pendingAcquireCount; - task.acquired(); - - super.acquire(task.promise); - } - - // We should never have a negative value. - assert pendingAcquireCount >= 0; - assert acquiredChannelCount() >= 0; - } - - @Override - public int getMaxConnections() { - return maxConnections; - } - - @Override - public int getMaxPendingAcquires() { - return maxPendingAcquires; - } - - @Override - public int getAcquiredChannelCount() { - return acquiredChannelCount.intValue(); - } - - @Override - public int getPendingAcquireCount() { - return pendingAcquireCount; - } - - @Override - public boolean isClosed() { - return closed; - } - - // AcquireTask extends AcquireListener to reduce object creations and so GC pressure - private final class AcquireTask extends AcquireListener { - final Promise promise; - final long expireNanoTime = System.nanoTime() + acquireTimeoutNanos; - ScheduledFuture timeoutFuture; - - public AcquireTask(Promise promise) { - super(promise); - // We need to create a new promise as we need to ensure the AcquireListener runs in the correct - // EventLoop. - this.promise = executor.newPromise().addListener(this); - } - } - - private abstract class TimeoutTask implements Runnable { - @Override - public final void run() { - assert executor.inEventLoop(); - long nanoTime = System.nanoTime(); - for (;;) { - AcquireTask task = pendingAcquireQueue.peek(); - // Compare nanoTime as descripted in the javadocs of System.nanoTime() - // - // See https://docs.oracle.com/javase/7/docs/api/java/lang/System.html#nanoTime() - // See https://github.com/netty/netty/issues/3705 - if (task == null || nanoTime - task.expireNanoTime < 0) { - break; - } - pendingAcquireQueue.remove(); - - --pendingAcquireCount; - onTimeout(task); - } - } - - public abstract void onTimeout(AcquireTask task); - } - - private class AcquireListener implements FutureListener { - private final Promise originalPromise; - protected boolean acquired; - - AcquireListener(Promise originalPromise) { - this.originalPromise = originalPromise; - } - - @Override - public void operationComplete(Future future) throws Exception { - assert executor.inEventLoop(); - if (closed) { - if (future.isSuccess()) { - // Since the pool is closed, we have no choice but to close the channel - future.getNow().close(); - } - originalPromise.setFailure(new IllegalStateException("EspressoFixedChannelPool was closed")); - return; - } - - if (future.isSuccess()) { - originalPromise.setSuccess(future.getNow()); - } else { - if (acquired) { - decrementAndRunTaskQueue(); - } else { - runTaskQueue(); - } - - originalPromise.setFailure(future.cause()); - } - } - - public void acquired() { - if (acquired) { - return; - } - acquiredChannelCount.incrementAndGet(); - acquired = true; - } - } - - @Override - public void close() { - try { - closeAsync().await(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new RuntimeException(e); - } - } - - /** - * Closes the pool in an async manner. - * - * @return Future which represents completion of the close task - */ - public Future closeAsync() { - if (executor.inEventLoop()) { - return close0(); - } else { - final Promise closeComplete = executor.newPromise(); - executor.execute(new Runnable() { - @Override - public void run() { - close0().addListener(new FutureListener() { - @Override - public void operationComplete(Future f) throws Exception { - if (f.isSuccess()) { - closeComplete.setSuccess(null); - } else { - closeComplete.setFailure(f.cause()); - } - } - }); - } - }); - return closeComplete; - } - } - - private Future close0() { - assert executor.inEventLoop(); - - if (!closed) { - closed = true; - for (;;) { - AcquireTask task = pendingAcquireQueue.poll(); - if (task == null) { - break; - } - ScheduledFuture f = task.timeoutFuture; - if (f != null) { - f.cancel(false); - } - task.promise.setFailure(new ClosedChannelException()); - } - acquiredChannelCount.set(0); - pendingAcquireCount = 0; - - // Ensure we dispatch this on another Thread as close0 will be called from the EventExecutor and we need - // to ensure we will not block in a EventExecutor. - return GlobalEventExecutor.INSTANCE.submit(new Callable() { - @Override - public Void call() throws Exception { - EspressoFixedChannelPool.super.close(); - return null; - } - }); - } - - return GlobalEventExecutor.INSTANCE.newSucceededFuture(null); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/EspressoSimpleChannelPool.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/EspressoSimpleChannelPool.java deleted file mode 100644 index 72e7d37b7db..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/EspressoSimpleChannelPool.java +++ /dev/null @@ -1,412 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import static io.netty.util.internal.ObjectUtil.checkNotNull; - -import io.netty.bootstrap.Bootstrap; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.EventLoop; -import io.netty.channel.pool.ChannelHealthChecker; -import io.netty.channel.pool.ChannelPool; -import io.netty.channel.pool.ChannelPoolHandler; -import io.netty.util.AttributeKey; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.FutureListener; -import io.netty.util.concurrent.Promise; -import io.netty.util.internal.PlatformDependent; -import io.netty.util.internal.ThrowableUtil; -import java.util.Deque; - - -/** - * Forked from Netty's SimpleChannelPool - * - * Simple {@link ChannelPool} implementation which will create new {@link Channel}s if someone tries to acquire - * a {@link Channel} but none is in the pool atm. No limit on the maximal concurrent {@link Channel}s is enforced. - * - * This implementation uses LIFO order for {@link Channel}s in the {@link ChannelPool}. - * - */ -public class EspressoSimpleChannelPool implements ChannelPool { - private static final AttributeKey POOL_KEY = - AttributeKey.valueOf(EspressoSimpleChannelPool.class, "channelPool"); - private static final IllegalStateException FULL_EXCEPTION = ThrowableUtil.unknownStackTrace( - new IllegalStateException("ChannelPool full"), - EspressoSimpleChannelPool.class, - "releaseAndOffer(...)"); - - private final Deque deque = PlatformDependent.newConcurrentDeque(); - private final ChannelPoolHandler handler; - private final ChannelHealthChecker healthCheck; - private final Bootstrap bootstrap; - private final boolean releaseHealthCheck; - private final boolean lastRecentUsed; - - /** - * Creates a new instance using the {@link ChannelHealthChecker#ACTIVE}. - * - * @param bootstrap the {@link Bootstrap} that is used for connections - * @param handler the {@link ChannelPoolHandler} that will be notified for the different pool actions - */ - public EspressoSimpleChannelPool(Bootstrap bootstrap, final ChannelPoolHandler handler) { - this(bootstrap, handler, ChannelHealthChecker.ACTIVE); - } - - /** - * Creates a new instance. - * - * @param bootstrap the {@link Bootstrap} that is used for connections - * @param handler the {@link ChannelPoolHandler} that will be notified for the different pool actions - * @param healthCheck the {@link ChannelHealthChecker} that will be used to check if a {@link Channel} is - * still healthy when obtain from the {@link ChannelPool} - */ - public EspressoSimpleChannelPool( - Bootstrap bootstrap, - final ChannelPoolHandler handler, - ChannelHealthChecker healthCheck) { - this(bootstrap, handler, healthCheck, true); - } - - /** - * Creates a new instance. - * - * @param bootstrap the {@link Bootstrap} that is used for connections - * @param handler the {@link ChannelPoolHandler} that will be notified for the different pool actions - * @param healthCheck the {@link ChannelHealthChecker} that will be used to check if a {@link Channel} is - * still healthy when obtain from the {@link ChannelPool} - * @param releaseHealthCheck will check channel health before offering back if this parameter set to {@code true}; - * otherwise, channel health is only checked at acquisition time - */ - public EspressoSimpleChannelPool( - Bootstrap bootstrap, - final ChannelPoolHandler handler, - ChannelHealthChecker healthCheck, - boolean releaseHealthCheck) { - this(bootstrap, handler, healthCheck, releaseHealthCheck, true); - } - - /** - * Creates a new instance. - * - * @param bootstrap the {@link Bootstrap} that is used for connections - * @param handler the {@link ChannelPoolHandler} that will be notified for the different pool actions - * @param healthCheck the {@link ChannelHealthChecker} that will be used to check if a {@link Channel} is - * still healthy when obtain from the {@link ChannelPool} - * @param releaseHealthCheck will check channel health before offering back if this parameter set to {@code true}; - * otherwise, channel health is only checked at acquisition time - * @param lastRecentUsed {@code true} {@link Channel} selection will be LIFO, if {@code false} FIFO. - */ - public EspressoSimpleChannelPool( - Bootstrap bootstrap, - final ChannelPoolHandler handler, - ChannelHealthChecker healthCheck, - boolean releaseHealthCheck, - boolean lastRecentUsed) { - this.handler = checkNotNull(handler, "handler"); - this.healthCheck = checkNotNull(healthCheck, "healthCheck"); - this.releaseHealthCheck = releaseHealthCheck; - // Clone the original Bootstrap as we want to set our own handler - this.bootstrap = checkNotNull(bootstrap, "bootstrap").clone(); - this.bootstrap.handler(new ChannelInitializer() { - @Override - protected void initChannel(Channel ch) throws Exception { - assert ch.eventLoop().inEventLoop(); - handler.channelCreated(ch); - } - }); - this.lastRecentUsed = lastRecentUsed; - } - - /** - * Returns the channel queue, which holds the available channels with the pool. - * @return Deque - */ - protected int getAvailableChannels() { - return deque.size(); - } - - /** - * Returns the {@link Bootstrap} this pool will use to open new connections. - * - * @return the {@link Bootstrap} this pool will use to open new connections - */ - protected Bootstrap bootstrap() { - return bootstrap; - } - - /** - * Returns the {@link ChannelPoolHandler} that will be notified for the different pool actions. - * - * @return the {@link ChannelPoolHandler} that will be notified for the different pool actions - */ - protected ChannelPoolHandler handler() { - return handler; - } - - /** - * Returns the {@link ChannelHealthChecker} that will be used to check if a {@link Channel} is healthy. - * - * @return the {@link ChannelHealthChecker} that will be used to check if a {@link Channel} is healthy - */ - protected ChannelHealthChecker healthChecker() { - return healthCheck; - } - - /** - * Indicates whether this pool will check the health of channels before offering them back into the pool. - * - * @return {@code true} if this pool will check the health of channels before offering them back into the pool, or - * {@code false} if channel health is only checked at acquisition time - */ - protected boolean releaseHealthCheck() { - return releaseHealthCheck; - } - - @Override - public final Future acquire() { - return acquire(bootstrap.config().group().next().newPromise()); - } - - @Override - public Future acquire(final Promise promise) { - checkNotNull(promise, "promise"); - return acquireHealthyFromPoolOrNew(promise); - } - - /** - * Tries to retrieve healthy channel from the pool if any or creates a new channel otherwise. - * @param promise the promise to provide acquire result. - * @return future for acquiring a channel. - */ - private Future acquireHealthyFromPoolOrNew(final Promise promise) { - try { - final Channel ch = pollChannel(); - if (ch == null) { - // No Channel left in the pool bootstrap a new Channel - Bootstrap bs = bootstrap.clone(); - bs.attr(POOL_KEY, this); - ChannelFuture f = connectChannel(bs); - if (f.isDone()) { - notifyConnect(f, promise); - } else { - f.addListener(new ChannelFutureListener() { - @Override - public void operationComplete(ChannelFuture future) throws Exception { - notifyConnect(future, promise); - } - }); - } - return promise; - } - EventLoop loop = ch.eventLoop(); - if (loop.inEventLoop()) { - doHealthCheck(ch, promise); - } else { - loop.execute(new Runnable() { - @Override - public void run() { - doHealthCheck(ch, promise); - } - }); - } - } catch (Throwable cause) { - promise.tryFailure(cause); - } - return promise; - } - - private void notifyConnect(ChannelFuture future, Promise promise) throws Exception { - if (future.isSuccess()) { - Channel channel = future.channel(); - handler.channelAcquired(channel); - if (!promise.trySuccess(channel)) { - // Promise was completed in the meantime (like cancelled), just release the channel again - release(channel); - } - } else { - promise.tryFailure(future.cause()); - } - } - - private void doHealthCheck(final Channel ch, final Promise promise) { - assert ch.eventLoop().inEventLoop(); - - Future f = healthCheck.isHealthy(ch); - if (f.isDone()) { - notifyHealthCheck(f, ch, promise); - } else { - f.addListener(new FutureListener() { - @Override - public void operationComplete(Future future) throws Exception { - notifyHealthCheck(future, ch, promise); - } - }); - } - } - - private void notifyHealthCheck(Future future, Channel ch, Promise promise) { - assert ch.eventLoop().inEventLoop(); - - if (future.isSuccess()) { - if (future.getNow()) { - try { - ch.attr(POOL_KEY).set(this); - handler.channelAcquired(ch); - promise.setSuccess(ch); - } catch (Throwable cause) { - closeAndFail(ch, cause, promise); - } - } else { - closeChannel(ch); - acquireHealthyFromPoolOrNew(promise); - } - } else { - closeChannel(ch); - acquireHealthyFromPoolOrNew(promise); - } - } - - /** - * Bootstrap a new {@link Channel}. The default implementation uses {@link Bootstrap#connect()}, sub-classes may - * override this. - *

- * The {@link Bootstrap} that is passed in here is cloned via {@link Bootstrap#clone()}, so it is safe to modify. - */ - protected ChannelFuture connectChannel(Bootstrap bs) { - return bs.connect(); - } - - @Override - public final Future release(Channel channel) { - return release(channel, channel.eventLoop().newPromise()); - } - - @Override - public Future release(final Channel channel, final Promise promise) { - checkNotNull(channel, "channel"); - checkNotNull(promise, "promise"); - try { - EventLoop loop = channel.eventLoop(); - if (loop.inEventLoop()) { - doReleaseChannel(channel, promise); - } else { - loop.execute(new Runnable() { - @Override - public void run() { - doReleaseChannel(channel, promise); - } - }); - } - } catch (Throwable cause) { - closeAndFail(channel, cause, promise); - } - return promise; - } - - private void doReleaseChannel(Channel channel, Promise promise) { - assert channel.eventLoop().inEventLoop(); - // Remove the POOL_KEY attribute from the Channel and check if it was acquired from this pool, if not fail. - if (channel.attr(POOL_KEY).getAndSet(null) != this) { - closeAndFail( - channel, - // Better include a stacktrace here as this is an user error. - new IllegalArgumentException("Channel " + channel + " was not acquired from this ChannelPool"), - promise); - } else { - try { - if (releaseHealthCheck) { - doHealthCheckOnRelease(channel, promise); - } else { - releaseAndOffer(channel, promise); - } - } catch (Throwable cause) { - closeAndFail(channel, cause, promise); - } - } - } - - private void doHealthCheckOnRelease(final Channel channel, final Promise promise) throws Exception { - final Future f = healthCheck.isHealthy(channel); - if (f.isDone()) { - releaseAndOfferIfHealthy(channel, promise, f); - } else { - f.addListener(new FutureListener() { - @Override - public void operationComplete(Future future) throws Exception { - releaseAndOfferIfHealthy(channel, promise, f); - } - }); - } - } - - /** - * Adds the channel back to the pool only if the channel is healthy. - * @param channel the channel to put back to the pool - * @param promise offer operation promise. - * @param future the future that contains information fif channel is healthy or not. - * @throws Exception in case when failed to notify handler about release operation. - */ - private void releaseAndOfferIfHealthy(Channel channel, Promise promise, Future future) - throws Exception { - if (future.getNow()) { // channel turns out to be healthy, offering and releasing it. - releaseAndOffer(channel, promise); - } else { // channel not healthy, just releasing it. - handler.channelReleased(channel); - promise.setSuccess(null); - } - } - - private void releaseAndOffer(Channel channel, Promise promise) throws Exception { - if (offerChannel(channel)) { - handler.channelReleased(channel); - promise.setSuccess(null); - } else { - closeAndFail(channel, FULL_EXCEPTION, promise); - } - } - - private static void closeChannel(Channel channel) { - channel.attr(POOL_KEY).getAndSet(null); - channel.close(); - } - - private static void closeAndFail(Channel channel, Throwable cause, Promise promise) { - closeChannel(channel); - promise.tryFailure(cause); - } - - /** - * Poll a {@link Channel} out of the internal storage to reuse it. This will return {@code null} if no - * {@link Channel} is ready to be reused. - * - * Sub-classes may override {@link #pollChannel()} and {@link #offerChannel(Channel)}. Be aware that - * implementations of these methods needs to be thread-safe! - */ - protected Channel pollChannel() { - return lastRecentUsed ? deque.pollLast() : deque.pollFirst(); - } - - /** - * Offer a {@link Channel} back to the internal storage. This will return {@code true} if the {@link Channel} - * could be added, {@code false} otherwise. - * - * Sub-classes may override {@link #pollChannel()} and {@link #offerChannel(Channel)}. Be aware that - * implementations of these methods needs to be thread-safe! - */ - protected boolean offerChannel(Channel channel) { - return deque.offer(channel); - } - - @Override - public void close() { - for (;;) { - Channel channel = pollChannel(); - if (channel == null) { - break; - } - channel.close(); - } - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/FastFixedChannelPool.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/FastFixedChannelPool.java deleted file mode 100644 index 11a6c4f29d3..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/FastFixedChannelPool.java +++ /dev/null @@ -1,551 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import com.linkedin.alpini.base.misc.PromiseDelegate; -import io.netty.bootstrap.Bootstrap; -import io.netty.channel.Channel; -import io.netty.channel.group.ChannelGroup; -import io.netty.channel.group.DefaultChannelGroup; -import io.netty.channel.pool.ChannelHealthChecker; -import io.netty.channel.pool.ChannelPoolHandler; -import io.netty.util.Attribute; -import io.netty.util.AttributeKey; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.FutureListener; -import io.netty.util.concurrent.Promise; -import io.netty.util.internal.ObjectUtil; -import io.netty.util.internal.PlatformDependent; -import java.util.Queue; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; -import java.util.concurrent.atomic.LongAdder; -import java.util.function.IntSupplier; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** - * Forked from Netty's FixedChannelPool - * - * {ChannelPool} implementation that takes another {ChannelPool} implementation and enforce a maximum - * number of concurrent connections. - */ -public class FastFixedChannelPool extends FastSimpleChannelPool implements ChannelPoolWithStats { - private static final Logger LOG = LogManager.getLogger(FixedChannelPoolImpl.class); - - private static final AtomicReferenceFieldUpdater CLOSED = - AtomicReferenceFieldUpdater.newUpdater(FastFixedChannelPool.class, Boolean.class, "closed"); - private static final AtomicIntegerFieldUpdater CONNECT_IN_FLIGHT = - AtomicIntegerFieldUpdater.newUpdater(FastFixedChannelPool.class, "_connectInFlight"); - private static final AttributeKey CHANNEL_IS_ACQUIRED = - AttributeKey.valueOf(FastFixedChannelPool.class, "acquired"); - - private final String _name; - private final long acquireTimeoutNanos; - private final TimeoutTask timeoutTask; - protected final ChannelGroup _channelGroup; - - /** Contains runnables to call connect which would have exceeded maxConnections, normally empty. */ - private final Queue _pendingConnect = PlatformDependent.newConcurrentDeque(); - private volatile int _connectInFlight; - - private IntSupplier maxConnections; - private final int maxPendingAcquires; - private final LongAdder acquiredChannelCount = new LongAdder(); - private final LongAdder pendingAcquireCount = new LongAdder(); - volatile private Boolean closed = false; - - public boolean isPoolClosed() { - return closed; - } - - /** - * Creates a new instance using the {@link ChannelHealthChecker#ACTIVE}. - * - * @param bootstrap the {@link Bootstrap} that is used for connections - * @param handler the {@link ChannelPoolHandler} that will be notified for the different pool actions - * @param maxConnections the number of maximal active connections, once this is reached new tries to acquire - * a {@link Channel} will be delayed until a connection is returned to the pool again. - */ - public FastFixedChannelPool(Bootstrap bootstrap, ChannelPoolHandler handler, int maxConnections) { - this(bootstrap, handler, maxConnections, Integer.MAX_VALUE); - } - - /** - * Creates a new instance using the {@link ChannelHealthChecker#ACTIVE}. - * - * @param bootstrap the {@link Bootstrap} that is used for connections - * @param handler the {@link ChannelPoolHandler} that will be notified for the different pool actions - * @param maxConnections the number of maximal active connections, once this is reached new tries to - * acquire a {@link Channel} will be delayed until a connection is returned to the - * pool again. - * @param maxPendingAcquires the maximum number of pending acquires. Once this is exceed acquire tries will - * be failed. - */ - public FastFixedChannelPool( - Bootstrap bootstrap, - ChannelPoolHandler handler, - int maxConnections, - int maxPendingAcquires) { - this(bootstrap, handler, ChannelHealthChecker.ACTIVE, null, -1, maxConnections, maxPendingAcquires); - } - - /** - * Creates a new instance. - * - * @param bootstrap the {@link Bootstrap} that is used for connections - * @param handler the {@link ChannelPoolHandler} that will be notified for the different pool actions - * @param healthCheck the {@link ChannelHealthChecker} that will be used to check if a {@link Channel} is - * still healthy when obtain from the {ChannelPool} - * @param action the {@link io.netty.channel.pool.FixedChannelPool.AcquireTimeoutAction} to use or {@code null} if non should be used. - * In this case {@param acquireTimeoutMillis} must be {@code -1}. - * @param acquireTimeoutMillis the time (in milliseconds) after which an pending acquire must complete or - * the {@link io.netty.channel.pool.FixedChannelPool.AcquireTimeoutAction} takes place. - * @param maxConnections the number of maximal active connections, once this is reached new tries to - * acquire a {@link Channel} will be delayed until a connection is returned to the - * pool again. - * @param maxPendingAcquires the maximum number of pending acquires. Once this is exceed acquire tries will - * be failed. - */ - public FastFixedChannelPool( - Bootstrap bootstrap, - ChannelPoolHandler handler, - ChannelHealthChecker healthCheck, - io.netty.channel.pool.FixedChannelPool.AcquireTimeoutAction action, - final long acquireTimeoutMillis, - int maxConnections, - int maxPendingAcquires) { - this(bootstrap, handler, healthCheck, action, acquireTimeoutMillis, maxConnections, maxPendingAcquires, true); - } - - /** - * Creates a new instance. - * - * @param bootstrap the {@link Bootstrap} that is used for connections - * @param handler the {@link ChannelPoolHandler} that will be notified for the different pool actions - * @param healthCheck the {@link ChannelHealthChecker} that will be used to check if a {@link Channel} is - * still healthy when obtain from the {ChannelPool} - * @param action the {@link io.netty.channel.pool.FixedChannelPool.AcquireTimeoutAction} to use or {@code null} if non should be used. - * In this case {@literal acquireTimeoutMillis} must be {@code -1}. - * @param acquireTimeoutMillis the time (in milliseconds) after which an pending acquire must complete or - * the {@link io.netty.channel.pool.FixedChannelPool.AcquireTimeoutAction} takes place. - * @param maxConnections the number of maximal active connections, once this is reached new tries to - * acquire a {@link Channel} will be delayed until a connection is returned to the - * pool again. - * @param maxPendingAcquires the maximum number of pending acquires. Once this is exceed acquire tries will - * be failed. - * @param releaseHealthCheck will check channel health before offering back if this parameter set to - * {@code true}. - */ - public FastFixedChannelPool( - Bootstrap bootstrap, - ChannelPoolHandler handler, - ChannelHealthChecker healthCheck, - io.netty.channel.pool.FixedChannelPool.AcquireTimeoutAction action, - final long acquireTimeoutMillis, - int maxConnections, - int maxPendingAcquires, - final boolean releaseHealthCheck) { - this( - bootstrap, - handler, - healthCheck, - action, - acquireTimeoutMillis, - maxConnections, - maxPendingAcquires, - releaseHealthCheck, - 1); - } - - /** - * Creates a new instance. - * - * @param bootstrap the {@link Bootstrap} that is used for connections - * @param handler the {@link ChannelPoolHandler} that will be notified for the different pool actions - * @param healthCheck the {@link ChannelHealthChecker} that will be used to check if a {@link Channel} is - * still healthy when obtain from the {ChannelPool} - * @param action the {@link io.netty.channel.pool.FixedChannelPool.AcquireTimeoutAction} to use or {@code null} if non should be used. - * In this case {@literal acquireTimeoutMillis} must be {@code -1}. - * @param acquireTimeoutMillis the time (in milliseconds) after which an pending acquire must complete or - * the {@link io.netty.channel.pool.FixedChannelPool.AcquireTimeoutAction} takes place. - * @param maxConnections the number of maximal active connections, once this is reached new tries to - * acquire a {@link Channel} will be delayed until a connection is returned to the - * pool again. - * @param maxPendingAcquires the maximum number of pending acquires. Once this is exceed acquire tries will - * be failed. - * @param releaseHealthCheck will check channel health before offering back if this parameter set to - * {@code true}. - * @param connectConcurrency the number of concurrent {@literal bootstrap.connect()} calls permitted - */ - public FastFixedChannelPool( - Bootstrap bootstrap, - ChannelPoolHandler handler, - ChannelHealthChecker healthCheck, - io.netty.channel.pool.FixedChannelPool.AcquireTimeoutAction action, - final long acquireTimeoutMillis, - int maxConnections, - int maxPendingAcquires, - boolean releaseHealthCheck, - int connectConcurrency) { - this( - bootstrap, - handler, - healthCheck, - action, - acquireTimeoutMillis, - () -> maxConnections, - maxPendingAcquires, - releaseHealthCheck, - connectConcurrency); - } - - /** - * Creates a new instance. - * - * @param bootstrap the {@link Bootstrap} that is used for connections - * @param handler the {@link ChannelPoolHandler} that will be notified for the different pool actions - * @param healthCheck the {@link ChannelHealthChecker} that will be used to check if a {@link Channel} is - * still healthy when obtain from the {ChannelPool} - * @param action the {@link io.netty.channel.pool.FixedChannelPool.AcquireTimeoutAction} to use or {@code null} if non should be used. - * In this case {@literal acquireTimeoutMillis} must be {@code -1}. - * @param acquireTimeoutMillis the time (in milliseconds) after which an pending acquire must complete or - * the {@link io.netty.channel.pool.FixedChannelPool.AcquireTimeoutAction} takes place. - * @param maxConnections the number of maximal active connections, once this is reached new tries to - * acquire a {@link Channel} will be delayed until a connection is returned to the - * pool again. - * @param maxPendingAcquires the maximum number of pending acquires. Once this is exceed acquire tries will - * be failed. - * @param releaseHealthCheck will check channel health before offering back if this parameter set to - * {@code true}. - * @param connectConcurrency the number of concurrent {@literal bootstrap.connect()} calls permitted - */ - public FastFixedChannelPool( - Bootstrap bootstrap, - ChannelPoolHandler handler, - ChannelHealthChecker healthCheck, - io.netty.channel.pool.FixedChannelPool.AcquireTimeoutAction action, - final long acquireTimeoutMillis, - IntSupplier maxConnections, - int maxPendingAcquires, - boolean releaseHealthCheck, - int connectConcurrency) { - super(bootstrap, handler, healthCheck, releaseHealthCheck, connectConcurrency); - if (maxConnections.getAsInt() < 1) { - throw new IllegalArgumentException("maxConnections: " + maxConnections.getAsInt() + " (expected: >= 1)"); - } - if (maxPendingAcquires < 1) { - throw new IllegalArgumentException("maxPendingAcquires: " + maxPendingAcquires + " (expected: >= 1)"); - } - if (action == null && acquireTimeoutMillis == -1) { - timeoutTask = null; - acquireTimeoutNanos = -1; - } else if (action == null && acquireTimeoutMillis != -1) { - throw new NullPointerException("action"); - } else if (action != null && acquireTimeoutMillis < 0) { - throw new IllegalArgumentException("acquireTimeoutMillis: " + acquireTimeoutMillis + " (expected: >= 0)"); - } else { - acquireTimeoutNanos = TimeUnit.MILLISECONDS.toNanos(acquireTimeoutMillis); - switch (action) { - case FAIL: - timeoutTask = new TimeoutTask() { - private final TimeoutException _timeoutException = - new TimeoutException("Acquire operation took longer then configured maximum time") { - @Override - public synchronized Throwable fillInStackTrace() { - return this; - } - }; - - @Override - public void onTimeout(AcquireTask task) { - // Fail the promise as we timed out. - task.tryFailure(_timeoutException); - } - }; - break; - case NEW: - timeoutTask = new TimeoutTask() { - @Override - public void onTimeout(AcquireTask task) { - // If there is any pending connect operation, allow it to execute even if it may - // cause the number of connections to exceed maxConnections. - Runnable pending = _pendingConnect.poll(); - if (pending != null) { - pending.run(); - } - } - }; - break; - default: - throw new Error(); - } - } - this.maxConnections = maxConnections; - this.maxPendingAcquires = maxPendingAcquires; - _name = bootstrap.config().remoteAddress().toString(); - _channelGroup = newPoolChannelGroup(); - } - - @Override - public String name() { - return _name; - } - - public void setMaxConnections(IntSupplier maxConnections) { - this.maxConnections = maxConnections; - } - - protected PoolChannelGroup newPoolChannelGroup() { - return new PoolChannelGroup(name()); - } - - protected class PoolChannelGroup extends DefaultChannelGroup { - protected PoolChannelGroup(String name) { - super(name, _immediateEventExecutor, true); - } - - @Override - public boolean remove(Object o) { - if (super.remove(o)) { - if (!_pendingConnect.isEmpty() && size() + _connectInFlight < getMaxConnections()) { - Runnable task = _pendingConnect.poll(); - if (task != null) { - task.run(); - } - } - return true; - } - return false; - } - } - - /** Returns the number of acquired channels that this pool thinks it has. */ - public int acquiredChannelCount() { - return acquiredChannelCount.intValue(); - } - - private void incrementAcquiredChannelCount() { - acquiredChannelCount.increment(); - } - - private void decrementAcquiredChannelCount() { - acquiredChannelCount.decrement(); - } - - @Override - public Future acquire(final Promise promise) { - try { - acquire0(promise); - } catch (Throwable cause) { - if (!promise.tryFailure(cause)) { - LOG.warn("Exception during acquire", cause); - } - } - return promise; - } - - private void acquire0(final Promise promise) { - if (closed) { - promise.setFailure(new IllegalStateException("FixedChannelPool was closed")); - return; - } - if (promise.isDone()) { - return; - } - if (pendingAcquireCount.intValue() >= maxPendingAcquires) { - tooManyOutstanding(promise); - } else { - AcquireTask task = new AcquireTask(promise); - super.acquire(task); - if (!task.isDone()) { - if (timeoutTask != null && !promise.isDone()) { - task.timeoutFuture = bootstrap().config() - .group() - .schedule(() -> timeoutTask.onTimeout(task), acquireTimeoutNanos, TimeUnit.NANOSECONDS); - } - } - } - } - - private void tooManyOutstanding(Promise promise) { - promise.setFailure(new IllegalStateException("Too many outstanding acquire operations")); - } - - /** - * Initiate establishing a new connection with the provided bootstrap. - * This implementation attempts to not exceed a preset number of max connections by - * storing deferred connections that would have caused the number of connections to - * be exceeded in the {@literal _pendingConnect} queue. - * As connections are established, they are added to {@literal _channelGroup}. - * @param bs Channel Bootstrap - * @param promise Promise to complete with result of Bootstrap connect - * @return the promise - */ - @Override - protected Future connectChannel(Bootstrap bs, Promise promise) { - Promise p = new PromiseDelegate(promise) { - @Override - public boolean trySuccess(Channel channel) { - _channelGroup.add(channel); - return super.trySuccess(channel); - } - }; - if (_channelGroup.size() + _connectInFlight >= getMaxConnections()) { - _pendingConnect.add(() -> connectChannel0(bs, p)); - } else { - connectChannel0(bs, p); - } - return promise; - } - - private void connectChannel0(Bootstrap bs, Promise promise) { - CONNECT_IN_FLIGHT.incrementAndGet(this); - super.connectChannel(bs, promise.addListener(future -> { - int connectInFlight = CONNECT_IN_FLIGHT.decrementAndGet(this); - // If there's another pending connection, we probably should ensure that it runs. - if (!_pendingConnect.isEmpty() && _channelGroup.size() + connectInFlight < getMaxConnections()) { - Runnable connect = _pendingConnect.poll(); - if (connect != null) { - connect.run(); - } - } - })); - } - - @Override - public Future release(final Channel channel, final Promise promise) { - ObjectUtil.checkNotNull(promise, "promise"); - Attribute attr = channel.attr(CHANNEL_IS_ACQUIRED); - if (attr.get() != this) { - return promise.setFailure(new IllegalArgumentException("Wrong pool for channel")); - } - if (attr.compareAndSet(FastFixedChannelPool.this, null)) { - decrementAcquiredChannelCount(); - } - final Promise p = _immediateEventExecutor.newPromise(); - super.release(channel, p.addListener(new FutureListener() { - @Override - public void operationComplete(Future future) throws Exception { - if (closed) { - // Since the pool is closed, we have no choice but to close the channel - channel.close(); - promise.setFailure(new IllegalStateException("FixedChannelPool was closed")); - return; - } - - if (future.isSuccess()) { - promise.setSuccess(null); - } else { - promise.setFailure(future.cause()); - } - } - })); - return promise; - } - - @Override - public int getMaxConnections() { - return maxConnections.getAsInt(); - } - - @Override - public int getMaxPendingAcquires() { - return maxPendingAcquires; - } - - @Override - public int getAcquiredChannelCount() { - return acquiredChannelCount.intValue(); - } - - @Override - public int getPendingAcquireCount() { - return pendingAcquireCount.intValue(); - } - - @Override - public boolean isClosed() { - return closed; - } - - private static final AtomicReferenceFieldUpdater ACQUIRE_TASK_COMPLETE = - AtomicReferenceFieldUpdater.newUpdater(AcquireTask.class, Boolean.class, "completed"); - - private final class AcquireTask extends PromiseDelegate { - ScheduledFuture timeoutFuture; - volatile Boolean completed = false; - - public AcquireTask(Promise promise) { - super(promise); - pendingAcquireCount.increment(); - } - - boolean complete() { - if (completed || !ACQUIRE_TASK_COMPLETE.compareAndSet(this, false, true)) { - return false; - } - pendingAcquireCount.decrement(); - if (timeoutFuture != null) { - timeoutFuture.cancel(false); - } - return true; - } - - @Override - public boolean trySuccess(Channel result) { - if (complete()) { - Attribute attr = result.attr(CHANNEL_IS_ACQUIRED); - attr.set(FastFixedChannelPool.this); - incrementAcquiredChannelCount(); - if (super.trySuccess(result)) { - return true; - } - attr.set(null); - decrementAcquiredChannelCount(); - } - return false; - } - - @Override - public boolean tryFailure(Throwable cause) { - return complete() && super.tryFailure(cause); - } - } - - private interface TimeoutTask { - void onTimeout(AcquireTask task); - } - - @Override - public void close() { - try { - closeAsync().await(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new RuntimeException(e); - } - } - - /** - * Closes the pool in an async manner. - * - * @return Future which represents completion of the close task - */ - public Future closeAsync() { - return close0(); - } - - private Future close0() { - if (!closed && !CLOSED.getAndSet(this, true)) { - acquiredChannelCount.reset(); - pendingAcquireCount.reset(); - // Calls close on the actual channels - super.close(); - } - - return _immediateEventExecutor.newSucceededFuture(null); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/FastSimpleChannelPool.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/FastSimpleChannelPool.java deleted file mode 100644 index d9d3f8b61be..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/FastSimpleChannelPool.java +++ /dev/null @@ -1,616 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import static io.netty.util.internal.ObjectUtil.checkNotNull; - -import io.netty.bootstrap.Bootstrap; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.pool.ChannelHealthChecker; -import io.netty.channel.pool.ChannelPool; -import io.netty.channel.pool.ChannelPoolHandler; -import io.netty.util.AttributeKey; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.FutureListener; -import io.netty.util.concurrent.ImmediateEventExecutor; -import io.netty.util.concurrent.Promise; -import io.netty.util.internal.ThrowableUtil; -import io.netty.util.internal.logging.InternalLogger; -import io.netty.util.internal.logging.InternalLoggerFactory; -import java.util.concurrent.Semaphore; -import java.util.concurrent.atomic.AtomicReference; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; -import java.util.concurrent.atomic.LongAdder; - - -/** - * Forked from Netty's SimpleChannelPool - * - * Simple {@link ChannelPool} implementation which will create new {@link Channel}s if someone tries to acquire - * a {@link Channel} but none is in the pool atm. No limit on the maximal concurrent {@link Channel}s is enforced. - * - * This implementation uses FIFO order for {@link Channel}s in the {@link ChannelPool}. - * - */ -public class FastSimpleChannelPool implements ChannelPool { - private static final AttributeKey POOL_KEY = - AttributeKey.valueOf(FastSimpleChannelPool.class, "channelPool"); - private static final IllegalStateException FULL_EXCEPTION = ThrowableUtil.unknownStackTrace( - new IllegalStateException("ChannelPool full"), - FastSimpleChannelPool.class, - "releaseAndOffer(...)"); - - private static final InternalLogger LOG = InternalLoggerFactory.getInstance(FastSimpleChannelPool.class); - - private static final AtomicReferenceFieldUpdater ACQUIRE = - AtomicReferenceFieldUpdater.newUpdater(FastSimpleChannelPool.class, DualQueueEntry.class, "_acquirePos"); - private static final AtomicReferenceFieldUpdater RELEASE = - AtomicReferenceFieldUpdater.newUpdater(FastSimpleChannelPool.class, DualQueueEntry.class, "_releasePos"); - - private volatile DualQueueEntry _acquirePos = new DualQueueEntry(); - private volatile DualQueueEntry _releasePos = _acquirePos; - private final ChannelPoolHandler handler; - private final ChannelHealthChecker healthCheck; - private final Bootstrap bootstrap; - private final boolean releaseHealthCheck; - private final Semaphore connectSemaphore; - private final LongAdder connectInProgress = new LongAdder(); - protected final ImmediateEventExecutor _immediateEventExecutor = ImmediateEventExecutor.INSTANCE; - - /** - * Dual Queues, introduced by Scherer and Scott - * (http://www.cs.rochester.edu/~scott/papers/2004_DISC_dual_DS.pdf) - * are (linked) queues in which nodes may represent either data or - * requests. When a thread tries to enqueue a data node, but - * encounters a request node, it instead "matches" and removes it; - * and vice versa for enqueuing requests. - */ - private static final class DualQueueEntry extends AtomicReference { - private volatile Channel _channel; - private volatile Promise _promise; - - DualQueueEntry() { - } - - DualQueueEntry(Channel channel) { - _channel = channel; - } - - DualQueueEntry(Promise promise) { - _promise = promise; - } - - Channel channel() { - return _channel; - } - - Promise promise() { - return _promise; - } - - boolean acquire(Channel channel) { - return CHANNEL.compareAndSet(this, channel, null); - } - - boolean acquire(Promise promise) { - return PROMISE.compareAndSet(this, promise, null); - } - - private static final AtomicReferenceFieldUpdater CHANNEL = - AtomicReferenceFieldUpdater.newUpdater(DualQueueEntry.class, Channel.class, "_channel"); - @SuppressWarnings({ "unchecked", "rawtypes" }) - private static final AtomicReferenceFieldUpdater> PROMISE = - AtomicReferenceFieldUpdater - .newUpdater(DualQueueEntry.class, (Class>) (Class) Promise.class, "_promise"); - } - - /** - * Creates a new instance using the {@link ChannelHealthChecker#ACTIVE}. - * - * @param bootstrap the {@link Bootstrap} that is used for connections - * @param handler the {@link ChannelPoolHandler} that will be notified for the different pool actions - */ - public FastSimpleChannelPool(Bootstrap bootstrap, final ChannelPoolHandler handler) { - this(bootstrap, handler, ChannelHealthChecker.ACTIVE); - } - - /** - * Creates a new instance. - * - * @param bootstrap the {@link Bootstrap} that is used for connections - * @param handler the {@link ChannelPoolHandler} that will be notified for the different pool actions - * @param healthCheck the {@link ChannelHealthChecker} that will be used to check if a {@link Channel} is - * still healthy when obtain from the {@link ChannelPool} - */ - public FastSimpleChannelPool( - Bootstrap bootstrap, - final ChannelPoolHandler handler, - ChannelHealthChecker healthCheck) { - this(bootstrap, handler, healthCheck, true); - } - - /** - * Creates a new instance. - * - * @param bootstrap the {@link Bootstrap} that is used for connections - * @param handler the {@link ChannelPoolHandler} that will be notified for the different pool actions - * @param healthCheck the {@link ChannelHealthChecker} that will be used to check if a {@link Channel} is - * still healthy when obtain from the {@link ChannelPool} - * @param releaseHealthCheck will check channel health before offering back if this parameter set to {@code true}; - * otherwise, channel health is only checked at acquisition time - */ - public FastSimpleChannelPool( - Bootstrap bootstrap, - final ChannelPoolHandler handler, - ChannelHealthChecker healthCheck, - boolean releaseHealthCheck) { - this(bootstrap, handler, healthCheck, releaseHealthCheck, 1); - } - - /** - * Creates a new instance. - * - * @param bootstrap the {@link Bootstrap} that is used for connections - * @param handler the {@link ChannelPoolHandler} that will be notified for the different pool actions - * @param healthCheck the {@link ChannelHealthChecker} that will be used to check if a {@link Channel} is - * still healthy when obtain from the {@link ChannelPool} - * @param releaseHealthCheck will check channel health before offering back if this parameter set to {@code true}; - * otherwise, channel health is only checked at acquisition time - * @param connectConcurrency the number of concurrent {@literal bootstrap.connect()} calls permitted - */ - public FastSimpleChannelPool( - Bootstrap bootstrap, - final ChannelPoolHandler handler, - ChannelHealthChecker healthCheck, - boolean releaseHealthCheck, - int connectConcurrency) { - this.handler = checkNotNull(handler, "handler"); - this.healthCheck = checkNotNull(healthCheck, "healthCheck"); - this.releaseHealthCheck = releaseHealthCheck; - // Clone the original Bootstrap as we want to set our own handler - this.bootstrap = checkNotNull(bootstrap, "bootstrap").clone(); - this.bootstrap.handler(new ChannelInitializer() { - @Override - protected void initChannel(Channel ch) throws Exception { - assert ch.eventLoop().inEventLoop(); - handler.channelCreated(ch); - } - }); - this.connectSemaphore = new Semaphore(connectConcurrency); - } - - /** - * Counts the number of idle channels available within the pool. - * @return available channels - */ - protected int getAvailableChannels() { - int count = 0; - for (DualQueueEntry entry = _acquirePos; entry != null; entry = entry.get()) { - if (entry._channel == null) { - continue; - } - count++; - } - return count; - } - - /** - * Returns the {@link Bootstrap} this pool will use to open new connections. - * - * @return the {@link Bootstrap} this pool will use to open new connections - */ - protected Bootstrap bootstrap() { - return bootstrap; - } - - /** - * Returns the {@link ChannelPoolHandler} that will be notified for the different pool actions. - * - * @return the {@link ChannelPoolHandler} that will be notified for the different pool actions - */ - protected ChannelPoolHandler handler() { - return handler; - } - - /** - * Returns the {@link ChannelHealthChecker} that will be used to check if a {@link Channel} is healthy. - * - * @return the {@link ChannelHealthChecker} that will be used to check if a {@link Channel} is healthy - */ - protected ChannelHealthChecker healthChecker() { - return healthCheck; - } - - /** - * Indicates whether this pool will check the health of channels before offering them back into the pool. - * - * @return {@code true} if this pool will check the health of channels before offering them back into the pool, or - * {@code false} if channel health is only checked at acquisition time - */ - protected boolean releaseHealthCheck() { - return releaseHealthCheck; - } - - @Override - public final Future acquire() { - return acquire(_immediateEventExecutor.newPromise()); - } - - @Override - public Future acquire(final Promise promise) { - checkNotNull(promise, "promise"); - return acquireHealthyFromPoolOrNew(promise); - } - - /** - * Tries to retrieve healthy channel from the pool if any or creates a new channel otherwise. - * @param promise the promise to provide acquire result. - * @return future for acquiring a channel. - */ - private Future acquireHealthyFromPoolOrNew(final Promise promise) { - try { - final Channel ch = pollChannel(); - if (ch == null) { - // No Channel left in the pool - if (addWaiter(promise)) { - return promise; - } - if (promise.isDone() || !acquireConnectSemaphore()) { - return promise; - } - // bootstrap a new Channel - return bootstrapChannel(promise); - } - doHealthCheck(ch, promise); - } catch (Throwable cause) { - promise.tryFailure(cause); - } - return promise; - } - - protected final int connectInProgress() { - return connectInProgress.intValue(); - } - - protected boolean acquireConnectSemaphore() { - if (connectSemaphore.tryAcquire()) { - connectInProgress.increment(); - return true; - } - return false; - } - - protected Future bootstrapChannel(Promise promise) throws Exception { - Bootstrap bs = bootstrap.clone(); - bs.attr(POOL_KEY, this); - Future f = connectChannel(bs, _immediateEventExecutor.newPromise()); - if (f.isDone()) { - notifyConnect(f, promise); - } else { - f.addListener(new FutureListener() { - @Override - public void operationComplete(Future future) throws Exception { - notifyConnect(future, promise); - } - }); - } - return promise; - } - - protected void onConnect(Channel channel, Promise promise) { - } - - protected final void releaseConnectSemaphore() { - connectSemaphore.release(); - connectInProgress.decrement(); - } - - private void notifyConnect(Future future, Promise promise) throws Exception { - releaseConnectSemaphore(); - if (future.isSuccess()) { - Channel channel = future.getNow(); - onConnect(channel, promise); - if (promise.isDone()) { - if (offerChannel(channel)) { - return; - } - closeChannel(channel); - return; - } - try { - promise.setUncancellable(); - handler.channelAcquired(channel); - if (!promise.trySuccess(channel)) { - // Promise was completed in the meantime (like cancelled), just release the channel again - release(channel); - } - } catch (Throwable ex) { - closeAndFail(channel, ex, promise); - } - } else { - onConnect(null, promise); - if (!promise.tryFailure(future.cause())) { - LOG.warn("Failure in connect", future.cause()); - } - } - } - - private void doHealthCheck(final Channel ch, final Promise promise) { - Future f = healthCheck.isHealthy(ch); - if (f.isDone()) { - notifyHealthCheck(f, ch, promise); - } else { - f.addListener(new FutureListener() { - @Override - public void operationComplete(Future future) throws Exception { - notifyHealthCheck(future, ch, promise); - } - }); - } - } - - private void notifyHealthCheck(Future future, Channel ch, Promise promise) { - if (future.isSuccess()) { - if (Boolean.TRUE.equals(future.getNow())) { - if (promise.isDone()) { - if (offerChannel(ch)) { - return; - } - closeChannel(ch); - } - try { - ch.attr(POOL_KEY).set(this); - handler.channelAcquired(ch); - if (!promise.trySuccess(ch)) { - handler.channelReleased(ch); - tryOffer(ch, _immediateEventExecutor.newPromise()); - } - } catch (Throwable cause) { - closeAndFail(ch, cause, promise); - } - } else { - closeChannel(ch); - acquireHealthyFromPoolOrNew(promise); - } - } else { - closeChannel(ch); - acquireHealthyFromPoolOrNew(promise); - } - } - - /** - * Bootstrap a new {@link Channel}. The default implementation uses {@link Bootstrap#connect()}, sub-classes may - * override this. - *

- * The {@link Bootstrap} that is passed in here is cloned via {@link Bootstrap#clone()}, so it is safe to modify. - * @return - */ - protected Future connectChannel(Bootstrap bs, Promise promise) { - if (!promise.isDone()) { - ChannelFuture future = bs.connect(); - if (future.isDone()) { - return connectChannel0(future, promise); - } else { - future.addListener((ChannelFuture connected) -> connectChannel0(connected, promise)); - } - } - return promise; - } - - private Future connectChannel0(ChannelFuture future, Promise promise) { - if (future.isSuccess()) { - if (promise.trySuccess(future.channel())) { - return promise; - } - closeChannel(future.channel()); - return promise; - } else { - return promise.setFailure(future.cause()); - } - } - - @Override - public final Future release(Channel channel) { - return release(channel, _immediateEventExecutor.newPromise()); - } - - @Override - public Future release(final Channel channel, final Promise promise) { - checkNotNull(channel, "channel"); - checkNotNull(promise, "promise"); - try { - doReleaseChannel(channel, promise); - } catch (Throwable cause) { - closeAndFail(channel, cause, promise); - } - return promise; - } - - private void doReleaseChannel(Channel channel, Promise promise) { - // Remove the POOL_KEY attribute from the Channel and check if it was acquired from this pool, if not fail. - if (channel.attr(POOL_KEY).getAndSet(null) != this) { - closeAndFail( - channel, - // Better include a stacktrace here as this is an user error. - new IllegalArgumentException("Channel " + channel + " was not acquired from this ChannelPool"), - promise); - } else { - try { - handler.channelReleased(channel); - if (releaseHealthCheck) { - doHealthCheckOnRelease(channel, promise); - } else { - tryOffer(channel, promise); - } - } catch (Throwable cause) { - closeAndFail(channel, cause, promise); - } - } - } - - private void doHealthCheckOnRelease(final Channel channel, final Promise promise) { - final Future f = healthCheck.isHealthy(channel); - if (f.isDone()) { - offerIfHealthy(channel, promise, f); - } else { - f.addListener(new FutureListener() { - @Override - public void operationComplete(Future future) throws Exception { - offerIfHealthy(channel, promise, future); - } - }); - } - } - - /** - * Adds the channel back to the pool only if the channel is healthy. - * @param channel the channel to put back to the pool - * @param promise offer operation promise. - * @param future the future that contains information fif channel is healthy or not. - * @throws Exception in case when failed to notify handler about release operation. - */ - private void offerIfHealthy(Channel channel, Promise promise, Future future) { - if (future.isSuccess() && Boolean.TRUE.equals(future.getNow())) { // channel turns out to be healthy, offering and - // releasing it. - tryOffer(channel, promise); - } else { // channel not healthy, just releasing it. - if (future.isSuccess()) { - if (!channel.closeFuture().isDone()) { - LOG.warn("Closing unhealthy channel: {}", channel); - closeChannel(channel).addListener(f -> promise.setSuccess(null)); - } else { - promise.setSuccess(null); - } - } else { - closeAndFail(channel, future.cause(), promise); - } - } - } - - private void tryOffer(Channel channel, Promise promise) { - try { - if (offerChannel(channel)) { - promise.setSuccess(null); - return; - } - } catch (Throwable ex) { - LOG.error("Unexpected", ex); - closeAndFail(channel, ex, promise); - return; - } - closeAndFail(channel, FULL_EXCEPTION, promise); - } - - protected static ChannelFuture closeChannel(Channel channel) { - channel.attr(POOL_KEY).getAndSet(null); - return channel.close(); - } - - private static void closeAndFail(Channel channel, Throwable cause, Promise promise) { - closeChannel(channel).addListener(closed -> promise.tryFailure(cause)); - } - - /** - * Poll a {@link Channel} out of the internal storage to reuse it. This will return {@code null} if no - * {@link Channel} is ready to be reused. - * - * Sub-classes may override {@link #pollChannel()} and {@link #offerChannel(Channel)}. Be aware that - * implementations of these methods needs to be thread-safe! - */ - protected Channel pollChannel() { - for (DualQueueEntry pos = _acquirePos; pos != null; pos = pos.get()) { - Channel channel = pos.channel(); - if (channel != null && pos.acquire(channel)) { - channelAcquiredFromPool(pos, channel); - return channel; - } - } - return null; - } - - private void channelAcquiredFromPool(DualQueueEntry pos, Channel channel) { - DualQueueEntry next = pos.get(); - ACQUIRE.lazySet(this, next != null ? next : pos); - } - - protected boolean addWaiter(Promise promise) { - DualQueueEntry entry = - new DualQueueEntry(_immediateEventExecutor.newPromise().addListener((Future future) -> { - if (future.isSuccess()) { - if (promise.isDone()) { - if (offerChannel(future.getNow())) { - return; - } - closeChannel(future.getNow()); - } else { - doHealthCheck(future.getNow(), promise); - } - } else { - promise.setFailure(future.cause()); - } - })); - DualQueueEntry pos = _acquirePos; - for (;;) { - Channel channel = pos.channel(); - if (channel != null && pos.acquire(channel)) { - channelAcquiredFromPool(pos, channel); - doHealthCheck(channel, promise); - return true; - } - DualQueueEntry next = pos.get(); - if (next == null) { - if (pos.compareAndSet(null, entry)) { - ACQUIRE.lazySet(this, entry); - break; - } - continue; - } - pos = next; - } - return false; - } - - /** - * Offer a {@link Channel} back to the internal storage. This will return {@code true} if the {@link Channel} - * could be added, {@code false} otherwise. - * - * Sub-classes may override {@link #pollChannel()} and {@link #offerChannel(Channel)}. Be aware that - * implementations of these methods needs to be thread-safe! - */ - protected boolean offerChannel(Channel channel) { - DualQueueEntry entry = null; - for (DualQueueEntry pos = _releasePos;;) { - Promise promise = pos.promise(); - if (promise != null && pos.acquire(promise)) { - DualQueueEntry next = pos.get(); - RELEASE.lazySet(this, next != null ? next : pos); - if (promise.trySuccess(channel)) { - return true; - } - } - DualQueueEntry next = pos.get(); - if (next == null) { - if (entry == null) { - entry = new DualQueueEntry(channel); - } - if (pos.compareAndSet(null, entry)) { - RELEASE.lazySet(this, entry); - return true; - } - continue; - } - pos = next; - } - } - - @Override - public void close() { - for (;;) { - Channel channel = pollChannel(); - if (channel == null) { - break; - } - channel.close(); - } - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/FixedChannelPoolFactory.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/FixedChannelPoolFactory.java deleted file mode 100644 index bf30cbc0a9a..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/FixedChannelPoolFactory.java +++ /dev/null @@ -1,380 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import com.linkedin.alpini.base.misc.Time; -import com.linkedin.alpini.base.monitoring.CallCompletion; -import com.linkedin.alpini.base.monitoring.CallTracker; -import com.linkedin.alpini.base.monitoring.NullCallTracker; -import com.linkedin.alpini.netty4.misc.NettyUtils; -import io.netty.bootstrap.Bootstrap; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandler; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.pool.ChannelHealthChecker; -import io.netty.channel.pool.ChannelPoolHandler; -import io.netty.channel.pool.FixedChannelPool; -import io.netty.util.Attribute; -import io.netty.util.AttributeKey; -import io.netty.util.concurrent.Future; -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.util.Objects; -import java.util.Optional; -import java.util.function.BooleanSupplier; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.IntSupplier; -import java.util.function.LongSupplier; -import javax.annotation.Nonnegative; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** - * This factory constructs instances of {@link FixedChannelPool} for the {@link ChannelPoolManager}. - * - * @author acurtis on 3/29/17. - */ -public class FixedChannelPoolFactory implements ChannelPoolFactory, ChannelHealthChecker { - private static final AttributeKey LAST_HEALTHCHECK_TIMESTAMP = - AttributeKey.valueOf(FixedChannelPoolFactory.class, "lastHealthCheck"); - - private final Logger _log = LogManager.getLogger(getClass()); - - private final Bootstrap _bootstrap; - private long _acquireTimeoutMillis; - private FixedChannelPool.AcquireTimeoutAction _acquireTimeoutAction = FixedChannelPool.AcquireTimeoutAction.FAIL; - private IntSupplier _minConnections; - private IntSupplier _maxConnections; - private IntSupplier _maxPendingAcquires; - private boolean _releaseHeathCheck; - private LongSupplier _healthCheckIntervalMillis; - private final ChannelHealthChecker _channelHealthChecker; - private final Function _healthCheckerTracker; - private final Consumer _channelInitializer; - protected boolean _usingFastPool; - - protected BooleanSupplier _useQueueSizeForAcquiredChannelCount = Boolean.FALSE::booleanValue; - - private static final AttributeKey CHANNEL_POOL_HANDLER = - AttributeKey.valueOf(ChannelPoolHandler.class, "channel-pool-handler"); - - public FixedChannelPoolFactory( - @Nonnull Bootstrap bootstrap, - @Nonnegative long acquireTimeoutMillis, - @Nonnegative int maxConnections, - @Nonnegative int maxPendingAcquires, - boolean releaseHeathCheck, - @Nonnegative long healthCheckIntervalMillis, - @Nonnull ChannelHealthChecker channelHealthChecker, - @Nullable CallTracker healthCheckerTracker) { - this( - bootstrap, - acquireTimeoutMillis, - maxConnections, - maxPendingAcquires, - releaseHeathCheck, - healthCheckIntervalMillis, - channelHealthChecker, - healthCheckerTracker != null ? ignored -> healthCheckerTracker : null); - } - - public FixedChannelPoolFactory( - @Nonnull Bootstrap bootstrap, - @Nonnegative long acquireTimeoutMillis, - @Nonnegative int maxConnections, - @Nonnegative int maxPendingAcquires, - boolean releaseHeathCheck, - @Nonnegative long healthCheckIntervalMillis, - @Nonnull ChannelHealthChecker channelHealthChecker, - @Nullable Function healthCheckerTracker) { - this( - bootstrap, - acquireTimeoutMillis, - 0, - maxConnections, - maxPendingAcquires, - releaseHeathCheck, - healthCheckIntervalMillis, - channelHealthChecker, - healthCheckerTracker); - } - - public FixedChannelPoolFactory( - @Nonnull Bootstrap bootstrap, - @Nonnegative long acquireTimeoutMillis, - @Nonnegative int minConnections, - @Nonnegative int maxConnections, - @Nonnegative int maxPendingAcquires, - boolean releaseHeathCheck, - @Nonnegative long healthCheckIntervalMillis, - @Nonnull ChannelHealthChecker channelHealthChecker, - @Nullable Function healthCheckerTracker) { - this( - bootstrap, - acquireTimeoutMillis, - minConnections, - maxConnections, - maxPendingAcquires, - releaseHeathCheck, - healthCheckIntervalMillis, - channelHealthChecker, - healthCheckerTracker, - extractChannelInitializer(bootstrap)); - } - - private static Consumer extractChannelInitializer(Bootstrap bootstrap) { - ChannelHandler handler = Objects.requireNonNull(bootstrap.config().handler(), "bootstrap.handler"); - return channel -> channel.pipeline().addLast(NettyUtils.executorGroup(channel), handler); - } - - @SuppressWarnings("unchecked") - protected static T getChannelPoolHandler(@Nonnull Channel ch) { - return (T) ch.attr(CHANNEL_POOL_HANDLER).get(); - } - - private FixedChannelPoolFactory( - @Nonnull Bootstrap bootstrap, - @Nonnegative long acquireTimeoutMillis, - @Nonnegative int minConnections, - @Nonnegative int maxConnections, - @Nonnegative int maxPendingAcquires, - boolean releaseHeathCheck, - @Nonnegative long healthCheckIntervalMillis, - @Nonnull ChannelHealthChecker channelHealthChecker, - @Nullable Function healthCheckerTracker, - @Nonnull Consumer channelInitializer) { - this( - bootstrap, - acquireTimeoutMillis, - Integer.valueOf(minConnections)::intValue, - Integer.valueOf(maxConnections)::intValue, - Integer.valueOf(maxPendingAcquires)::intValue, - releaseHeathCheck, - Long.valueOf(healthCheckIntervalMillis)::longValue, - channelHealthChecker, - healthCheckerTracker, - channelInitializer); - } - - public FixedChannelPoolFactory( - @Nonnull Bootstrap bootstrap, - @Nonnegative long acquireTimeoutMillis, - @Nonnull IntSupplier minConnections, - @Nonnull IntSupplier maxConnections, - @Nonnull IntSupplier maxPendingAcquires, - boolean releaseHeathCheck, - @Nonnull LongSupplier healthCheckIntervalMillis, - @Nonnull ChannelHealthChecker channelHealthChecker, - @Nullable Function healthCheckerTracker) { - this( - bootstrap, - acquireTimeoutMillis, - minConnections, - maxConnections, - maxPendingAcquires, - releaseHeathCheck, - healthCheckIntervalMillis, - channelHealthChecker, - healthCheckerTracker, - extractChannelInitializer(bootstrap)); - } - - private FixedChannelPoolFactory( - @Nonnull Bootstrap bootstrap, - @Nonnegative long acquireTimeoutMillis, - @Nonnull IntSupplier minConnections, - @Nonnull IntSupplier maxConnections, - @Nonnull IntSupplier maxPendingAcquires, - boolean releaseHeathCheck, - @Nonnull LongSupplier healthCheckIntervalMillis, - @Nonnull ChannelHealthChecker channelHealthChecker, - @Nullable Function healthCheckerTracker, - @Nonnull Consumer channelInitializer) { - - _bootstrap = Objects.requireNonNull(bootstrap, "bootstrap"); - _acquireTimeoutMillis = acquireTimeoutMillis; - _minConnections = minConnections; - _maxConnections = maxConnections; - _maxPendingAcquires = maxPendingAcquires; - _releaseHeathCheck = releaseHeathCheck; - _healthCheckIntervalMillis = healthCheckIntervalMillis; - _channelHealthChecker = channelHealthChecker; - _healthCheckerTracker = Optional.ofNullable(healthCheckerTracker).orElse(ignored -> NullCallTracker.INSTANCE); - _channelInitializer = Objects.requireNonNull(channelInitializer, "channelInitializer"); - } - - public void setUsingFastPool(boolean usingFastPool) { - _usingFastPool = usingFastPool; - } - - public boolean isUsingFastPool() { - return _usingFastPool; - } - - public void setUseQueueSizeForAcquiredChannelCount(@Nonnull BooleanSupplier useQueueSizeForAcquiredChannelCount) { - _useQueueSizeForAcquiredChannelCount = useQueueSizeForAcquiredChannelCount; - } - - public void setMinConnections(@Nonnegative int minConnections) { - setMinConnections(Integer.valueOf(minConnections)::intValue); - } - - public void setAcquireTimeoutAction(@Nonnull FixedChannelPool.AcquireTimeoutAction action) { - _acquireTimeoutAction = Objects.requireNonNull(action); - } - - public void setMinConnections(@Nonnull IntSupplier minConnections) { - _minConnections = minConnections; - } - - public int getMinConnections() { - return _minConnections.getAsInt(); - } - - public int getMaxConnections() { - return _maxConnections.getAsInt(); - } - - public int getMaxPendingAcquires() { - return _maxPendingAcquires.getAsInt(); - } - - public long getAcquireTimeoutMillis() { - return _acquireTimeoutMillis; - } - - @Override - @Nonnull - public ManagedChannelPool construct( - @Nonnull ChannelPoolManager manager, - @Nonnull ChannelPoolHandler handler, - @Nonnull EventLoopGroup eventLoop, - @Nonnull InetSocketAddress address) { - - int subpoolCount = manager.subpoolCount(); - IntSupplier minConnections = () -> Math.max(1, (getMinConnections() + subpoolCount - 1) / subpoolCount); - int maxConnections = Math.max(1, (getMaxConnections() + subpoolCount - 1) / subpoolCount); - - _log.debug( - "FixedChannelPool - acquireTimeoutMillis={}, minConnections={}, maxConnections={}, maxPendingAcquires={}, releaseHealthCheck={}", - getAcquireTimeoutMillis(), - minConnections.getAsInt(), - maxConnections, - _maxPendingAcquires, - _releaseHeathCheck); - - return construct( - _bootstrap.clone(eventLoop).remoteAddress(address).attr(CHANNEL_POOL_HANDLER, handler), - new ChannelPoolHandler() { - @Override - public void channelReleased(Channel ch) throws Exception { - handler.channelReleased(ch); - } - - @Override - public void channelAcquired(Channel ch) throws Exception { - handler.channelAcquired(ch); - } - - @Override - public void channelCreated(Channel ch) throws Exception { - _channelInitializer.accept(ch); - handler.channelCreated(ch); - } - }, - this, - _acquireTimeoutAction, - minConnections, - maxConnections, - _releaseHeathCheck); - } - - @Nonnull - protected ManagedChannelPool construct( - @Nonnull Bootstrap bootstrap, - @Nonnull ChannelPoolHandler channelPoolHandler, - @Nonnull ChannelHealthChecker healthChecker, - @Nonnull FixedChannelPool.AcquireTimeoutAction acquireTimeoutAction, - @Nonnull IntSupplier minConnections, - int maxConnections, - boolean releaseHeathCheck) { - if (_usingFastPool) { - return new FixedFastChannelPoolImpl( - bootstrap, - channelPoolHandler, - healthChecker, - acquireTimeoutAction, - getAcquireTimeoutMillis(), - minConnections, - maxConnections, - getMaxPendingAcquires(), - releaseHeathCheck, - 1, - _useQueueSizeForAcquiredChannelCount); - } - return new FixedChannelPoolImpl( - bootstrap, - channelPoolHandler, - healthChecker, - acquireTimeoutAction, - getAcquireTimeoutMillis(), - minConnections, - maxConnections, - getMaxPendingAcquires(), - releaseHeathCheck, - false, - _useQueueSizeForAcquiredChannelCount); - } - - public void setHealthCheckIntervalMillis(@Nonnegative long healthCheckIntervalMillis) { - setHealthCheckIntervalMillis(Long.valueOf(healthCheckIntervalMillis)::longValue); - } - - public void setHealthCheckIntervalMillis(@Nonnull LongSupplier healthCheckIntervalMillis) { - _healthCheckIntervalMillis = healthCheckIntervalMillis; - } - - public long getHealthCheckIntervalMillis() { - return _healthCheckIntervalMillis.getAsLong(); - } - - @Override - public Future isHealthy(Channel channel) { - - if (!channel.isActive()) { - return channel.eventLoop().newSucceededFuture(Boolean.FALSE); - } - - if (_channelHealthChecker != null) { - Attribute attribute = channel.attr(LAST_HEALTHCHECK_TIMESTAMP); - Long lastHealthCheckTimestamp = attribute.get(); - - if (lastHealthCheckTimestamp == null - || lastHealthCheckTimestamp + getHealthCheckIntervalMillis() < Time.currentTimeMillis()) { - CallCompletion completion = Optional.ofNullable(_healthCheckerTracker.apply(channel.remoteAddress())) - .orElse(NullCallTracker.INSTANCE) - .startCall(); - - // TODO(acurtis) probably should add a healthcheck timeout using the netty hashedwheeltimer - - return _channelHealthChecker.isHealthy(channel).addListener((Future future) -> { - if (future.isSuccess()) { - if (Boolean.TRUE == future.getNow()) { - completion.close(); - attribute.set(Time.currentTimeMillis()); - } else { - completion.closeWithError(); - channel.attr(ChannelPoolManager.FAILED_HEALTH_CHECK).set(true); - } - } else { - completion.closeWithError(future.cause()); - channel.attr(ChannelPoolManager.FAILED_HEALTH_CHECK).set(true); - } - }); - } - } - return channel.eventLoop().newSucceededFuture(Boolean.TRUE); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/FixedChannelPoolImpl.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/FixedChannelPoolImpl.java deleted file mode 100644 index ddb451cbb5f..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/FixedChannelPoolImpl.java +++ /dev/null @@ -1,405 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import com.linkedin.alpini.base.misc.ExceptionUtil; -import io.netty.bootstrap.Bootstrap; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.EventLoop; -import io.netty.channel.group.ChannelGroup; -import io.netty.channel.group.ChannelGroupFuture; -import io.netty.channel.group.DefaultChannelGroup; -import io.netty.channel.pool.ChannelHealthChecker; -import io.netty.channel.pool.ChannelPoolHandler; -import io.netty.channel.pool.FixedChannelPool; -import io.netty.util.AsciiString; -import io.netty.util.Attribute; -import io.netty.util.AttributeKey; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.ImmediateEventExecutor; -import io.netty.util.concurrent.Promise; -import java.net.ConnectException; -import java.net.SocketAddress; -import java.util.concurrent.TimeUnit; -import java.util.function.BooleanSupplier; -import java.util.function.IntSupplier; -import javax.annotation.Nonnull; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** - * Created by acurtis on 5/8/18. - */ -public class FixedChannelPoolImpl extends EspressoFixedChannelPool implements ManagedChannelPool { - private static final Logger LOG = LogManager.getLogger(FixedChannelPoolImpl.class); - - private final String _name; - private IntSupplier _minConnections; - private int _connectsInProgress; - private boolean _growInProgress; - private final ChannelGroup _channelGroup; - private final Promise _closing; - private final Future _closeFuture; - private final EventLoop _eventLoop; - private final BooleanSupplier _useQueueSizeForAcquiredChannelCount; - - public FixedChannelPoolImpl( - @Nonnull Bootstrap bootstrap, - @Nonnull ChannelPoolHandler handler, - @Nonnull ChannelHealthChecker healthCheck, - @Nonnull FixedChannelPool.AcquireTimeoutAction action, - long acquireTimeoutMillis, - @Nonnull IntSupplier minConnections, - int maxConnections, - int maxPendingAcquires, - boolean releaseHealthCheck, - boolean lastRecentUsed) { - this( - bootstrap, - handler, - healthCheck, - action, - acquireTimeoutMillis, - minConnections, - maxConnections, - maxPendingAcquires, - releaseHealthCheck, - lastRecentUsed, - () -> false); - } - - public FixedChannelPoolImpl( - @Nonnull Bootstrap bootstrap, - @Nonnull ChannelPoolHandler handler, - @Nonnull ChannelHealthChecker healthCheck, - @Nonnull FixedChannelPool.AcquireTimeoutAction action, - long acquireTimeoutMillis, - int minConnections, - int maxConnections, - int maxPendingAcquires, - boolean releaseHealthCheck, - boolean lastRecentUsed) { - this( - bootstrap, - handler, - healthCheck, - action, - acquireTimeoutMillis, - Integer.valueOf(minConnections)::intValue, - maxConnections, - maxPendingAcquires, - releaseHealthCheck, - lastRecentUsed, - () -> false); - } - - public FixedChannelPoolImpl( - @Nonnull Bootstrap bootstrap, - @Nonnull ChannelPoolHandler handler, - @Nonnull ChannelHealthChecker healthCheck, - @Nonnull FixedChannelPool.AcquireTimeoutAction action, - long acquireTimeoutMillis, - int minConnections, - int maxConnections, - int maxPendingAcquires, - boolean releaseHealthCheck, - boolean lastRecentUsed, - @Nonnull BooleanSupplier useQueueSizeForAcquiredChannelCount) { - this( - bootstrap, - handler, - healthCheck, - action, - acquireTimeoutMillis, - Integer.valueOf(minConnections)::intValue, - maxConnections, - maxPendingAcquires, - releaseHealthCheck, - lastRecentUsed, - useQueueSizeForAcquiredChannelCount); - } - - public FixedChannelPoolImpl( - @Nonnull Bootstrap bootstrap, - @Nonnull ChannelPoolHandler handler, - @Nonnull ChannelHealthChecker healthCheck, - @Nonnull FixedChannelPool.AcquireTimeoutAction action, - long acquireTimeoutMillis, - @Nonnull IntSupplier minConnections, - int maxConnections, - int maxPendingAcquires, - boolean releaseHealthCheck, - boolean lastRecentUsed, - @Nonnull BooleanSupplier useQueueSizeForAcquiredChannelCount) { - super( - bootstrap, - handler, - healthCheck, - action, - acquireTimeoutMillis, - maxConnections, - maxPendingAcquires, - releaseHealthCheck, - lastRecentUsed); - _name = bootstrap.config().remoteAddress().toString(); - _eventLoop = bootstrap.config().group().next(); - _channelGroup = new DefaultChannelGroup(_name, _eventLoop, true) { - @Override - public boolean remove(Object o) { - if (super.remove(o)) { - LOG.info("closing channel {}", o); - if (o instanceof Channel) { - Channel ch = (Channel) o; - if (ch.hasAttr(CHECKED_OUT) && Boolean.TRUE.equals(ch.attr(CHECKED_OUT).get())) { - release(ch, _eventLoop.newPromise()); - } - } - return true; - } else { - return false; - } - } - }; - Promise closeFuture = _eventLoop.newPromise(); - _closing = _eventLoop.newPromise().addListener(f -> { - LOG.info("begin closing pool {}", bootstrap.config().remoteAddress()); - - super.closeAsync().addListener(closeAsyncFuture -> { - /* Close on super (EspressoFixedChannelPool) sets the pool to closed state and calls close on channels not in - use. Doesn't wait for the actual channels to close. To close the channels that are in use, we call close on - channel group. So that we can handle any requests in pipeline. For the requests in the pipeline, a premature - close exception is set in HttpClientHandler's ResponseConsumer (StorageNodeRequest) accept */ - ChannelGroupFuture groupClose = _channelGroup.close(); - - if (!groupClose.isDone()) { - Future scheduleFuture = _eventLoop.schedule(() -> { - LOG.info("Force closing connections to {}", bootstrap.config().remoteAddress()); - _channelGroup.forEach(channel -> { - try { - if (channel.isActive()) { - channel.eventLoop().submit(() -> channel.unsafe().close(channel.voidPromise())); - } - } catch (Exception e) { - // Ignore the Exception - LOG.warn("couldn't force close the connection {}", bootstrap.config().remoteAddress()); - } - }); - }, 5000, TimeUnit.MILLISECONDS); - - groupClose.addListener(groupClosed -> scheduleFuture.cancel(false)); - } - - // Marks the close successful - closeFuture.setSuccess(null); - LOG.info("end closing pool {}", bootstrap.config().remoteAddress()); - }); - }); - - _closeFuture = closeFuture; - setMinConnections(minConnections); - _useQueueSizeForAcquiredChannelCount = useQueueSizeForAcquiredChannelCount; - } - - @Override - public String name() { - return _name; - } - - @Override - public ChannelPoolHandler handler() { - return super.handler(); - } - - @Override - public int getConnectedChannels() { - return _channelGroup.size(); - } - - public void setMinConnections(int minConnections) { - setMinConnections(Integer.valueOf(minConnections)::intValue); - } - - public void setMinConnections(@Nonnull IntSupplier minConnections) { - _minConnections = minConnections; - } - - public int getMinConnections() { - return _minConnections.getAsInt(); - } - - private boolean needsMoreConnections() { - return !isClosing() && getConnectedChannels() + _connectsInProgress < getMinConnections(); - } - - private void addCloseListener(ChannelFuture future) { - _channelGroup.add(future.channel()); - } - - protected ChannelFuture connectChannel0(Bootstrap bs) { - _connectsInProgress++; - return super.connectChannel(bs); - } - - @Override - protected ChannelFuture connectChannel(Bootstrap bs) { - return connectChannel0(bs).addListener((ChannelFuture future) -> { - _connectsInProgress--; - if (future.isSuccess()) { - addCloseListener(future); - if (!_growInProgress && needsMoreConnections()) { - connectChannel0(bs).addListener(new GrowPoolSize(bs)); - } - } - }); - } - - @Override - public boolean isHealthy() { - return getConnectedChannels() >= Math.max(1, getMinConnections()); - } - - static final AttributeKey CHECKED_OUT = AttributeKey.valueOf(FixedChannelPoolImpl.class, "checkedOut"); - - @Override - public Future acquire(Promise promise) { - Promise p = _eventLoop.newPromise(); - super.acquire(p); - p.addListener((Future f) -> { - if (f.isSuccess() && f.getNow() != null) { - Attribute checkedOut = f.getNow().attr(CHECKED_OUT); - checkedOut.set(Boolean.TRUE); - if (!promise.trySuccess(f.getNow())) { - checkedOut.set(false); - super.release(f.getNow(), _eventLoop.newPromise()); - } - } else if (f.cause() != null) { - promise.tryFailure(f.cause()); - } else { - promise.tryFailure(new IllegalStateException("Failed to retrieve connection from pool")); - } - }); - return promise; - } - - @Override - public Future release(Channel channel, Promise promise) { - if (!channel.hasAttr(CHECKED_OUT)) { - // Channel was not checked out, do nothing here. - return promise.setSuccess(null); - } - - Attribute checkedOut = channel.attr(CHECKED_OUT); - if (Boolean.TRUE.equals(checkedOut.getAndSet(false))) { - try { - super.release(channel, _eventLoop.newPromise()).addListener((Future future) -> { - if (future.isSuccess()) { - promise.trySuccess(future.getNow()); - } else if ((future.cause() instanceof IllegalStateException) - && AsciiString.contains(future.cause().getMessage(), "closed")) { - // Pool is already closed, ignore the exception - } else { - LOG.warn("Release failed with unexpected exception", future.cause()); - promise.setFailure(future.cause()); - } - }); - } catch (Exception e) { - LOG.warn("A really unexpected exception occurred", e); - promise.setFailure(e); - } - return promise; - } else { - return promise.setSuccess(null); - } - } - - @Override - public void close() { - _closing.trySuccess(null); - } - - @Override - public final Future closeFuture() { - return _closeFuture; - } - - public final boolean isClosing() { - return _closing.isDone(); - } - - @Override - public int acquiredChannelCount() { - /** Returns the number of channels in use based on queue size. - * - * This can be calculated using channelGroup (ChannelGroup has a list of all the healthy channels, this pool owns) - * and getAvailableChannels (gets the number of channels in the SimpleChannelPool, not checked out). - */ - if (_useQueueSizeForAcquiredChannelCount.getAsBoolean()) { - int newAcquiredChannelCount = (_channelGroup.size() - getAvailableChannels()) + _connectsInProgress; - // acquired channel count can never be less than zero - if (newAcquiredChannelCount < 0) { - LOG.warn( - "Negative acquired channel count {} (group size {}, deque size {}, connectsInProgress {}) for {}", - newAcquiredChannelCount, - _channelGroup.size(), - getAvailableChannels(), - _connectsInProgress, - bootstrap().config().remoteAddress()); - return super.acquiredChannelCount(); - } - int oldAcquiredChannelCount = super.acquiredChannelCount(); - if (newAcquiredChannelCount != oldAcquiredChannelCount) { - LOG.warn( - "The acquired channel count based on the queue size is {} (group size {}, deque size {}, connectsInProgress {}) " - + "doesn't match {} FixedChannelPool acquiredChannelCount {} ", - newAcquiredChannelCount, - _channelGroup.size(), - getAvailableChannels(), - _connectsInProgress, - bootstrap().config().remoteAddress(), - oldAcquiredChannelCount); - } - return newAcquiredChannelCount; - } - return super.acquiredChannelCount(); - } - - private class GrowPoolSize implements ChannelFutureListener { - private final Bootstrap _bootstrap; - - private GrowPoolSize(Bootstrap bootstrap) { - _bootstrap = bootstrap; - _growInProgress = true; - LOG.debug( - "Growing connections {} from {} to {}", - bootstrap.config().remoteAddress(), - getConnectedChannels(), - getMinConnections()); - } - - @Override - public void operationComplete(ChannelFuture future) throws Exception { - _connectsInProgress--; - if (future.isSuccess()) { - addCloseListener(future); - incrementAcquiredChannelCount(); - FixedChannelPoolImpl.super.release(future.channel(), ImmediateEventExecutor.INSTANCE.newPromise()); - if (needsMoreConnections()) { - connectChannel0(_bootstrap).addListener(this); - return; - } - } else { - notifyGrowFailure(_bootstrap.config().remoteAddress(), ExceptionUtil.unwrapCompletion(future.cause())); - } - _growInProgress = false; - } - } - - protected void notifyGrowFailure(SocketAddress remoteAddress, Throwable cause) { - if (cause instanceof ConnectException) { - LOG.info("Pool grow ConnectException: {} {}", remoteAddress, cause.getMessage()); - } else { - LOG.warn("Pool grow failure: {}", remoteAddress, cause); - } - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/FixedFastChannelPoolImpl.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/FixedFastChannelPoolImpl.java deleted file mode 100644 index f7544f93e08..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/FixedFastChannelPoolImpl.java +++ /dev/null @@ -1,431 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import io.netty.bootstrap.Bootstrap; -import io.netty.channel.Channel; -import io.netty.channel.EventLoop; -import io.netty.channel.group.ChannelGroupFuture; -import io.netty.channel.pool.ChannelHealthChecker; -import io.netty.channel.pool.ChannelPoolHandler; -import io.netty.channel.pool.FixedChannelPool; -import io.netty.util.AsciiString; -import io.netty.util.Attribute; -import io.netty.util.AttributeKey; -import io.netty.util.concurrent.DefaultPromise; -import io.netty.util.concurrent.EventExecutor; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.Promise; -import java.net.ConnectException; -import java.net.SocketAddress; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; -import java.util.function.BooleanSupplier; -import java.util.function.IntSupplier; -import javax.annotation.Nonnull; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** - * Created by acurtis on 5/8/18. - */ -public class FixedFastChannelPoolImpl extends FastFixedChannelPool implements ManagedChannelPool { - private static final Logger LOG = LogManager.getLogger(FixedFastChannelPoolImpl.class); - - private static final AtomicIntegerFieldUpdater GROW_IN_PROGRESS = - AtomicIntegerFieldUpdater.newUpdater(FixedFastChannelPoolImpl.class, "_growInProgress"); - - private IntSupplier _minConnections; - private volatile int _growInProgress = 0; - private final Promise _closing; - private final Future _closeFuture; - private final BooleanSupplier _useQueueSizeForAcquiredChannelCount; - - public FixedFastChannelPoolImpl( - @Nonnull Bootstrap bootstrap, - @Nonnull ChannelPoolHandler handler, - @Nonnull ChannelHealthChecker healthCheck, - @Nonnull FixedChannelPool.AcquireTimeoutAction action, - long acquireTimeoutMillis, - @Nonnull IntSupplier minConnections, - int maxConnections, - int maxPendingAcquires, - boolean releaseHealthCheck, - int connectConcurrency) { - this( - bootstrap, - handler, - healthCheck, - action, - acquireTimeoutMillis, - minConnections, - maxConnections, - maxPendingAcquires, - releaseHealthCheck, - connectConcurrency, - () -> false); - } - - public FixedFastChannelPoolImpl( - @Nonnull Bootstrap bootstrap, - @Nonnull ChannelPoolHandler handler, - @Nonnull ChannelHealthChecker healthCheck, - @Nonnull FixedChannelPool.AcquireTimeoutAction action, - long acquireTimeoutMillis, - int minConnections, - int maxConnections, - int maxPendingAcquires, - boolean releaseHealthCheck, - int connectConcurrency) { - this( - bootstrap, - handler, - healthCheck, - action, - acquireTimeoutMillis, - Integer.valueOf(minConnections)::intValue, - maxConnections, - maxPendingAcquires, - releaseHealthCheck, - connectConcurrency, - () -> false); - } - - public FixedFastChannelPoolImpl( - @Nonnull Bootstrap bootstrap, - @Nonnull ChannelPoolHandler handler, - @Nonnull ChannelHealthChecker healthCheck, - @Nonnull FixedChannelPool.AcquireTimeoutAction action, - long acquireTimeoutMillis, - int minConnections, - int maxConnections, - int maxPendingAcquires, - boolean releaseHealthCheck, - int connectConcurrency, - @Nonnull BooleanSupplier useQueueSizeForAcquiredChannelCount) { - this( - bootstrap, - handler, - healthCheck, - action, - acquireTimeoutMillis, - Integer.valueOf(minConnections)::intValue, - maxConnections, - maxPendingAcquires, - releaseHealthCheck, - connectConcurrency, - useQueueSizeForAcquiredChannelCount); - } - - public FixedFastChannelPoolImpl( - @Nonnull Bootstrap bootstrap, - @Nonnull ChannelPoolHandler handler, - @Nonnull ChannelHealthChecker healthCheck, - @Nonnull FixedChannelPool.AcquireTimeoutAction action, - long acquireTimeoutMillis, - @Nonnull IntSupplier minConnections, - int maxConnections, - int maxPendingAcquires, - boolean releaseHealthCheck, - int connectConcurrency, - @Nonnull BooleanSupplier useQueueSizeForAcquiredChannelCount) { - super( - bootstrap, - handler, - healthCheck, - action, - acquireTimeoutMillis, - maxConnections, - maxPendingAcquires, - releaseHealthCheck, - connectConcurrency); - EventLoop eventLoop = bootstrap.config().group().next(); - Promise closeFuture = eventLoop.newPromise(); - _closing = eventLoop.newPromise().addListener(f -> { - LOG.info("begin closing pool {}", bootstrap.config().remoteAddress()); - - super.closeAsync().addListener(closeAsyncFuture -> { - /* Close on super (EspressoFixedChannelPool) sets the pool to closed state and calls close on channels not in - use. Doesn't wait for the actual channels to close. To close the channels that are in use, we call close on - channel group. So that we can handle any requests in pipeline. For the requests in the pipeline, a premature - close exception is set in HttpClientHandler's ResponseConsumer (StorageNodeRequest) accept */ - ChannelGroupFuture groupClose = _channelGroup.close(); - - if (!groupClose.isDone()) { - Future scheduleFuture = eventLoop.schedule(() -> { - LOG.info("Force closing connections to {}", bootstrap.config().remoteAddress()); - _channelGroup.forEach(channel -> { - try { - if (channel.isActive()) { - channel.eventLoop().submit(() -> channel.unsafe().close(channel.voidPromise())); - } - } catch (Exception e) { - // Ignore the Exception - LOG.warn("couldn't force close the connection {}", bootstrap.config().remoteAddress()); - } - }); - }, 5000, TimeUnit.MILLISECONDS); - - groupClose.addListener(groupClosed -> scheduleFuture.cancel(false)); - } - - LOG.info("end closing pool {}", bootstrap.config().remoteAddress()); - // Marks the close successful - closeFuture.setSuccess(null); - }); - }); - - _closeFuture = closeFuture; - setMinConnections(minConnections); - _useQueueSizeForAcquiredChannelCount = useQueueSizeForAcquiredChannelCount; - } - - @Override - protected PoolChannelGroup newPoolChannelGroup() { - return new FixedPoolChannelGroup(name()); - } - - protected class FixedPoolChannelGroup extends PoolChannelGroup { - protected FixedPoolChannelGroup(String name) { - super(name); - } - - @Override - public boolean remove(Object o) { - if (super.remove(o)) { - LOG.info("closing channel {}", o); - release((Channel) o, _immediateEventExecutor.newPromise()); - return true; - } else { - return false; - } - } - } - - @Override - public ChannelPoolHandler handler() { - return super.handler(); - } - - @Override - public int getConnectedChannels() { - return _channelGroup.size(); - } - - public void setMinConnections(int minConnections) { - setMinConnections(Integer.valueOf(minConnections)::intValue); - } - - public void setMinConnections(@Nonnull IntSupplier minConnections) { - _minConnections = minConnections; - } - - public int getMinConnections() { - return _minConnections.getAsInt(); - } - - private boolean needsMoreConnections() { - return !isClosing() && getConnectedChannels() + connectInProgress() < getMinConnections(); - } - - @Override - protected boolean acquireConnectSemaphore() { - return getConnectedChannels() + connectInProgress() < getMaxConnections() && super.acquireConnectSemaphore(); - } - - @Override - protected void onConnect(Channel ch, Promise promise) { - if (ch != null) { - assert _channelGroup.contains(ch); - if (promise instanceof GrowPoolSize) { - if (needsMoreConnections()) { - GROW_IN_PROGRESS.incrementAndGet(this); - growPoolSize(); - } - } else { - checkGrowPoolSize(); - } - } - super.onConnect(ch, promise); - } - - @Override - protected Future connectChannel(Bootstrap bs, Promise promise) { - return connectChannel0(bs, promise); - } - - protected Future connectChannel0(Bootstrap bs, Promise promise) { - return super.connectChannel(bs, promise); - } - - private void checkGrowPoolSize() { - if (isClosing()) { - return; - } - if (_growInProgress == 0 && needsMoreConnections() && GROW_IN_PROGRESS.compareAndSet(this, 0, 1)) { - growPoolSize(); - } - } - - private void growPoolSize() { - assert _growInProgress > 0; - if (acquireConnectSemaphore()) { - if (getConnectedChannels() + connectInProgress() > getMinConnections()) { - releaseConnectSemaphore(); - return; - } - Promise grow = new GrowPoolSize(_immediateEventExecutor).addListener((Future future) -> { - GROW_IN_PROGRESS.decrementAndGet(this); - if (future.isSuccess()) { - assert future.getNow() == null : "Expected null"; - // We expected null because the GrowPoolSize.isDone() method should complete the promise with null - // and after the connection is established, FastSimpleChannelPool.notifyConnect will first check - // the promise with isDone before trying to complete it. - } else { - notifyGrowFailure(bootstrap().config().remoteAddress(), future.cause()); - } - }); - try { - bootstrapChannel(grow); - } catch (Throwable ex) { - if (!grow.tryFailure(ex)) { - LOG.info("Exception trying to grow pool", ex); - } - } - } else { - GROW_IN_PROGRESS.decrementAndGet(this); - } - } - - @Override - public boolean isHealthy() { - return getConnectedChannels() >= Math.max(1, getMinConnections()); - } - - static final AttributeKey CHECKED_OUT = AttributeKey.valueOf(FixedFastChannelPoolImpl.class, "checkedOut"); - - @Override - public Future acquire(Promise promise) { - Promise p = _immediateEventExecutor.newPromise(); - super.acquire(p); - p.addListener((Future f) -> { - if (f.isSuccess() && f.getNow() != null) { - Attribute checkedOut = f.getNow().attr(CHECKED_OUT); - checkedOut.set(Boolean.TRUE); - if (!promise.trySuccess(f.getNow())) { - checkedOut.set(false); - super.release(f.getNow(), _immediateEventExecutor.newPromise()); - } - } else if (f.cause() != null) { - promise.tryFailure(f.cause()); - } else { - promise.tryFailure(new IllegalStateException("Failed to retrieve connection from pool")); - } - }); - if (!p.isDone()) { - checkGrowPoolSize(); - } - return promise; - } - - @Override - public Future release(Channel channel, Promise promise) { - if (!channel.hasAttr(CHECKED_OUT)) { - return super.release(channel, promise); - } - - Attribute checkedOut = channel.attr(CHECKED_OUT); - if (checkedOut.get()) { - checkedOut.set(Boolean.FALSE); - try { - super.release(channel, _immediateEventExecutor.newPromise()).addListener((Future future) -> { - if (future.isSuccess()) { - promise.trySuccess(future.getNow()); - checkGrowPoolSize(); - } else if ((future.cause() instanceof IllegalStateException) - && AsciiString.contains(future.cause().getMessage(), "closed")) { - // Pool is already closed, ignore the exception - } else { - LOG.warn("Release failed with unexpected exception", future.cause()); - promise.setFailure(future.cause()); - } - }); - } catch (Exception e) { - LOG.warn("A really unexpected exception occurred", e); - promise.setFailure(e); - } - return promise; - } else { - return promise.setSuccess(null); - } - } - - @Override - public void close() { - _closing.trySuccess(null); - } - - @Override - public final Future closeFuture() { - return _closeFuture; - } - - public final boolean isClosing() { - return _closing.isDone(); - } - - @Override - public int acquiredChannelCount() { - /** Returns the number of channels in use based on queue size. - * - * This can be calculated using channelGroup (ChannelGroup has a list of all the healthy channels, this pool owns) - * and getAvailableChannels (gets the number of channels in the SimpleChannelPool, not checked out). - */ - if (_useQueueSizeForAcquiredChannelCount.getAsBoolean()) { - int availableChannels = getAvailableChannels(); - int channelGroupSize = _channelGroup.size(); - int newAcquiredChannelCount = (channelGroupSize - availableChannels); - // acquired channel count can never be less than zero - if (newAcquiredChannelCount < 0) { - LOG.warn( - "Negative acquired channel count {} (group size {}, deque size {}) for {}", - newAcquiredChannelCount, - channelGroupSize, - availableChannels, - bootstrap().config().remoteAddress()); - return super.acquiredChannelCount(); - } - int oldAcquiredChannelCount = super.acquiredChannelCount(); - if (newAcquiredChannelCount != oldAcquiredChannelCount) { - LOG.warn( - "The acquired channel count based on the queue size is {} (group size {}, deque size {}) " - + "doesn't match {} FixedChannelPool acquiredChannelCount {} ", - newAcquiredChannelCount, - channelGroupSize, - availableChannels, - bootstrap().config().remoteAddress(), - oldAcquiredChannelCount); - } - return newAcquiredChannelCount; - } - return super.acquiredChannelCount(); - } - - static class GrowPoolSize extends DefaultPromise { - public GrowPoolSize(EventExecutor executor) { - super(executor); - } - - @Override - public boolean isDone() { - return super.isDone() || trySuccess(null); - } - } - - protected void notifyGrowFailure(SocketAddress remoteAddress, Throwable cause) { - if (cause instanceof ConnectException) { - LOG.info("Pool grow ConnectException: {} {}", remoteAddress, cause.getMessage()); - } else { - LOG.warn("Pool grow failure: {}", remoteAddress, cause); - } - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/Http2AwareChannelPool.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/Http2AwareChannelPool.java deleted file mode 100644 index 25d009dea6d..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/Http2AwareChannelPool.java +++ /dev/null @@ -1,680 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import com.linkedin.alpini.netty4.handlers.ChannelInitializer; -import com.linkedin.alpini.netty4.handlers.HttpObjectToBasicHttpObjectAdapter; -import com.linkedin.alpini.netty4.http2.Http2StreamFrameClientCodec; -import com.linkedin.alpini.netty4.misc.Http2Utils; -import com.linkedin.alpini.netty4.misc.NettyUtils; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelPipeline; -import io.netty.channel.group.ChannelGroup; -import io.netty.channel.group.DefaultChannelGroup; -import io.netty.channel.pool.ChannelPoolHandler; -import io.netty.handler.codec.http2.EspressoHttp2MultiplexHandler; -import io.netty.handler.codec.http2.EspressoHttp2StreamChannelBootstrap; -import io.netty.handler.codec.http2.Http2Connection; -import io.netty.handler.codec.http2.Http2FrameCodec; -import io.netty.handler.codec.http2.Http2StreamChannel; -import io.netty.handler.codec.http2.Http2StreamFrameToHttpObjectCodec; -import io.netty.util.AttributeKey; -import io.netty.util.concurrent.EventExecutorGroup; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.FutureListener; -import io.netty.util.concurrent.ImmediateEventExecutor; -import io.netty.util.concurrent.Promise; -import java.nio.channels.ShutdownChannelGroupException; -import java.util.Objects; -import java.util.Optional; -import java.util.Queue; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.Semaphore; -import java.util.concurrent.atomic.LongAdder; -import java.util.function.Consumer; -import javax.annotation.Nullable; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** - * A ChannelPool Wrapper that would return either a ChannelPool if the request is an HTTP 1.1 request or - * A Stream if HTTP2 - */ -public class Http2AwareChannelPool implements ManagedChannelPool { - private static final Logger LOG = LogManager.getLogger(Http2AwareChannelPool.class); - - private static final AttributeKey BOOTSTRAP_ATTRIBUTE_KEY = - AttributeKey.valueOf(Http2AwareChannelPool.class, "http2Bootstrap"); - private static final AttributeKey> RECYCLE_STREAMS_KEY = - AttributeKey.valueOf(Http2AwareChannelPool.class, "recycleQueue"); - - // Consumers of the stream channel should set this attribute to true so that it can be reused - public static final AttributeKey HTTP2_STREAM_CHANNEL_AVAILABLE_FOR_REUSE = - AttributeKey.valueOf(Http2AwareChannelPool.class, "http2StreamChannelAvailableForReuse"); - public static final AttributeKey HTTP2_REUSED_STREAM_CHANNEL = - AttributeKey.valueOf(Http2AwareChannelPool.class, "http2ReusedStreamChannel"); - public static final AttributeKey HTTP2_CONNECTION = - AttributeKey.valueOf(Http2AwareChannelPool.class, "http2Connection"); - - // We maintain a ChannelGroup which contains all the stream channels created for a h2 connection. - // This allows us to close them all should the h2 connection suddenly fails due to network glitch. - /* package */ static final AttributeKey STREAM_GROUP = - AttributeKey.valueOf(Http2AwareChannelPool.class, "streamGroup"); - - public static final int DEFAULT_MAX_REUSE_STREAM_CHANNELS_LIMIT = 100; - public static final int DEFAULT_MAX_CONCURRENT_STREAMS = 500; - // 1 initial acquire attempt + 2 retry attempts = 3 acquire attempts allowed in total - private static final int MAX_ACQUIRE_RETRY_LIMIT = 2; - - private final ManagedChannelPool _parentPool; - - // preStreamChannelInitializer would be called before this class's own ChannelInitializer calling p.addLast, giving - // the outsider a chance to insert any handler before Http2AwareChannelPool's own handler. - private final Consumer _preStreamChannelInitializer; - - // postStreamChannelInitializer would be called after this class's own ChannelInitializer calling p.addLast, giving - // the outsider a chance to append any handler after Http2AwareChannelPool's own handler. - private final Consumer _postStreamChannelInitializer; - - // set only by setMoreThanOneHttp2Connection, indicates if the pool should try to - // create more than one HTTP/2 connection. - private boolean _moreThanOneHttp2Connection; - - // Semaphore to guard extra HTTP/2 connection creation. - private final Semaphore _extraHttp2Connections = new Semaphore(1); - - private final ChannelHandler _basicHttpAdapter = new HttpObjectToBasicHttpObjectAdapter(); - - // Channel group of HTTP/2 connections created by this pool. - private final ChannelGroup _http2ChannelGroup; - - // Global channel group of HTTP/2 connections, this will allow us to keep track of the total number of HTTP/2 - // connections - private final Consumer _allHttp2ChannelGroup; - - private final LongAdder _activeStreamsLimitReachedCount = new LongAdder(); - private final LongAdder _totalStreamsReused = new LongAdder(); - private final LongAdder _totalStreamCreations = new LongAdder(); - private final LongAdder _currentStreamsReused = new LongAdder(); - private final LongAdder _totalAcquireRetries = new LongAdder(); - private final LongAdder _totalActiveStreamChannels = new LongAdder(); - - // Use custom codec - private boolean _useCustomH2Codec = false; - - private boolean _channelReuse = false; - private boolean _retryOnMaxStreamsLimit = false; - private int _maxReuseStreamChannelsLimit = DEFAULT_MAX_REUSE_STREAM_CHANNELS_LIMIT; - private long _maxConcurrentStreamsLimit = DEFAULT_MAX_CONCURRENT_STREAMS; - - public Http2AwareChannelPool( - ManagedChannelPool parentPool, - Consumer preStreamChannelInitializer, - Consumer postStreamInitializer) { - this(parentPool, preStreamChannelInitializer, postStreamInitializer, true); - } - - public Http2AwareChannelPool( - ManagedChannelPool parentPool, - Consumer preStreamChannelInitializer, - Consumer postStreamInitializer, - boolean moreThanOneHttp2Connection) { - this(parentPool, preStreamChannelInitializer, postStreamInitializer, moreThanOneHttp2Connection, null); - } - - public Http2AwareChannelPool( - ManagedChannelPool parentPool, - Consumer preStreamChannelInitializer, - Consumer postStreamInitializer, - boolean moreThanOneHttp2Connection, - ChannelGroup http2ChannelGroup) { - _parentPool = Objects.requireNonNull(parentPool, "parentPool"); - _preStreamChannelInitializer = Objects.requireNonNull(preStreamChannelInitializer, "preStreamChannelInitializer"); - _postStreamChannelInitializer = Objects.requireNonNull(postStreamInitializer, "postStreamInitializer"); - _moreThanOneHttp2Connection = moreThanOneHttp2Connection; - _http2ChannelGroup = new DefaultChannelGroup(name(), ImmediateEventExecutor.INSTANCE); - _allHttp2ChannelGroup = http2ChannelGroup != null ? http2ChannelGroup::add : ch -> {}; - } - - @Override - public String name() { - return _parentPool.name(); - } - - public void setMaxConcurrentStreams(long maxConcurrentStreams) { - _maxConcurrentStreamsLimit = maxConcurrentStreams; - } - - @Override - public long getActiveStreamsLimitReachedCount() { - return _activeStreamsLimitReachedCount.longValue(); - } - - public long getMaxConcurrentStreamsLimit() { - return _maxConcurrentStreamsLimit; - } - - public void setMoreThanOneHttp2Connection(boolean value) { - _moreThanOneHttp2Connection = value; - } - - public void setChannelReuse(boolean channelReuse) { - _channelReuse = channelReuse; - } - - @Override - public long getTotalActiveStreams() { - return _http2ChannelGroup.stream() - .mapToInt(ch -> ch.pipeline().get(Http2FrameCodec.class).connection().numActiveStreams()) - .sum(); - } - - @Override - public long getCurrentStreamChannelsReused() { - return _currentStreamsReused.longValue(); - } - - @Override - public long getTotalStreamChannelsReused() { - return _totalStreamsReused.longValue(); - } - - @Override - public long getTotalStreamCreations() { - return _totalStreamCreations.longValue(); - } - - @Override - public long getTotalAcquireRetries() { - return _totalAcquireRetries.longValue(); - } - - @Override - public long getTotalActiveStreamChannels() { - return _totalActiveStreamChannels.longValue(); - } - - public boolean wantMoreThanOneHttp2Connection() { - return _moreThanOneHttp2Connection; - } - - public boolean hasMoreThanOneHttp2Connection() { - return _http2ChannelGroup.size() > 1; - } - - public boolean useCustomH2Codec() { - return _useCustomH2Codec; - } - - public void setUseCustomH2Codec(boolean useCustomH2Codec) { - _useCustomH2Codec = useCustomH2Codec; - } - - public void setMaxReuseStreamChannelsLimit(int maxReuseStreamChannelsLimit) { - _maxReuseStreamChannelsLimit = maxReuseStreamChannelsLimit; - } - - public int getMaxReuseStreamChannelsLimit() { - return _maxReuseStreamChannelsLimit; - } - - public void setRetryOnMaxStreamsLimit(boolean retryOnMaxStreamsLimit) { - _retryOnMaxStreamsLimit = retryOnMaxStreamsLimit; - } - - public boolean shouldRetryOnMaxStreamsLimit() { - return _retryOnMaxStreamsLimit; - } - - @Override - public Future acquire() { - return acquire(ImmediateEventExecutor.INSTANCE.newPromise()); - } - - protected EspressoHttp2StreamChannelBootstrap createHttp2StreamChannelBootstrap(Channel ch) { - ChannelGroup group = new DefaultChannelGroup(ch.eventLoop(), true); - ch.attr(STREAM_GROUP).set(group); - ch.closeFuture().addListener(f -> group.close()); - return new EspressoHttp2StreamChannelBootstrap(ch).handler(new ChannelInitializer() { - @Override - protected void initChannel(Channel ch) { - // commenting this line will cause TestHttp2AwareChannelPoolFactory.testHttp2WithRemoteBadConnection to fail. - group.add(ch); - ChannelPipeline p = ch.pipeline(); - EventExecutorGroup executorGroup = NettyUtils.executorGroup(ch); - _preStreamChannelInitializer.accept(ch); - if (useCustomH2Codec()) { - p.addLast(executorGroup, "child-client-frame-converter", new Http2StreamFrameClientCodec(false)); - } else { - p.addLast(executorGroup, "child-client-frame-converter", new Http2StreamFrameToHttpObjectCodec(false)); - p.addLast(executorGroup, "basic-http-from-http-converter", _basicHttpAdapter); - } - _postStreamChannelInitializer.accept(ch); - } - }); - } - - /** - * Return a new recycle queue. - * - * If queue size is within range [0, Integer.MAX_VALUE), - * Use array blocking queue to handle concurrency issues, - * and limit the number of entries allowed in the queue to avoid caching too many stream channels. - * - * Else, use unbounded ConcurrentLinkedQueue. - * @return New recycle queue - */ - private Queue newRecycleQueue() { - int queueSize = getMaxReuseStreamChannelsLimit(); - return 0 <= queueSize && queueSize < Integer.MAX_VALUE - ? new ArrayBlockingQueue<>(queueSize) - : new ConcurrentLinkedQueue<>(); - } - - @Override - public Future acquire(Promise promise) { - if (shouldRetryOnMaxStreamsLimit()) { - acquire0(ImmediateEventExecutor.INSTANCE.newPromise()).addListener(createAcquireRetryListener(promise)); - return promise; - } - return acquire0(promise); - } - - private FutureListener createAcquireRetryListener(Promise returnPromise) { - return new FutureListener() { - private int _retries = 0; - - @Override - public void operationComplete(Future future) { - if (future.isSuccess()) { - if (returnPromise.trySuccess(future.getNow())) { - return; - } - release(future.getNow()); - } else if (Http2Utils.isTooManyActiveStreamsError(future.cause()) && _retries++ < MAX_ACQUIRE_RETRY_LIMIT - && !returnPromise.isDone()) { - // If the failure is caused by too many streams exception, and we have retry budget, retry acquiring - _totalAcquireRetries.increment(); - acquire0(ImmediateEventExecutor.INSTANCE.newPromise()).addListener(this); - } else { - // If the failure is caused by other exceptions, don't retry - returnPromise.tryFailure(future.cause()); - } - } - }; - } - - protected Promise acquire0(Promise promise) { - _parentPool.acquire().addListener((Future acquired) -> { - if (acquired.isSuccess()) { - final Channel ch = acquired.getNow(); - EspressoHttp2StreamChannelBootstrap http2Bootstrap; - boolean returnChannel = true; - try { - if (isActiveStreamsLimitReached(promise, ch)) { - return; - } - if (tryReuseStreamChannel(ch.attr(RECYCLE_STREAMS_KEY).get(), promise)) { - return; - } - setupHttp2ParentChannel(ch); - http2Bootstrap = ch.attr(BOOTSTRAP_ATTRIBUTE_KEY).get(); - if (http2Bootstrap == null) { - returnChannel = !promise.trySuccess(ch); - return; - } - } catch (Throwable ex) { - promise.setFailure(ex); - return; - } finally { - if (returnChannel) { - _parentPool.release(ch); - } - } - createStreamChannel(http2Bootstrap, promise); - } else { - promise.setFailure(acquired.cause()); - } - }); - return promise; - } - - private boolean isActiveStreamsLimitReached(Promise promise, Channel ch) { - if (Http2Utils.isConfiguredHttp2Connection(ch) && !Http2Utils.canOpenLocalStream(ch)) { - tooManyActiveStreams(promise, getTotalActiveStreams()); - return true; - } - return false; - } - - private void setupHttp2ParentChannel(Channel ch) { - if (!ch.hasAttr(BOOTSTRAP_ATTRIBUTE_KEY)) { - if (Http2Utils.isHttp2ParentChannelPipeline(ch.pipeline())) { - addChannelToHttp2ChannelGroups(ch); - configureHttp2Connection(ch); - if (Http2Utils.isHttp2MultiplexPipeline(_channelReuse, ch.pipeline())) { - ch.attr(BOOTSTRAP_ATTRIBUTE_KEY).set(createHttp2StreamChannelBootstrap(ch)); - if (_channelReuse) { - createRecycleQueue(ch); - } - } else { - // Not a multiplex pipeline, there is no bootstrap - ch.attr(BOOTSTRAP_ATTRIBUTE_KEY).set(null); - } - if (wantMoreThanOneHttp2Connection() && !isClosing() && !hasMoreThanOneHttp2Connection() - && _extraHttp2Connections.tryAcquire()) { - createExtraHttp2Connection(); - } - } else { - // Not a HTTP/2 connection, Http2 bootstrap set to null - ch.attr(BOOTSTRAP_ATTRIBUTE_KEY).set(null); - } - } - } - - private void createRecycleQueue(Channel ch) { - Queue recycleQueue = newRecycleQueue(); - ch.attr(RECYCLE_STREAMS_KEY).set(recycleQueue); - } - - private void tooManyActiveStreams(Promise promise, long totalActiveStreams) { - _activeStreamsLimitReachedCount.increment(); - promise.setFailure( - Http2Utils.tooManyStreamsException( - String.format( - "Reached maxConcurrentStreamsLimit=%d, totalActiveStream=%d", - getMaxConcurrentStreamsLimit(), - totalActiveStreams))); - } - - @Deprecated - public static boolean isTooManyActiveStreamsError(Throwable t) { - return Http2Utils.isTooManyActiveStreamsError(t); - } - - private void addChannelToHttp2ChannelGroups(Channel ch) { - _http2ChannelGroup.add(ch); - _allHttp2ChannelGroup.accept(ch); - } - - /** - * Configure the HTTP/2 connection on the parent channel. - * - * The connection is added to the channel attributes for fast retrieval. - * We also override the max active streams limit after SETTINGS frame has been received from remote endpoint - * as the remote endpoint normally grants a much larger limit. - * - * @param ch Parent HTTP/2 channel - */ - private void configureHttp2Connection(Channel ch) { - Http2Connection connection = ch.pipeline().get(Http2FrameCodec.class).connection(); - ch.attr(HTTP2_CONNECTION).set(connection); - - int limit = (int) getMaxConcurrentStreamsLimit(); - LOG.info( - "Overriding local endpoint maxActiveStreams for channel {} from {} to {}", - ch, - connection.local().maxActiveStreams(), - limit); - connection.local().maxActiveStreams(limit); - } - - private void createExtraHttp2Connection() { - LOG.debug("Creating extra HTTP/2 connection"); - _parentPool.acquire().addListener((Future extra) -> { - _extraHttp2Connections.release(); - if (extra.isSuccess()) { - Channel ch = extra.getNow(); - // check that the pool really is a HTTP/2 connection - if (!Http2Utils.isHttp2MultiplexPipeline(_channelReuse, ch.pipeline())) { - LOG.warn("Extra connection was not a HTTP/2 connection to {}", ch.remoteAddress()); - } - _parentPool.release(ch); - } else { - if (_parentPool.isClosing() || _parentPool.isClosed()) { - // for closed pool, we don't have to print the exception stack - LOG.warn( - "Failed to create extra HTTP/2 connection because {}", - Optional.ofNullable(extra.cause()).map(Throwable::getMessage).orElse("Unknown reason")); - } else { - LOG.warn("Failed to create extra HTTP/2 connection", extra.cause()); - } - } - }); - } - - private void createStreamChannel(EspressoHttp2StreamChannelBootstrap bootstrap, Promise promise) { - if (!promise.isDone()) { - try { - bootstrapStreamChannel(bootstrap, promise); - } catch (Exception ex) { - promise.setFailure(ex); - } - } - } - - private void bootstrapStreamChannel(EspressoHttp2StreamChannelBootstrap bootstrap, Promise promise) { - bootstrap.open().addListener((Future s) -> { - if (s.isSuccess()) { - Http2StreamChannel streamChannel = s.getNow(); - _totalStreamCreations.increment(); - boolean closeStream = true; - try { - if (streamChannel.isOpen()) { - // TODO: ESPENG-38541: Make channel active with streams - handler().channelAcquired(streamChannel); - if (promise.trySuccess(streamChannel)) { - closeStream = false; - _totalActiveStreamChannels.increment(); - } else { - handler().channelReleased(streamChannel); - if (streamChannel.parent().hasAttr(RECYCLE_STREAMS_KEY)) { - Http2Utils.markChannelAvailableForReuse(streamChannel); - // If recycle fails, close the stream - closeStream = !streamChannel.parent().attr(RECYCLE_STREAMS_KEY).get().offer(streamChannel); - } - } - } else if (!promise.isDone()) { - // Shutdown is likely if adding it to the groups caused the channel to be closed - promise.setFailure(new ShutdownChannelGroupException()); - } - } catch (Exception ex) { - promise.setFailure(ex); - } finally { - if (closeStream) { - Http2Utils.closeStreamChannel(streamChannel); - } - } - } else { - if (!promise.tryFailure(s.cause())) { - LOG.warn("unhandled exception", s.cause()); - } - } - }); - } - - private boolean tryReuseStreamChannel(@Nullable Queue queue, Promise promise) - throws Exception { - if (queue == null) { - return false; - } - // Loop to find a stream channel good for reuse - for (Http2StreamChannel streamChannel = queue.poll(); streamChannel != null; streamChannel = queue.poll()) { - boolean closeStream = true; - try { - // Reuse if possible - if (streamChannel.isOpen() && Http2Utils.channelAvailableForReuse(streamChannel)) { - ((EspressoHttp2MultiplexHandler.EspressoHttp2MultiplexHandlerStreamChannel) streamChannel).init(); - // TODO: ESPENG-38541: Make channel active with streams - handler().channelAcquired(streamChannel); - if (promise.trySuccess(streamChannel)) { - markStreamForReuse(streamChannel); - closeStream = false; - } else { - handler().channelReleased(streamChannel); - closeStream = !queue.offer(streamChannel); - } - // If we found a good stream channel, exit - return true; - } - } finally { - if (closeStream) { - Http2Utils.closeStreamChannel(streamChannel); - } - } - } - return false; - } - - private void markStreamForReuse(Http2StreamChannel streamChannel) { - Http2Utils.markChannelForReuse(streamChannel); - _totalStreamsReused.increment(); - _currentStreamsReused.increment(); - _totalActiveStreamChannels.increment(); - } - - @Override - public Future release(Channel channel) { - return release(channel, ImmediateEventExecutor.INSTANCE.newPromise()); - } - - private boolean canReuseChannel(Http2StreamChannel channel) { - if (!channel.isOpen() || !channel.parent().hasAttr(RECYCLE_STREAMS_KEY) - || !(channel instanceof EspressoHttp2MultiplexHandler.EspressoHttp2MultiplexHandlerStreamChannel)) { - return false; - } - Queue queue = channel.parent().attr(RECYCLE_STREAMS_KEY).get(); - // Haven't hit channel reuse limit and channel is available for reuse - return queue.size() < getMaxReuseStreamChannelsLimit() && Http2Utils.channelAvailableForReuse(channel); - } - - @Override - public Future release(Channel channel, Promise promise) { - // If we can use reuse the stream channel, use it. - if (channel instanceof Http2StreamChannel) { - Http2StreamChannel streamChannel = (Http2StreamChannel) channel; - boolean closeChannel = true; - try { - handler().channelReleased(streamChannel); - - if (canReuseChannel(streamChannel)) { - // If recycle fails, close the stream - closeChannel = !streamChannel.parent().attr(RECYCLE_STREAMS_KEY).get().offer(streamChannel); - // when closeChannel == true, we call releaseReusedStream in the close listener - if (!closeChannel) { - releaseReusedStream(streamChannel); - } - return promise.setSuccess(null); - } - return promise; - } catch (Exception ex) { - return promise.setFailure(ex); - } finally { - _totalActiveStreamChannels.decrement(); - if (closeChannel) { - streamChannel.close().addListener(closeFuture -> { - releaseReusedStream(streamChannel); - if (closeFuture.isSuccess()) { - promise.setSuccess(null); - } else { - promise.setFailure(closeFuture.cause()); - } - }); - } - } - } else { - return _parentPool.release(channel, promise); - } - } - - private void releaseReusedStream(Http2StreamChannel channel) { - if (Http2Utils.isReusedChannel(channel)) { - _currentStreamsReused.decrement(); - Http2Utils.unmarkReusedStream(channel); - } - } - - @Override - public void close() { - _parentPool.close(); - } - - @Override - public ChannelPoolHandler handler() { - return _parentPool.handler(); - } - - @Override - public int getConnectedChannels() { - return _parentPool.getConnectedChannels(); - } - - @Override - public boolean isHealthy() { - // Check if parent pool is healthy directly. Parent pool will check if min connections are reached under H2 mode - return _parentPool.isHealthy(); - } - - @Override - public final Future closeFuture() { - return _parentPool.closeFuture(); - } - - @Override - public final boolean isClosing() { - return _parentPool.isClosing(); - } - - @Override - public int getMaxConnections() { - return _parentPool.getMaxConnections(); - } - - @Override - public int getH2ActiveConnections() { - // we are using h2 - if (_http2ChannelGroup.size() > 0) { - return (int) _http2ChannelGroup.stream() - .filter(channel -> channel.pipeline().get(Http2FrameCodec.class).connection().numActiveStreams() > 0) - .count(); - } - // no h2 active connections or we are using h1 - return -1; - } - - @Override - public ChannelGroup getHttp2ChannelGroup() { - return _http2ChannelGroup; - } - - @Override - public int getMaxPendingAcquires() { - return _parentPool.getMaxPendingAcquires(); - } - - @Override - public int getAcquiredChannelCount() { - return _parentPool.getAcquiredChannelCount(); - } - - @Override - public int getPendingAcquireCount() { - return _parentPool.getPendingAcquireCount(); - } - - @Override - public boolean isClosed() { - return _parentPool.isClosed(); - } - - @Override - public long getChannelReusePoolSize() { - return _http2ChannelGroup.stream() - .filter(channel -> channel.hasAttr(RECYCLE_STREAMS_KEY)) - .map(channel -> channel.attr(RECYCLE_STREAMS_KEY).get()) - .filter(Objects::nonNull) - .mapToInt(Queue::size) - .sum(); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/Http2PingCallListener.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/Http2PingCallListener.java deleted file mode 100644 index 2dea7ec2723..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/Http2PingCallListener.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -/* -* This listener is designed to track the http2 ping calls. -* -* @author Binbing Hou -* */ -public interface Http2PingCallListener { - boolean isCallComplete(long pingId); - - void callStart(long pingId, long timeNanos); - - void callClose(long pingId, long timeNanos); - - void callCloseWithError(long pingId, long timeNanos); -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/Http2PingHelper.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/Http2PingHelper.java deleted file mode 100644 index a5aa54f59c5..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/Http2PingHelper.java +++ /dev/null @@ -1,209 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import com.linkedin.alpini.base.misc.Time; -import com.linkedin.alpini.base.monitoring.CallCompletion; -import com.linkedin.alpini.base.monitoring.CallTracker; -import com.linkedin.alpini.netty4.handlers.Http2PingSendHandler; -import io.netty.channel.Channel; -import io.netty.handler.codec.http2.DefaultHttp2PingFrame; -import io.netty.handler.codec.http2.Http2ConnectionHandler; -import io.netty.handler.codec.http2.Http2PingFrame; -import javax.annotation.Nonnull; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/* -* This class is designed to provide the HTTP/2 ping related functions. -* Each host has an instance of Http2PingHelper to handle its ping calls, -* accessed via the instance of ChannelPoolManagerImpl.Pool. -* -* Two ping call trackers are used: -* -* 1. A normal call tracker: CallTracker _pingCallTracker. -* This is used to track all the ping call info and expose it to ingraph -* for monitoring purposes. -* -* 2. A customized call tracker: LatestPingCallTimeTracker _latestPingCallTimeTracker. -* This is designed and used to keep the response time of latest ping calls. -* This metric will be used as SN health metric in terms of connection health. -* -* @author Binbing Hou -* */ -public class Http2PingHelper implements Http2PingCallListener { - private final static Logger LOG = LogManager.getLogger(Http2PingHelper.class); - - private static final int NUM_OF_LATEST_PINGS_TO_TRACK = 5; - - private final CallTracker _pingCallTracker; - private CallCompletion _callCompletion; - private long _lastPingId; - - private final LatestPingCallTimeTracker _latestPingCallTimeTracker; - private final Http2PingSendHandler _http2PingSendHandler; - - public Http2PingHelper() { - _pingCallTracker = createPingCallTracker(); - _latestPingCallTimeTracker = createLatestPingCallTimeTracker(); - _http2PingSendHandler = createHttp2PingSendHandler(); - } - - public CallTracker createPingCallTracker() { - return CallTracker.create(); - } - - public LatestPingCallTimeTracker createLatestPingCallTimeTracker() { - return new LatestPingCallTimeTracker(); - } - - public Http2PingSendHandler createHttp2PingSendHandler() { - return new Http2PingSendHandler(this); - } - - public void sendPing(@Nonnull Channel channel) { - if (channel.pipeline().get(Http2ConnectionHandler.class) == null) { - LOG.debug( - "Channel={} does not have a Http2ConnectionHandler in the pipeline. It is possible that " - + "it is an HTTP/1 channel or an HTTP/2 channel in the middle of setup/teardown", - channel); - return; - } - // take the current nanoseconds as the id of the ping frame - Http2PingFrame defaultHttp2PingFrame = new DefaultHttp2PingFrame(Time.nanoTime()); - channel.writeAndFlush(defaultHttp2PingFrame).addListener(writeFuture -> { - if (!writeFuture.isSuccess()) { - LOG.error( - "Failed to write the PING frame={} to the HTTP/2 Channel={}", - defaultHttp2PingFrame, - channel, - writeFuture.cause()); - } else { - LOG.debug("Succeed to write PING frame={} to the HTTP/2 Channel={}", defaultHttp2PingFrame, channel); - } - }); - } - - public CallTracker pingCallTracker() { - return _pingCallTracker; - } - - public double getAvgResponseTimeOfLatestPings() { - return _latestPingCallTimeTracker.getAvgResponseTimeOfLatestPings(); - } - - public Http2PingSendHandler getHttp2PingSendHandler() { - return _http2PingSendHandler; - } - - @Override - public synchronized void callStart(long pingId, long timeNanos) { - if (_callCompletion != null) { - // Generally, _callCompletion is not possible to be null. - // In case any issue could make _callCompletion != null, close the call with callCloseWithError. - LOG.warn( - "_callCompletion is not null, but is expected to be null " - + "when a new ping call id={} starts; last ping id={}", - pingId, - _lastPingId); - callCloseWithError(_lastPingId, Time.nanoTime()); - } - _lastPingId = pingId; - _callCompletion = _pingCallTracker.startCall(timeNanos); - _latestPingCallTimeTracker.callStart(timeNanos); - } - - @Override - public synchronized void callClose(long pingId, long timeNanos) { - if (_callCompletion != null) { - if (pingId != _lastPingId) { - LOG.warn( - "callClose is trying to close the ping call with id={}, " + "but the call was started with id={}", - pingId, - _lastPingId); - return; - } - _callCompletion.close(timeNanos); - _latestPingCallTimeTracker.callClose(timeNanos); - _callCompletion = null; - } else { - LOG.warn( - "callClose is trying to close a ping call id={} " + "that has not been started; last ping call id={}", - pingId, - _lastPingId); - } - } - - @Override - public synchronized void callCloseWithError(long pingId, long timeNanos) { - if (_callCompletion != null) { - if (pingId != _lastPingId) { - LOG.warn( - "callCloseWithError is trying to close the ping call with id={}, " - + "but the last ping call was started with id={}", - pingId, - _lastPingId); - return; - } - _callCompletion.close(timeNanos); - _latestPingCallTimeTracker.callClose(timeNanos); - _callCompletion = null; - } else { - LOG.warn( - "callCloseWithError is trying to close a ping call id={} " - + "that has not been started; last ping call id={}", - pingId, - _lastPingId); - } - } - - @Override - public synchronized boolean isCallComplete(long pingId) { - if (_lastPingId != pingId) { - LOG.warn("isCallComplete is checking pingId={}, but the last ping id ={}", pingId, _lastPingId); - } - return _callCompletion == null; - } - - private static class LatestPingCallTimeTracker { - - // The latest response times are stored in a circular array for low overhead. - // Each host has an instance of Http2PingHelper and only updates the latest - // ping response time every ping interval. Therefore, there are no concurrent issues. - private final long[] _circularArray = new long[NUM_OF_LATEST_PINGS_TO_TRACK]; - private int _currentPingPos = -1; - public long _lastPingSendTime; - - LatestPingCallTimeTracker() { - } - - private void callStart(long timeNanos) { - _lastPingSendTime = timeNanos; - } - - private void callClose(long timeNanos) { - long responseTime = timeNanos - _lastPingSendTime; - updateLatestPingResponseTime(responseTime); - } - - private void updateLatestPingResponseTime(long pingResponseTimeNanos) { - _currentPingPos = (_currentPingPos + 1) % NUM_OF_LATEST_PINGS_TO_TRACK; - _circularArray[_currentPingPos] = pingResponseTimeNanos; - } - - private double getAvgResponseTimeOfLatestPings() { - // if no enough ping call times, return 0 - if (_circularArray[NUM_OF_LATEST_PINGS_TO_TRACK - 1] == 0) { - return 0; - } - double totalTime = 0; - for (int i = 0; i < NUM_OF_LATEST_PINGS_TO_TRACK; i++) { - totalTime += _circularArray[i]; - } - return totalTime / NUM_OF_LATEST_PINGS_TO_TRACK; - } - } - - public static double nanoToMillis(double nanos) { - return nanos / 1000000.0; - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/ManagedChannelPool.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/ManagedChannelPool.java deleted file mode 100644 index 208a851f1a1..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/ManagedChannelPool.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import io.netty.channel.group.ChannelGroup; -import io.netty.channel.pool.ChannelPoolHandler; -import io.netty.util.concurrent.Future; - - -public interface ManagedChannelPool extends ChannelPoolWithStats { - /** - * Returns the {@link ChannelPoolHandler} that will be notified for the different pool actions. - * - * @return the {@link ChannelPoolHandler} that will be notified for the different pool actions - */ - ChannelPoolHandler handler(); - - int getConnectedChannels(); - - boolean isHealthy(); - - Future closeFuture(); - - boolean isClosing(); - - default boolean isClosed() { - return false; - } - - default long getTotalActiveStreams() { - return 0; - } - - default long getCurrentStreamChannelsReused() { - return 0; - } - - default long getTotalStreamChannelsReused() { - return 0; - } - - default long getTotalStreamCreations() { - return 0; - } - - /** - * Returns the current reuse channel pool size. Normally this should be 0 since we should be reusing as much - * as possible. - * @return current reuse channel pool size - */ - default long getChannelReusePoolSize() { - return 0; - } - - default long getActiveStreamsLimitReachedCount() { - return 0; - } - - default int getH2ActiveConnections() { - return -1; - } - - default ChannelGroup getHttp2ChannelGroup() { - return null; - } - - default long getTotalAcquireRetries() { - return 0; - } - - default long getTotalActiveStreamChannels() { - return 0; - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/SimpleChannelPoolManagerImpl.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/SimpleChannelPoolManagerImpl.java deleted file mode 100644 index 95fbc6e25e4..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/com/linkedin/alpini/netty4/pool/SimpleChannelPoolManagerImpl.java +++ /dev/null @@ -1,365 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import com.linkedin.alpini.base.concurrency.Executors; -import com.linkedin.alpini.base.concurrency.Lazy; -import com.linkedin.alpini.base.misc.Time; -import com.linkedin.alpini.base.monitoring.CallCompletion; -import com.linkedin.alpini.base.monitoring.CallTracker; -import com.linkedin.alpini.consts.QOS; -import io.netty.channel.Channel; -import io.netty.channel.EventLoop; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.MultithreadEventLoopGroup; -import io.netty.channel.group.ChannelGroup; -import io.netty.channel.group.DefaultChannelGroup; -import io.netty.channel.pool.ChannelPoolHandler; -import io.netty.util.AttributeKey; -import io.netty.util.concurrent.EventExecutor; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.FutureListener; -import io.netty.util.concurrent.ImmediateEventExecutor; -import io.netty.util.concurrent.Promise; -import io.netty.util.internal.PlatformDependent; -import java.net.InetSocketAddress; -import java.net.URI; -import java.net.UnknownHostException; -import java.util.Queue; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.Executor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.LongAdder; -import java.util.function.Supplier; -import javax.annotation.Nonnull; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** - * In order to simplify the implementation of this {@link ChannelPoolManager}, this implementation requires that - * {@link #open(String)} is called to create the {@literal hostNameAndPort} instead of - * lazily creating them upon first reference. - * - * In the case for Espresso Router, it is informed of all the valid {@literal hostNameAndPort} from Helix and should - * then call {@link #open(String)} for each host. Calling it for a host that is already existant is a no-operation. - */ -public class SimpleChannelPoolManagerImpl implements ChannelPoolManager { - private static final AttributeKey POOL_ATTRIBUTE_KEY = - AttributeKey.valueOf(SimpleChannelPoolManagerImpl.class, "pool"); - private static final AttributeKey> BUSY_ATTRIBUTE_KEY = - AttributeKey.valueOf(SimpleChannelPoolManagerImpl.class, "busy"); - - private final Logger _log = LogManager.getLogger(getClass()); - private final ConcurrentMap _map = PlatformDependent.newConcurrentHashMap(); - private final Executor _closeExecutor = Executors.newSingleThreadExecutor(Executors.daemonThreadFactory()); // will be - // gc - // automatically - private final Executor _statsExecutor; - private final EventLoopGroup _eventLoopGroup; - private final ChannelPoolFactory _channelPoolFactory; - - public SimpleChannelPoolManagerImpl( - @Nonnull E eventLoopGroup, - @Nonnull ChannelPoolFactory channelPoolFactory) { - _eventLoopGroup = eventLoopGroup; - _channelPoolFactory = channelPoolFactory; - - // will be garbage collected automatically - Executor statsExecutor = Executors.newSingleThreadExecutor(Executors.daemonThreadFactory()); - - // To avoid stats collection to incurr a cost in the critical path, - // they are collected into a separate queue and run in a separate thread. - // which is scheduled to run periodically. - Queue statsQueue = PlatformDependent.newMpscQueue(); - _statsExecutor = statsQueue::add; - Runnable collectStats = () -> { - for (Runnable task = statsQueue.poll(); task != null; task = statsQueue.poll()) { - task.run(); - } - }; - - _eventLoopGroup.schedule(new Runnable() { - @Override - public void run() { - // drain all the collected stats - statsExecutor.execute(collectStats); - // schedule the next drain to occur in 100 milliseconds after completion - statsExecutor.execute(this::reschedule); - } - - private void reschedule() { - _eventLoopGroup.schedule(this, 100, TimeUnit.MILLISECONDS); - } - }, 1, TimeUnit.SECONDS); - - } - - protected ManagedChannelPool constructManagedPool(ChannelPoolHandler poolHandler, InetSocketAddress address) { - return _channelPoolFactory.construct(this, poolHandler, _eventLoopGroup, address); - } - - @Nonnull - protected CallTracker createHostAcquireCallTracker(@Nonnull String hostAndPort) { - return CallTracker.create(); - } - - @Nonnull - protected CallTracker createHostBusyCallTracker(@Nonnull String hostAndPort) { - return CallTracker.create(); - } - - class HostPool implements ChannelPoolHandler { - private final Supplier _channelPool; - private final ChannelGroup _channelGroup; - private final ChannelGroup _activeGroup; - private final LongAdder _createCount; - private final LongAdder _closeCount; - private final InetSocketAddress _socketAddress; - private final CallTracker _acquireCallTracker; - private final CallTracker _busyCallTracker; - private final CompletableFuture _closeCompleted; - private boolean closing; - - HostPool(String name) { - EventExecutor eventExecutor = _eventLoopGroup.next(); - URI uri = URI.create("socket://" + name); - _socketAddress = InetSocketAddress.createUnresolved(uri.getHost(), uri.getPort()); - _createCount = new LongAdder(); - _closeCount = new LongAdder(); - _channelGroup = new DefaultChannelGroup(name, eventExecutor, true) { - @Override - public boolean add(Channel channel) { - if (super.add(channel)) { - _createCount.increment(); - return true; - } - return false; - } - - @Override - public boolean remove(Object o) { - if (super.remove(o)) { - _closeCount.increment(); - return true; - } - return false; - } - }; - _acquireCallTracker = createHostAcquireCallTracker(name); - _busyCallTracker = createHostBusyCallTracker(name); - _closeCompleted = new CompletableFuture<>(); - _activeGroup = new DefaultChannelGroup("active:" + name, eventExecutor); - _channelPool = Lazy.of(() -> constructManagedPool(this, remoteAddress())); - } - - @Override - public void channelReleased(Channel ch) throws Exception { - CompletableFuture acquireTime = CompletableFuture.completedFuture(Time.nanoTime()); - boolean success = _activeGroup.remove(ch); - - CompletableFuture cc = ch.attr(BUSY_ATTRIBUTE_KEY).getAndSet(null); - if (cc != null) { - if (success) { - cc.thenAcceptBothAsync(acquireTime, CallCompletion::close, _statsExecutor); - } else { - cc.thenAcceptBothAsync(acquireTime, CallCompletion::closeWithError, _statsExecutor); - } - } - } - - @Override - public void channelAcquired(Channel ch) throws Exception { - CompletableFuture acquireTime = CompletableFuture.completedFuture(Time.nanoTime()); - CompletableFuture cc = ch.attr(BUSY_ATTRIBUTE_KEY) - .getAndSet(acquireTime.thenApplyAsync(busyCallTracker()::startCall, _statsExecutor)); - if (cc != null) { - cc.thenAcceptBothAsync(acquireTime, CallCompletion::closeWithError, _statsExecutor); - } - _activeGroup.add(ch); - } - - @Override - public void channelCreated(Channel ch) throws Exception { - _channelGroup.add(ch); - ch.attr(POOL_ATTRIBUTE_KEY).set(this); - } - - public InetSocketAddress remoteAddress() { - return _socketAddress; - } - - public int openConnections() { - return _channelGroup.size(); - } - - public boolean isHealthy() { - return _channelPool.get().isHealthy(); - } - - public boolean isClosing() { - return closing || _channelPool.get().isClosing(); - } - - private FutureListener acquireListener0(Promise channelPromise) { - return (Future future) -> { - if (future.isSuccess()) { - future.getNow().attr(POOL_ATTRIBUTE_KEY).set(this); - if (channelPromise.trySuccess(future.getNow())) { - return; - } - _channelPool.get().release(future.getNow()); - } else { - channelPromise.setFailure(future.cause()); - } - }; - } - - private Future acquire0(FutureListener futureListener) { - Future channelFuture = _channelPool.get().acquire(); - if (channelFuture.isSuccess()) { - channelFuture.getNow().attr(POOL_ATTRIBUTE_KEY).set(this); - return channelFuture.addListener(futureListener); - } - Promise channelPromise = ImmediateEventExecutor.INSTANCE.newPromise(); - channelFuture.addListener(acquireListener0(channelPromise)); - return channelPromise.addListener(futureListener); - } - - private Future acquire0(Promise promise) { - _channelPool.get().acquire().addListener(acquireListener0(promise)); - return promise; - } - - public Future acquire() { - return acquire0(acquireListener(startAcquire())); - } - - public Future acquire(Promise promise) { - return acquire0(promise.addListener(acquireListener(startAcquire()))); - } - - private CompletableFuture startAcquire() { - long startTime = Time.nanoTime(); - return CompletableFuture.completedFuture(startTime) - .thenApplyAsync(acquireCallTracker()::startCall, _statsExecutor); - } - - private FutureListener acquireListener(CompletableFuture cc) { - return acquireFuture -> { - long endTime = Time.nanoTime(); - if (acquireFuture.isSuccess()) { - cc.thenAcceptBothAsync(CompletableFuture.completedFuture(endTime), CallCompletion::close); - } else { - cc.thenAcceptBothAsync(CompletableFuture.completedFuture(endTime), CallCompletion::closeWithError); - } - }; - } - - public Future release(Channel channel) { - return release(channel, channel.eventLoop().newPromise()); - } - - public Future release(Channel channel, Promise promise) { - return _channelPool.get().release(channel, promise); - } - - Future closeAsync() { - closing = true; - ManagedChannelPool channelPool = _channelPool.get(); - Future closeFuture = channelPool.closeFuture(); - CompletableFuture.runAsync(channelPool::close, _closeExecutor).thenRun(() -> closeFuture.addListener(future -> { - _closeCompleted.complete(_map.remove(name(), this)); - })); - return closeFuture; - } - - @Nonnull - public String name() { - return _channelGroup.name(); - } - - public int activeCount() { - return _activeGroup.size(); - } - - @Nonnull - public CallTracker acquireCallTracker() { - return _acquireCallTracker; - } - - @Nonnull - public CallTracker busyCallTracker() { - return _busyCallTracker; - } - } - - @Override - @Deprecated - public int executorCount() { - return subpoolCount(); - } - - @Override - public int subpoolCount() { - return 1; - } - - @Nonnull - @Override - public Future acquire(@Nonnull String hostNameAndPort, @Nonnull String queueName, @Nonnull QOS qos) { - HostPool hostPool = _map.get(hostNameAndPort); - return hostPool == null - ? ImmediateEventExecutor.INSTANCE.newFailedFuture(new UnknownHostException(hostNameAndPort)) - : hostPool.acquire(); - } - - @Nonnull - @Override - public Future acquire( - @Nonnull EventLoop eventLoop, - @Nonnull String hostNameAndPort, - @Nonnull String queueName, - @Nonnull QOS qos) { - HostPool hostPool = _map.get(hostNameAndPort); - if (hostPool == null) { - return eventLoop.newFailedFuture(new UnknownHostException(hostNameAndPort)); - } - if (eventLoop.inEventLoop()) { - return hostPool.acquire(eventLoop.newPromise()); - } - Promise promise = eventLoop.newPromise(); - eventLoop.execute(() -> hostPool.acquire(promise)); - return promise; - } - - @Nonnull - @Override - public Future release(@Nonnull Channel channel) { - if (channel.hasAttr(POOL_ATTRIBUTE_KEY)) { - return channel.attr(POOL_ATTRIBUTE_KEY).get().release(channel); - } - return channel.eventLoop().newFailedFuture(new IllegalStateException()); - } - - @Override - public Future open(@Nonnull String hostNameAndPort) { - return open(hostNameAndPort, ImmediateEventExecutor.INSTANCE.newPromise()); - } - - private Future open(@Nonnull String hostNameAndPort, Promise promise) { - HostPool hostPool = _map.computeIfAbsent(hostNameAndPort, HostPool::new); - if (hostPool.isClosing()) { - hostPool._closeCompleted.thenRunAsync(() -> open(hostNameAndPort, promise), _eventLoopGroup); - return promise; - } else { - return promise.setSuccess(null); - } - } - - @Nonnull - @Override - public Future close(@Nonnull String hostNameAndPort) { - HostPool hostPool = _map.get(hostNameAndPort); - return hostPool == null ? ImmediateEventExecutor.INSTANCE.newSucceededFuture(null) : hostPool.closeAsync(); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/io/netty/bootstrap/InstrumentedBootstrap.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/io/netty/bootstrap/InstrumentedBootstrap.java deleted file mode 100644 index 6d62b592fa6..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/io/netty/bootstrap/InstrumentedBootstrap.java +++ /dev/null @@ -1,105 +0,0 @@ -package io.netty.bootstrap; - -import com.linkedin.alpini.base.monitoring.CallCompletion; -import com.linkedin.alpini.base.monitoring.CallTracker; -import io.netty.channel.ChannelFuture; -import io.netty.channel.EventLoopGroup; -import java.net.SocketAddress; -import java.util.function.Function; -import java.util.function.Supplier; -import javax.annotation.Nonnull; - - -/** - * Because various netty methods and classes have been declared as {@code final}, - * we construct this pile of foo in order to be able to instrument the {@linkplain #connect()} - * method invocation. This class is in the {@code io.netty.bootstrap} package in - * order to access some methods of {@link Bootstrap} which have package access. - * - * @author acurtis on 3/30/17. - */ -public class InstrumentedBootstrap extends Bootstrap { - private final Function _connectCallTracker; - - public InstrumentedBootstrap(@Nonnull CallTracker connectCallTracker) { - this(ignored -> connectCallTracker); - } - - public InstrumentedBootstrap(@Nonnull Function connectCallTracker) { - _connectCallTracker = connectCallTracker; - } - - protected InstrumentedBootstrap(InstrumentedBootstrap old) { - _connectCallTracker = old._connectCallTracker; - - if (old.channelFactory() != null) { - channelFactory(old.channelFactory()); - } - if (old.handler() != null) { - handler(old.handler()); - } - if (old.localAddress() != null) { - localAddress(old.localAddress()); - } - synchronized (old.options0()) { - options0().putAll(old.options0()); - } - synchronized (old.attrs0()) { - attrs0().putAll(old.attrs0()); - } - - resolver(old.resolver()); - remoteAddress(old.remoteAddress()); - } - - ChannelFuture trackConnect(Supplier futureSupplier, CallCompletion completion) { - ChannelFuture channelFuture = null; - try { - channelFuture = futureSupplier.get().addListener(f -> completion.closeCompletion(f.getNow(), f.cause())); - } finally { - if (channelFuture == null) { - completion.closeWithError(); - } - } - return channelFuture; - } - - CallTracker getCallTracker(SocketAddress remoteAddress) { - return _connectCallTracker.apply(remoteAddress); - } - - /** - * Connect a {@link io.netty.channel.Channel} to the remote peer. - */ - public ChannelFuture connect() { - CallCompletion callCompletion = getCallTracker(remoteAddress()).startCall(); - return trackConnect(super::connect, callCompletion); - } - - /** - * Connect a {@link io.netty.channel.Channel} to the remote peer. - */ - public ChannelFuture connect(SocketAddress remoteAddress) { - CallCompletion callCompletion = getCallTracker(remoteAddress).startCall(); - return trackConnect(() -> super.connect(remoteAddress), callCompletion); - } - - /** - * Connect a {@link io.netty.channel.Channel} to the remote peer. - */ - public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress) { - CallCompletion callCompletion = getCallTracker(remoteAddress).startCall(); - return trackConnect(() -> super.connect(remoteAddress, localAddress), callCompletion); - } - - @Override - @SuppressWarnings("CloneDoesntCallSuperClone") - public Bootstrap clone() { - return clone(group); - } - - @Override - public Bootstrap clone(EventLoopGroup group) { - return new InstrumentedBootstrap(this).group(group); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/io/netty/bootstrap/ResolveAllBootstrap.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/io/netty/bootstrap/ResolveAllBootstrap.java deleted file mode 100644 index 730f3570502..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/io/netty/bootstrap/ResolveAllBootstrap.java +++ /dev/null @@ -1,248 +0,0 @@ -package io.netty.bootstrap; - -import com.linkedin.alpini.base.misc.ExceptionUtil; -import com.linkedin.alpini.base.misc.Msg; -import com.linkedin.alpini.base.misc.Pair; -import com.linkedin.alpini.base.monitoring.CallCompletion; -import com.linkedin.alpini.base.monitoring.CallTracker; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.EventLoop; -import io.netty.channel.EventLoopGroup; -import io.netty.resolver.AddressResolver; -import io.netty.resolver.AddressResolverGroup; -import io.netty.util.AttributeKey; -import io.netty.util.concurrent.Future; -import java.net.SocketAddress; -import java.nio.channels.UnresolvedAddressException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; -import java.util.function.Function; -import javax.annotation.Nonnull; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** - * The existing Netty Bootstrap has a limitation regarding connecting to remote hosts - * where the hostname resolves to more than one IP address. - * It will only try one resolved address and then fail if the connection cannot be established. - * - * This is a problem for us: If we have a service which is bound to the IPv4 address and the IPv6 - * address is added to the DNS, attempts to connect to the machine are likely to fail. - * - * This bootstrap will attempt to do the right thing by attempting to connect using each of the - * resolved IP addresses. A sort comparator may be provided to encourage preference in the order - * of connect attempts. To conform to de-facto standards, one should provide a comparator which - * will sort IPv6 addresses first. - * - * Created by acurtis on 4/20/18. - */ -public class ResolveAllBootstrap extends InstrumentedBootstrap { - private static final Logger LOG = LogManager.getLogger(ResolveAllBootstrap.class); - - public static final AttributeKey> SORT_KEY = - AttributeKey.valueOf(ResolveAllBootstrap.class, "sortKey"); - - private final Function _resolveCallTracker; - - /** - * Constructor for the bootstrap. - * @param connectCallTracker CallTracker for connect operations. - * @param resolveCallTracker CallTracker for resolveAll operations. - */ - public ResolveAllBootstrap(@Nonnull CallTracker connectCallTracker, @Nonnull CallTracker resolveCallTracker) { - this(address -> connectCallTracker, address -> resolveCallTracker); - } - - /** - * Constructor for the bootstrap - * @param connectCallTracker provide CallTracker for connect operations. Function must not return null. - * @param resolveCallTracker provide CallTracker for resolveAll operations. Function must not return null. - */ - public ResolveAllBootstrap( - @Nonnull Function connectCallTracker, - @Nonnull Function resolveCallTracker) { - super(connectCallTracker); - _resolveCallTracker = resolveCallTracker; - } - - protected ResolveAllBootstrap(ResolveAllBootstrap old) { - super(old); - _resolveCallTracker = old._resolveCallTracker; - } - - public Bootstrap sortResolvedAddress(@Nonnull Comparator comparator) { - return attr(SORT_KEY, comparator); - } - - @Override - public ChannelFuture connect() { - validate(); - SocketAddress remoteAddress = remoteAddress(); - if (remoteAddress == null) { - throw new IllegalStateException("remoteAddress not set"); - } - return doResolveAndConnect(remoteAddress, config().localAddress()); - } - - @Override - public ChannelFuture connect(SocketAddress remoteAddress) { - Objects.requireNonNull(remoteAddress, "remoteAddress"); - validate(); - return doResolveAndConnect(remoteAddress, config().localAddress()); - } - - @Override - public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress) { - Objects.requireNonNull(remoteAddress, "remoteAddress"); - validate(); - return doResolveAndConnect(remoteAddress, localAddress); - } - - @Nonnull - private CompletionStage awaitRegistration(ChannelFuture regFuture) { - CompletableFuture reg = new CompletableFuture<>(); - if (regFuture.isDone()) { - if (!regFuture.isSuccess()) { - reg.obtrudeException(regFuture.cause()); - } else { - reg.obtrudeValue(regFuture.channel()); - } - } else { - regFuture.addListener((ChannelFutureListener) future -> { - // Directly obtain the cause and do a null check so we only need one volatile read in case of a - // failure. - Throwable cause = future.cause(); - if (cause != null) { - // Registration on the EventLoop failed so fail the ChannelPromise directly to not cause an - // IllegalStateException once we try to access the EventLoop of the Channel. - reg.completeExceptionally(cause); - } else { - // Registration was successful, so set the correct executor to use. - // See https://github.com/netty/netty/issues/2586 - reg.complete(future.channel()); - } - }); - } - return reg; - } - - @Nonnull - private ChannelFuture doResolveAndConnect(SocketAddress remoteAddress, SocketAddress localAddress) { - LOG.debug("doResolveAndConnect({}, {})", remoteAddress, localAddress); - return new PendingConnectPromise( - CompletableFuture.completedFuture(initAndRegister()) - .thenCompose(this::awaitRegistration) - .thenCompose(channel -> doResolve(channel, remoteAddress)) - .thenApply(this::doSortAddresses) - .thenCompose( - channelAndAddress -> doConnect( - channelAndAddress.getFirst(), - channelAndAddress.getSecond().iterator(), - localAddress))); - } - - @Nonnull - private CompletionStage doConnect( - Channel channel, - Iterator remoteAddressIterator, - SocketAddress localAddress) { - SocketAddress remoteAddress = remoteAddressIterator.next(); - - CompletableFuture connect = new CompletableFuture<>(); - final CallCompletion callCompletion = getCallTracker(remoteAddress).startCall(); - - (localAddress == null ? channel.connect(remoteAddress) : channel.connect(remoteAddress, localAddress)) - .addListener(future -> { - callCompletion.closeCompletion(future.getNow(), future.cause()); - if (future.isSuccess()) { - if (!connect.complete(channel)) { - channel.close(); - } - } else { - Throwable cause = ExceptionUtil.unwrapCompletion(future.cause()); - if (remoteAddressIterator.hasNext() && !connect.isDone()) { - LOG.info( - "Failed to connect to {}, retrying with next address. Cause: {}", - remoteAddress, - cause.getMessage()); - // channel would already be closed. we need to register a new channel and try again. - CompletableFuture.completedFuture(initAndRegister()) - .thenCompose(this::awaitRegistration) - .thenCompose(nextChannel -> doConnect(nextChannel, remoteAddressIterator, localAddress)) - .handle((connectedChannel, throwable) -> { - if (throwable != null) { - connect.completeExceptionally(throwable); - } else if (!connect.complete(connectedChannel)) { - connectedChannel.close(); - } - return null; - }); - } else { - if (!connect.completeExceptionally(cause)) { - LOG.warn("Failed to connect to {}", remoteAddress, cause); - } - } - } - }); - return connect; - } - - @SuppressWarnings("unchecked") - private AddressResolverGroup resolverGroup() { - return (AddressResolverGroup) resolver(); - } - - private CompletionStage>> doResolve( - final Channel channel, - SocketAddress remoteAddress) { - final EventLoop eventLoop = channel.eventLoop(); - final AddressResolver resolver = resolverGroup().getResolver(eventLoop); - - if (!resolver.isSupported(remoteAddress) || resolver.isResolved(remoteAddress)) { - return CompletableFuture.completedFuture(Pair.make(channel, Collections.singletonList(remoteAddress))); - } - - CompletableFuture>> resolve = new CompletableFuture<>(); - final CallCompletion callCompletion = _resolveCallTracker.apply(remoteAddress).startCall(); - resolver.resolveAll(remoteAddress).addListener((Future> resolveFuture) -> { - final Throwable resolveFailureCause = resolveFuture.cause(); - callCompletion.closeCompletion(resolveFuture.getNow(), resolveFailureCause); - LOG.debug("doResolve complete {} {}", resolveFuture.getNow(), Msg.make(resolveFailureCause, String::valueOf)); - - if (resolveFailureCause != null || resolveFuture.getNow().isEmpty()) { - // Failed to resolve immediately - channel.close(); - resolve.completeExceptionally( - resolveFailureCause == null ? new UnresolvedAddressException() : resolveFailureCause); - } else { - resolve.complete(Pair.make(channel, resolveFuture.getNow())); - } - }); - return resolve; - } - - @Nonnull - private Pair> doSortAddresses( - @Nonnull Pair> channelListPair) { - if (channelListPair.getSecond().size() < 2 || !channelListPair.getFirst().hasAttr(SORT_KEY)) { - return channelListPair; - } - List list = new ArrayList<>(channelListPair.getSecond()); - list.sort(channelListPair.getFirst().attr(SORT_KEY).get()); - return Pair.make(channelListPair.getFirst(), list); - } - - @Override - public Bootstrap clone(EventLoopGroup group) { - return new ResolveAllBootstrap(this).group(group); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/io/netty/handler/codec/EspressoMessageAggregator.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/io/netty/handler/codec/EspressoMessageAggregator.java deleted file mode 100644 index 30a94f5d8ce..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/io/netty/handler/codec/EspressoMessageAggregator.java +++ /dev/null @@ -1,467 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project 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 io.netty.handler.codec; - -import static io.netty.buffer.Unpooled.EMPTY_BUFFER; -import static io.netty.util.internal.ObjectUtil.checkPositiveOrZero; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufHolder; -import io.netty.buffer.CompositeByteBuf; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelPipeline; -import io.netty.util.ReferenceCountUtil; -import java.util.List; - - -/** - * Forked from Netty 4.1.42.Final. Main change is to avoid creating {@link io.netty.util.internal.TypeParameterMatcher}. - * - * An abstract {@link io.netty.channel.ChannelHandler} that aggregates a series of message objects into a single aggregated message. - *

- * 'A series of messages' is composed of the following: - *

    - *
  • a single start message which optionally contains the first part of the content, and
  • - *
  • 1 or more content messages.
  • - *
- * The content of the aggregated message will be the merged content of the start message and its following content - * messages. If this aggregator encounters a content message where {@link #isLastContentMessage(ByteBufHolder)} - * return {@code true} for, the aggregator will finish the aggregation and produce the aggregated message and expect - * another start message. - *

- * - * @param the type that covers both start message and content message - * @param the type of the start message - * @param the type of the content message (must be a subtype of {@link ByteBufHolder}) - * @param the type of the aggregated message (must be a subtype of {@code S} and {@link ByteBufHolder}) - */ -public abstract class EspressoMessageAggregator - extends EspressoMessageToMessageDecoder { - private static final int DEFAULT_MAX_COMPOSITEBUFFER_COMPONENTS = 1024; - - private final int maxContentLength; - private O currentMessage; - private boolean handlingOversizedMessage; - - private int maxCumulationBufferComponents = DEFAULT_MAX_COMPOSITEBUFFER_COMPONENTS; - private ChannelHandlerContext ctx; - private ChannelFutureListener continueResponseWriteListener; - - private boolean aggregating; - - /** - * Creates a new instance. - * - * @param maxContentLength - * the maximum length of the aggregated content. - * If the length of the aggregated content exceeds this value, - * {@link #handleOversizedMessage(ChannelHandlerContext, Object)} will be called. - */ - protected EspressoMessageAggregator(int maxContentLength) { - validateMaxContentLength(maxContentLength); - this.maxContentLength = maxContentLength; - } - - protected EspressoMessageAggregator(int maxContentLength, Class inboundMessageType) { - super(inboundMessageType); - validateMaxContentLength(maxContentLength); - this.maxContentLength = maxContentLength; - } - - private static void validateMaxContentLength(int maxContentLength) { - checkPositiveOrZero(maxContentLength, "maxContentLength"); - } - - @Override - public boolean acceptInboundMessage(Object msg) throws Exception { - // No need to match last and full types because they are subset of first and middle types. - if (!super.acceptInboundMessage(msg)) { - return false; - } - - @SuppressWarnings("unchecked") - I in = (I) msg; - - if (isAggregated(in)) { - return false; - } - - // NOTE: It's tempting to make this check only if aggregating is false. There are however - // side conditions in decode(...) in respect to large messages. - if (isStartMessage(in)) { - aggregating = true; - return true; - } else if (aggregating && isContentMessage(in)) { - return true; - } - - return false; - } - - /** - * Returns {@code true} if and only if the specified message is a start message. Typically, this method is - * implemented as a single {@code return} statement with {@code instanceof}: - *
-   * return msg instanceof MyStartMessage;
-   * 
- */ - protected abstract boolean isStartMessage(I msg) throws Exception; - - /** - * Returns {@code true} if and only if the specified message is a content message. Typically, this method is - * implemented as a single {@code return} statement with {@code instanceof}: - *
-   * return msg instanceof MyContentMessage;
-   * 
- */ - protected abstract boolean isContentMessage(I msg) throws Exception; - - /** - * Returns {@code true} if and only if the specified message is the last content message. Typically, this method is - * implemented as a single {@code return} statement with {@code instanceof}: - *
-   * return msg instanceof MyLastContentMessage;
-   * 
- * or with {@code instanceof} and boolean field check: - *
-   * return msg instanceof MyContentMessage && msg.isLastFragment();
-   * 
- */ - protected abstract boolean isLastContentMessage(C msg) throws Exception; - - /** - * Returns {@code true} if and only if the specified message is already aggregated. If this method returns - * {@code true}, this handler will simply forward the message to the next handler as-is. - */ - protected abstract boolean isAggregated(I msg) throws Exception; - - /** - * Returns the maximum allowed length of the aggregated message in bytes. - */ - public final int maxContentLength() { - return maxContentLength; - } - - /** - * Returns the maximum number of components in the cumulation buffer. If the number of - * the components in the cumulation buffer exceeds this value, the components of the - * cumulation buffer are consolidated into a single component, involving memory copies. - * The default value of this property is {@value #DEFAULT_MAX_COMPOSITEBUFFER_COMPONENTS}. - */ - public final int maxCumulationBufferComponents() { - return maxCumulationBufferComponents; - } - - /** - * Sets the maximum number of components in the cumulation buffer. If the number of - * the components in the cumulation buffer exceeds this value, the components of the - * cumulation buffer are consolidated into a single component, involving memory copies. - * The default value of this property is {@value #DEFAULT_MAX_COMPOSITEBUFFER_COMPONENTS} - * and its minimum allowed value is {@code 2}. - */ - public final void setMaxCumulationBufferComponents(int maxCumulationBufferComponents) { - if (maxCumulationBufferComponents < 2) { - throw new IllegalArgumentException( - "maxCumulationBufferComponents: " + maxCumulationBufferComponents + " (expected: >= 2)"); - } - - if (ctx == null) { - this.maxCumulationBufferComponents = maxCumulationBufferComponents; - } else { - throw new IllegalStateException("decoder properties cannot be changed once the decoder is added to a pipeline."); - } - } - - /** - * @deprecated This method will be removed in future releases. - */ - @Deprecated - public final boolean isHandlingOversizedMessage() { - return handlingOversizedMessage; - } - - protected final ChannelHandlerContext ctx() { - if (ctx == null) { - throw new IllegalStateException("not added to a pipeline yet"); - } - return ctx; - } - - @Override - protected void decode(final ChannelHandlerContext ctx, I msg, List out) throws Exception { - assert aggregating; - - if (isStartMessage(msg)) { - handlingOversizedMessage = false; - if (currentMessage != null) { - currentMessage.release(); - currentMessage = null; - throw new MessageAggregationException(); - } - - @SuppressWarnings("unchecked") - S m = (S) msg; - - // Send the continue response if necessary (e.g. 'Expect: 100-continue' header) - // Check before content length. Failing an expectation may result in a different response being sent. - Object continueResponse = newContinueResponse(m, maxContentLength, ctx.pipeline()); - if (continueResponse != null) { - // Cache the write listener for reuse. - ChannelFutureListener listener = continueResponseWriteListener; - if (listener == null) { - continueResponseWriteListener = listener = new ChannelFutureListener() { // SUPPRESS CHECKSTYLE - // InnerAssignment - @Override - public void operationComplete(ChannelFuture future) throws Exception { - if (!future.isSuccess()) { - ctx.fireExceptionCaught(future.cause()); - } - } - }; - } - - // Make sure to call this before writing, otherwise reference counts may be invalid. - boolean closeAfterWrite = closeAfterContinueResponse(continueResponse); - handlingOversizedMessage = ignoreContentAfterContinueResponse(continueResponse); - - final ChannelFuture future = ctx.writeAndFlush(continueResponse).addListener(listener); - - if (closeAfterWrite) { - future.addListener(ChannelFutureListener.CLOSE); - return; - } - if (handlingOversizedMessage) { - return; - } - } else if (isContentLengthInvalid(m, maxContentLength)) { - // if content length is set, preemptively close if it's too large - invokeHandleOversizedMessage(ctx, m); - return; - } - - if (m instanceof DecoderResultProvider && !((DecoderResultProvider) m).decoderResult().isSuccess()) { - O aggregated; - if (m instanceof ByteBufHolder) { - aggregated = beginAggregation(m, ((ByteBufHolder) m).content().retain()); - } else { - aggregated = beginAggregation(m, EMPTY_BUFFER); - } - finishAggregation0(aggregated); - out.add(aggregated); - return; - } - - // A streamed message - initialize the cumulative buffer, and wait for incoming chunks. - CompositeByteBuf content = ctx.alloc().compositeBuffer(maxCumulationBufferComponents); - if (m instanceof ByteBufHolder) { - appendPartialContent(content, ((ByteBufHolder) m).content()); - } - currentMessage = beginAggregation(m, content); - } else if (isContentMessage(msg)) { - if (currentMessage == null) { - // it is possible that a TooLongFrameException was already thrown but we can still discard data - // until the begging of the next request/response. - return; - } - - // Merge the received chunk into the content of the current message. - CompositeByteBuf content = (CompositeByteBuf) currentMessage.content(); - - @SuppressWarnings("unchecked") - final C m = (C) msg; - // Handle oversized message. - if (content.readableBytes() > maxContentLength - m.content().readableBytes()) { - // By convention, full message type extends first message type. - @SuppressWarnings("unchecked") - S s = (S) currentMessage; - invokeHandleOversizedMessage(ctx, s); - return; - } - - // Append the content of the chunk. - appendPartialContent(content, m.content()); - - // Give the subtypes a chance to merge additional information such as trailing headers. - aggregate(currentMessage, m); - - final boolean last; - if (m instanceof DecoderResultProvider) { - DecoderResult decoderResult = ((DecoderResultProvider) m).decoderResult(); - if (!decoderResult.isSuccess()) { - if (currentMessage instanceof DecoderResultProvider) { - ((DecoderResultProvider) currentMessage).setDecoderResult(DecoderResult.failure(decoderResult.cause())); - } - last = true; - } else { - last = isLastContentMessage(m); - } - } else { - last = isLastContentMessage(m); - } - - if (last) { - finishAggregation0(currentMessage); - - // All done - out.add(currentMessage); - currentMessage = null; - } - } else { - throw new MessageAggregationException(); - } - } - - private static void appendPartialContent(CompositeByteBuf content, ByteBuf partialContent) { - if (partialContent.isReadable()) { - content.addComponent(true, partialContent.retain()); - } - } - - /** - * Determine if the message {@code start}'s content length is known, and if it greater than - * {@code maxContentLength}. - * @param start The message which may indicate the content length. - * @param maxContentLength The maximum allowed content length. - * @return {@code true} if the message {@code start}'s content length is known, and if it greater than - * {@code maxContentLength}. {@code false} otherwise. - */ - protected abstract boolean isContentLengthInvalid(S start, int maxContentLength) throws Exception; - - /** - * Returns the 'continue response' for the specified start message if necessary. For example, this method is - * useful to handle an HTTP 100-continue header. - * - * @return the 'continue response', or {@code null} if there's no message to send - */ - protected abstract Object newContinueResponse(S start, int maxContentLength, ChannelPipeline pipeline) - throws Exception; - - /** - * Determine if the channel should be closed after the result of - * {@link #newContinueResponse(Object, int, ChannelPipeline)} is written. - * @param msg The return value from {@link #newContinueResponse(Object, int, ChannelPipeline)}. - * @return {@code true} if the channel should be closed after the result of - * {@link #newContinueResponse(Object, int, ChannelPipeline)} is written. {@code false} otherwise. - */ - protected abstract boolean closeAfterContinueResponse(Object msg) throws Exception; - - /** - * Determine if all objects for the current request/response should be ignored or not. - * Messages will stop being ignored the next time {@link #isContentMessage(Object)} returns {@code true}. - * - * @param msg The return value from {@link #newContinueResponse(Object, int, ChannelPipeline)}. - * @return {@code true} if all objects for the current request/response should be ignored or not. - * {@code false} otherwise. - */ - protected abstract boolean ignoreContentAfterContinueResponse(Object msg) throws Exception; - - /** - * Creates a new aggregated message from the specified start message and the specified content. If the start - * message implements {@link ByteBufHolder}, its content is appended to the specified {@code content}. - * This aggregator will continue to append the received content to the specified {@code content}. - */ - protected abstract O beginAggregation(S start, ByteBuf content) throws Exception; - - /** - * Transfers the information provided by the specified content message to the specified aggregated message. - * Note that the content of the specified content message has been appended to the content of the specified - * aggregated message already, so that you don't need to. Use this method to transfer the additional information - * that the content message provides to {@code aggregated}. - */ - protected void aggregate(O aggregated, C content) throws Exception { - } - - private void finishAggregation0(O aggregated) throws Exception { - aggregating = false; - finishAggregation(aggregated); - } - - /** - * Invoked when the specified {@code aggregated} message is about to be passed to the next handler in the pipeline. - */ - protected void finishAggregation(O aggregated) throws Exception { - } - - private void invokeHandleOversizedMessage(ChannelHandlerContext ctx, S oversized) throws Exception { - handlingOversizedMessage = true; - currentMessage = null; - try { - handleOversizedMessage(ctx, oversized); - } finally { - // Release the message in case it is a full one. - ReferenceCountUtil.release(oversized); - } - } - - /** - * Invoked when an incoming request exceeds the maximum content length. The default behvaior is to trigger an - * {@code exceptionCaught()} event with a {@link TooLongFrameException}. - * - * @param ctx the {@link ChannelHandlerContext} - * @param oversized the accumulated message up to this point, whose type is {@code S} or {@code O} - */ - protected void handleOversizedMessage(ChannelHandlerContext ctx, S oversized) throws Exception { - ctx.fireExceptionCaught(new TooLongFrameException("content length exceeded " + maxContentLength() + " bytes.")); - } - - @Override - public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { - // We might need keep reading the channel until the full message is aggregated. - // - // See https://github.com/netty/netty/issues/6583 - if (currentMessage != null && !ctx.channel().config().isAutoRead()) { - ctx.read(); - } - ctx.fireChannelReadComplete(); - } - - @Override - public void channelInactive(ChannelHandlerContext ctx) throws Exception { - try { - // release current message if it is not null as it may be a left-over - super.channelInactive(ctx); - } finally { - releaseCurrentMessage(); - } - } - - @Override - public void handlerAdded(ChannelHandlerContext ctx) throws Exception { - this.ctx = ctx; - } - - @Override - public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { - try { - super.handlerRemoved(ctx); - } finally { - // release current message if it is not null as it may be a left-over as there is not much more we can do in - // this case - releaseCurrentMessage(); - } - } - - private void releaseCurrentMessage() { - if (currentMessage != null) { - currentMessage.release(); - currentMessage = null; - handlingOversizedMessage = false; - aggregating = false; - } - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/io/netty/handler/codec/EspressoMessageToMessageDecoder.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/io/netty/handler/codec/EspressoMessageToMessageDecoder.java deleted file mode 100644 index ef25a0ede33..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/io/netty/handler/codec/EspressoMessageToMessageDecoder.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project 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 io.netty.handler.codec; - -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; -import io.netty.util.ReferenceCountUtil; -import java.util.List; - - -/** - * Forked from Netty 4.1.42.Final. Main change is to avoid creating {@link io.netty.util.internal.TypeParameterMatcher}. - * - * {@link ChannelInboundHandlerAdapter} which decodes from one message to an other message. - * - * - * For example here is an implementation which decodes a {@link String} to an {@link Integer} which represent - * the length of the {@link String}. - * - *
- *     public class StringToIntegerDecoder extends
- *             {@link MessageToMessageDecoder}<{@link String}> {
- *
- *         {@code @Override}
- *         public void decode({@link ChannelHandlerContext} ctx, {@link String} message,
- *                            List<Object> out) throws {@link Exception} {
- *             out.add(message.length());
- *         }
- *     }
- * 
- * - * Be aware that you need to call {@link io.netty.util.ReferenceCounted#retain()} on messages that are just passed through if they - * are of type {@link io.netty.util.ReferenceCounted}. This is needed as the {@link MessageToMessageDecoder} will call - * {@link io.netty.util.ReferenceCounted#release()} on decoded messages. - * - */ -public abstract class EspressoMessageToMessageDecoder extends ChannelInboundHandlerAdapter { - /** - * Create a new instance which will try to detect the types to match out of the type parameter of the class. - */ - protected EspressoMessageToMessageDecoder() { - } - - /** - * Create a new instance - * - * @param inboundMessageType The type of messages to match and so decode - */ - protected EspressoMessageToMessageDecoder(Class inboundMessageType) { - } - - /** - * Returns {@code true} if the given message should be handled. If {@code false} it will be passed to the next - * {@link io.netty.channel.ChannelInboundHandler} in the {@link io.netty.channel.ChannelPipeline}. - */ - public boolean acceptInboundMessage(Object msg) throws Exception { - // Return true directly. Don't check with TypeParameterMatcher - return true; - } - - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - CodecOutputList out = CodecOutputList.newInstance(); - try { - if (acceptInboundMessage(msg)) { - @SuppressWarnings("unchecked") - I cast = (I) msg; - try { - decode(ctx, cast, out); - } finally { - ReferenceCountUtil.release(cast); - } - } else { - out.add(msg); - } - } catch (DecoderException e) { - throw e; - } catch (Exception e) { - throw new DecoderException(e); - } finally { - int size = out.size(); - for (int i = 0; i < size; i++) { - ctx.fireChannelRead(out.getUnsafe(i)); - } - out.recycle(); - } - } - - /** - * Decode from one message to an other. This method will be called for each written message that can be handled - * by this decoder. - * - * @param ctx the {@link ChannelHandlerContext} which this {@link MessageToMessageDecoder} belongs to - * @param msg the message to decode to an other one - * @param out the {@link List} to which decoded messages should be added - * @throws Exception is thrown if an error occurs - */ - protected abstract void decode(ChannelHandlerContext ctx, I msg, List out) throws Exception; -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/io/netty/handler/codec/EspressoMessageToMessageEncoder.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/io/netty/handler/codec/EspressoMessageToMessageEncoder.java deleted file mode 100644 index 94d2722b9a9..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/io/netty/handler/codec/EspressoMessageToMessageEncoder.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project 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 io.netty.handler.codec; - -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelOutboundHandlerAdapter; -import io.netty.channel.ChannelPromise; -import io.netty.util.ReferenceCountUtil; -import io.netty.util.concurrent.PromiseCombiner; -import io.netty.util.internal.StringUtil; -import java.util.List; - - -/** - * Forked from Netty 4.1.42.Final. Main change is to avoid creating {@link io.netty.util.internal.TypeParameterMatcher}. - * - * {@link ChannelOutboundHandlerAdapter} which encodes from one message to an other message - * - * For example here is an implementation which decodes an {@link Integer} to an {@link String}. - * - *
- *     public class IntegerToStringEncoder extends
- *             {@link MessageToMessageEncoder}<{@link Integer}> {
- *
- *         {@code @Override}
- *         public void encode({@link ChannelHandlerContext} ctx, {@link Integer} message, List<Object> out)
- *                 throws {@link Exception} {
- *             out.add(message.toString());
- *         }
- *     }
- * 
- * - * Be aware that you need to call {@link io.netty.util.ReferenceCounted#retain()} on messages that are just passed through if they - * are of type {@link io.netty.util.ReferenceCounted}. This is needed as the {@link MessageToMessageEncoder} will call - * {@link io.netty.util.ReferenceCounted#release()} on encoded messages. - */ -public abstract class EspressoMessageToMessageEncoder extends ChannelOutboundHandlerAdapter { - /** - * Create a new instance which will try to detect the types to match out of the type parameter of the class. - */ - protected EspressoMessageToMessageEncoder() { - } - - /** - * Create a new instance - * - * @param inboundMessageType The type of messages to match and so decode - */ - protected EspressoMessageToMessageEncoder(Class inboundMessageType) { - } - - @Override - public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { - CodecOutputList out = null; - try { - if (acceptOutboundMessage(msg)) { - out = CodecOutputList.newInstance(); - @SuppressWarnings("unchecked") - I cast = (I) msg; - try { - encode(ctx, cast, out); - } finally { - ReferenceCountUtil.release(cast); - } - - if (out.isEmpty()) { - out.recycle(); - out = null; - - throw new EncoderException(StringUtil.simpleClassName(this) + " must produce at least one message."); - } - } else { - ctx.write(msg, promise); - } - } catch (EncoderException e) { - throw e; - } catch (Throwable t) { - throw new EncoderException(t); - } finally { - if (out != null) { - final int sizeMinusOne = out.size() - 1; - if (sizeMinusOne == 0) { - ctx.write(out.getUnsafe(0), promise); - } else if (sizeMinusOne > 0) { - // Check if we can use a voidPromise for our extra writes to reduce GC-Pressure - // See https://github.com/netty/netty/issues/2525 - if (promise == ctx.voidPromise()) { - writeVoidPromise(ctx, out); - } else { - writePromiseCombiner(ctx, out, promise); - } - } - out.recycle(); - } - } - } - - protected boolean acceptOutboundMessage(Object msg) throws Exception { - // Return true directly. Don't call TypeParameterMatcher - return true; - } - - private static void writeVoidPromise(ChannelHandlerContext ctx, CodecOutputList out) { - final ChannelPromise voidPromise = ctx.voidPromise(); - for (int i = 0; i < out.size(); i++) { - ctx.write(out.getUnsafe(i), voidPromise); - } - } - - private static void writePromiseCombiner(ChannelHandlerContext ctx, CodecOutputList out, ChannelPromise promise) { - final PromiseCombiner combiner = new PromiseCombiner(ctx.executor()); - for (int i = 0; i < out.size(); i++) { - combiner.add(ctx.write(out.getUnsafe(i))); - } - combiner.finish(promise); - } - - /** - * Encode from one message to an other. This method will be called for each written message that can be handled - * by this encoder. - * - * @param ctx the {@link ChannelHandlerContext} which this {@link MessageToMessageEncoder} belongs to - * @param msg the message to encode to an other one - * @param out the {@link List} into which the encoded msg should be added - * needs to do some kind of aggregation - * @throws Exception is thrown if an error occurs - */ - protected abstract void encode(ChannelHandlerContext ctx, I msg, List out) throws Exception; -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/io/netty/handler/codec/http/EspressoHttpObjectAggregator.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/io/netty/handler/codec/http/EspressoHttpObjectAggregator.java deleted file mode 100644 index 80d81c4931c..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/io/netty/handler/codec/http/EspressoHttpObjectAggregator.java +++ /dev/null @@ -1,581 +0,0 @@ -package io.netty.handler.codec.http; - -/* - * Copyright 2012 The Netty Project - * - * The Netty Project 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. - */ - -import static io.netty.handler.codec.http.HttpHeaderNames.CONNECTION; -import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH; -import static io.netty.handler.codec.http.HttpHeaderNames.EXPECT; -import static io.netty.handler.codec.http.HttpUtil.getContentLength; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelPipeline; -import io.netty.handler.codec.DecoderResult; -import io.netty.handler.codec.EspressoMessageAggregator; -import io.netty.handler.codec.TooLongFrameException; -import io.netty.util.internal.logging.InternalLogger; -import io.netty.util.internal.logging.InternalLoggerFactory; - - -/** - * Forked from Netty 4.1.42.Final. Main change is to extend EspressoMessageAggregator to avoid creating - * {@link io.netty.util.internal.TypeParameterMatcher}. - * - * A {@link io.netty.channel.ChannelHandler} that aggregates an {@link HttpMessage} - * and its following {@link HttpContent}s into a single {@link FullHttpRequest} - * or {@link FullHttpResponse} (depending on if it used to handle requests or responses) - * with no following {@link HttpContent}s. It is useful when you don't want to take - * care of HTTP messages whose transfer encoding is 'chunked'. Insert this - * handler after {@link HttpResponseDecoder} in the {@link ChannelPipeline} if being used to handle - * responses, or after {@link HttpRequestDecoder} and {@link HttpResponseEncoder} in the - * {@link ChannelPipeline} if being used to handle requests. - *
- *
- *  {@link ChannelPipeline} p = ...;
- *  ...
- *  p.addLast("decoder", new {@link HttpRequestDecoder}());
- *  p.addLast("encoder", new {@link HttpResponseEncoder}());
- *  p.addLast("aggregator", new {@link HttpObjectAggregator}(1048576));
- *  ...
- *  p.addLast("handler", new HttpRequestHandler());
- *  
- *
- *

- * For convenience, consider putting a {@link HttpServerCodec} before the {@link HttpObjectAggregator} - * as it functions as both a {@link HttpRequestDecoder} and a {@link HttpResponseEncoder}. - *

- * Be aware that {@link HttpObjectAggregator} may end up sending a {@link HttpResponse}: - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
Response StatusCondition When Sent
100 ContinueA '100-continue' expectation is received and the 'content-length' doesn't exceed maxContentLength
417 Expectation FailedA '100-continue' expectation is received and the 'content-length' exceeds maxContentLength
413 Request Entity Too LargeEither the 'content-length' or the bytes received so far exceed maxContentLength
- * - * @see FullHttpRequest - * @see FullHttpResponse - * @see HttpResponseDecoder - * @see HttpServerCodec - */ -public class EspressoHttpObjectAggregator - extends EspressoMessageAggregator { - private static final InternalLogger logger = InternalLoggerFactory.getInstance(HttpObjectAggregator.class); - private static final FullHttpResponse CONTINUE = - new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.CONTINUE, Unpooled.EMPTY_BUFFER); - private static final FullHttpResponse EXPECTATION_FAILED = - new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.EXPECTATION_FAILED, Unpooled.EMPTY_BUFFER); - private static final FullHttpResponse TOO_LARGE_CLOSE = new DefaultFullHttpResponse( - HttpVersion.HTTP_1_1, - HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE, - Unpooled.EMPTY_BUFFER); - private static final FullHttpResponse TOO_LARGE = new DefaultFullHttpResponse( - HttpVersion.HTTP_1_1, - HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE, - Unpooled.EMPTY_BUFFER); - - static { - EXPECTATION_FAILED.headers().set(CONTENT_LENGTH, 0); - TOO_LARGE.headers().set(CONTENT_LENGTH, 0); - - TOO_LARGE_CLOSE.headers().set(CONTENT_LENGTH, 0); - TOO_LARGE_CLOSE.headers().set(CONNECTION, HttpHeaderValues.CLOSE); - } - - private final boolean closeOnExpectationFailed; - - /** - * Creates a new instance. - * @param maxContentLength the maximum length of the aggregated content in bytes. - * If the length of the aggregated content exceeds this value, - * {@link #handleOversizedMessage(ChannelHandlerContext, HttpMessage)} will be called. - */ - public EspressoHttpObjectAggregator(int maxContentLength) { - this(maxContentLength, false); - } - - /** - * Creates a new instance. - * @param maxContentLength the maximum length of the aggregated content in bytes. - * If the length of the aggregated content exceeds this value, - * {@link #handleOversizedMessage(ChannelHandlerContext, HttpMessage)} will be called. - * @param closeOnExpectationFailed If a 100-continue response is detected but the content length is too large - * then {@code true} means close the connection. otherwise the connection will remain open and data will be - * consumed and discarded until the next request is received. - */ - public EspressoHttpObjectAggregator(int maxContentLength, boolean closeOnExpectationFailed) { - super(maxContentLength); - this.closeOnExpectationFailed = closeOnExpectationFailed; - } - - @Override - protected boolean isStartMessage(HttpObject msg) throws Exception { - return msg instanceof HttpMessage; - } - - @Override - protected boolean isContentMessage(HttpObject msg) throws Exception { - return msg instanceof HttpContent; - } - - @Override - protected boolean isLastContentMessage(HttpContent msg) throws Exception { - return msg instanceof LastHttpContent; - } - - @Override - protected boolean isAggregated(HttpObject msg) throws Exception { - return msg instanceof FullHttpMessage; - } - - @Override - protected boolean isContentLengthInvalid(HttpMessage start, int maxContentLength) { - try { - return getContentLength(start, -1L) > maxContentLength; - } catch (final NumberFormatException e) { - return false; - } - } - - private static Object continueResponse(HttpMessage start, int maxContentLength, ChannelPipeline pipeline) { - if (HttpUtil.isUnsupportedExpectation(start)) { - // if the request contains an unsupported expectation, we return 417 - pipeline.fireUserEventTriggered(HttpExpectationFailedEvent.INSTANCE); - return EXPECTATION_FAILED.retainedDuplicate(); - } else if (HttpUtil.is100ContinueExpected(start)) { - // if the request contains 100-continue but the content-length is too large, we return 413 - if (getContentLength(start, -1L) <= maxContentLength) { - return CONTINUE.retainedDuplicate(); - } - pipeline.fireUserEventTriggered(HttpExpectationFailedEvent.INSTANCE); - return TOO_LARGE.retainedDuplicate(); - } - - return null; - } - - @Override - protected Object newContinueResponse(HttpMessage start, int maxContentLength, ChannelPipeline pipeline) { - Object response = continueResponse(start, maxContentLength, pipeline); - // we're going to respond based on the request expectation so there's no - // need to propagate the expectation further. - if (response != null) { - start.headers().remove(EXPECT); - } - return response; - } - - @Override - protected boolean closeAfterContinueResponse(Object msg) { - return closeOnExpectationFailed && ignoreContentAfterContinueResponse(msg); - } - - @Override - protected boolean ignoreContentAfterContinueResponse(Object msg) { - if (msg instanceof HttpResponse) { - final HttpResponse httpResponse = (HttpResponse) msg; - return httpResponse.status().codeClass().equals(HttpStatusClass.CLIENT_ERROR); - } - return false; - } - - @Override - protected FullHttpMessage beginAggregation(HttpMessage start, ByteBuf content) throws Exception { - assert !(start instanceof FullHttpMessage); - - HttpUtil.setTransferEncodingChunked(start, false); - - AggregatedFullHttpMessage ret; - if (start instanceof HttpRequest) { - ret = new AggregatedFullHttpRequest((HttpRequest) start, content, null); - } else if (start instanceof HttpResponse) { - ret = new AggregatedFullHttpResponse((HttpResponse) start, content, null); - } else { - throw new Error(); - } - return ret; - } - - @Override - protected void aggregate(FullHttpMessage aggregated, HttpContent content) throws Exception { - if (content instanceof LastHttpContent) { - // Merge trailing headers into the message. - ((AggregatedFullHttpMessage) aggregated).setTrailingHeaders(((LastHttpContent) content).trailingHeaders()); - } - } - - @Override - protected void finishAggregation(FullHttpMessage aggregated) throws Exception { - // Set the 'Content-Length' header. If one isn't already set. - // This is important as HEAD responses will use a 'Content-Length' header which - // does not match the actual body, but the number of bytes that would be - // transmitted if a GET would have been used. - // - // See rfc2616 14.13 Content-Length - if (!HttpUtil.isContentLengthSet(aggregated)) { - aggregated.headers().set(CONTENT_LENGTH, String.valueOf(aggregated.content().readableBytes())); - } - } - - @Override - protected void handleOversizedMessage(final ChannelHandlerContext ctx, HttpMessage oversized) throws Exception { - if (oversized instanceof HttpRequest) { - // send back a 413 and close the connection - - // If the client started to send data already, close because it's impossible to recover. - // If keep-alive is off and 'Expect: 100-continue' is missing, no need to leave the connection open. - if (oversized instanceof FullHttpMessage - || !HttpUtil.is100ContinueExpected(oversized) && !HttpUtil.isKeepAlive(oversized)) { - ChannelFuture future = ctx.writeAndFlush(TOO_LARGE_CLOSE.retainedDuplicate()); - future.addListener((ChannelFutureListener) future1 -> { - if (!future1.isSuccess()) { - logger.debug("Failed to send a 413 Request Entity Too Large.", future1.cause()); - } - ctx.close(); - }); - } else { - ctx.writeAndFlush(TOO_LARGE.retainedDuplicate()).addListener((ChannelFutureListener) future -> { - if (!future.isSuccess()) { - logger.debug("Failed to send a 413 Request Entity Too Large.", future.cause()); - ctx.close(); - } - }); - } - } else if (oversized instanceof HttpResponse) { - ctx.close(); - throw new TooLongFrameException("Response entity too large: " + oversized); - } else { - throw new IllegalStateException(); - } - } - - private abstract static class AggregatedFullHttpMessage implements FullHttpMessage { - protected final HttpMessage message; - private final ByteBuf content; - private HttpHeaders trailingHeaders; - - AggregatedFullHttpMessage(HttpMessage message, ByteBuf content, HttpHeaders trailingHeaders) { - this.message = message; - this.content = content; - this.trailingHeaders = trailingHeaders; - } - - @Override - public HttpHeaders trailingHeaders() { - HttpHeaders trailingHeaders = this.trailingHeaders; - if (trailingHeaders == null) { - return EmptyHttpHeaders.INSTANCE; - } else { - return trailingHeaders; - } - } - - void setTrailingHeaders(HttpHeaders trailingHeaders) { - this.trailingHeaders = trailingHeaders; - } - - @Override - public HttpVersion getProtocolVersion() { - return message.protocolVersion(); - } - - @Override - public HttpVersion protocolVersion() { - return message.protocolVersion(); - } - - @Override - public FullHttpMessage setProtocolVersion(HttpVersion version) { - message.setProtocolVersion(version); - return this; - } - - @Override - public HttpHeaders headers() { - return message.headers(); - } - - @Override - public DecoderResult decoderResult() { - return message.decoderResult(); - } - - @Override - public DecoderResult getDecoderResult() { - return message.decoderResult(); - } - - @Override - public void setDecoderResult(DecoderResult result) { - message.setDecoderResult(result); - } - - @Override - public ByteBuf content() { - return content; - } - - @Override - public int refCnt() { - return content.refCnt(); - } - - @Override - public FullHttpMessage retain() { - content.retain(); - return this; - } - - @Override - public FullHttpMessage retain(int increment) { - content.retain(increment); - return this; - } - - @Override - public FullHttpMessage touch(Object hint) { - content.touch(hint); - return this; - } - - @Override - public FullHttpMessage touch() { - content.touch(); - return this; - } - - @Override - public boolean release() { - return content.release(); - } - - @Override - public boolean release(int decrement) { - return content.release(decrement); - } - - @Override - public abstract FullHttpMessage copy(); - - @Override - public abstract FullHttpMessage duplicate(); - - @Override - public abstract FullHttpMessage retainedDuplicate(); - } - - private static final class AggregatedFullHttpRequest extends AggregatedFullHttpMessage implements FullHttpRequest { - AggregatedFullHttpRequest(HttpRequest request, ByteBuf content, HttpHeaders trailingHeaders) { - super(request, content, trailingHeaders); - } - - @Override - public FullHttpRequest copy() { - return replace(content().copy()); - } - - @Override - public FullHttpRequest duplicate() { - return replace(content().duplicate()); - } - - @Override - public FullHttpRequest retainedDuplicate() { - return replace(content().retainedDuplicate()); - } - - @Override - public FullHttpRequest replace(ByteBuf content) { - DefaultFullHttpRequest dup = new DefaultFullHttpRequest( - protocolVersion(), - method(), - uri(), - content, - headers().copy(), - trailingHeaders().copy()); - dup.setDecoderResult(decoderResult()); - return dup; - } - - @Override - public FullHttpRequest retain(int increment) { - super.retain(increment); - return this; - } - - @Override - public FullHttpRequest retain() { - super.retain(); - return this; - } - - @Override - public FullHttpRequest touch() { - super.touch(); - return this; - } - - @Override - public FullHttpRequest touch(Object hint) { - super.touch(hint); - return this; - } - - @Override - public FullHttpRequest setMethod(HttpMethod method) { - ((HttpRequest) message).setMethod(method); - return this; - } - - @Override - public FullHttpRequest setUri(String uri) { - ((HttpRequest) message).setUri(uri); - return this; - } - - @Override - public HttpMethod getMethod() { - return ((HttpRequest) message).method(); - } - - @Override - public String getUri() { - return ((HttpRequest) message).uri(); - } - - @Override - public HttpMethod method() { - return getMethod(); - } - - @Override - public String uri() { - return getUri(); - } - - @Override - public FullHttpRequest setProtocolVersion(HttpVersion version) { - super.setProtocolVersion(version); - return this; - } - - @Override - public String toString() { - return HttpMessageUtil.appendFullRequest(new StringBuilder(256), this).toString(); - } - } - - private static final class AggregatedFullHttpResponse extends AggregatedFullHttpMessage implements FullHttpResponse { - AggregatedFullHttpResponse(HttpResponse message, ByteBuf content, HttpHeaders trailingHeaders) { - super(message, content, trailingHeaders); - } - - @Override - public FullHttpResponse copy() { - return replace(content().copy()); - } - - @Override - public FullHttpResponse duplicate() { - return replace(content().duplicate()); - } - - @Override - public FullHttpResponse retainedDuplicate() { - return replace(content().retainedDuplicate()); - } - - @Override - public FullHttpResponse replace(ByteBuf content) { - DefaultFullHttpResponse dup = new DefaultFullHttpResponse( - getProtocolVersion(), - getStatus(), - content, - headers().copy(), - trailingHeaders().copy()); - dup.setDecoderResult(decoderResult()); - return dup; - } - - @Override - public FullHttpResponse setStatus(HttpResponseStatus status) { - ((HttpResponse) message).setStatus(status); - return this; - } - - @Override - public HttpResponseStatus getStatus() { - return ((HttpResponse) message).status(); - } - - @Override - public HttpResponseStatus status() { - return getStatus(); - } - - @Override - public FullHttpResponse setProtocolVersion(HttpVersion version) { - super.setProtocolVersion(version); - return this; - } - - @Override - public FullHttpResponse retain(int increment) { - super.retain(increment); - return this; - } - - @Override - public FullHttpResponse retain() { - super.retain(); - return this; - } - - @Override - public FullHttpResponse touch(Object hint) { - super.touch(hint); - return this; - } - - @Override - public FullHttpResponse touch() { - super.touch(); - return this; - } - - @Override - public String toString() { - return HttpMessageUtil.appendFullResponse(new StringBuilder(256), this).toString(); - } - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/main/java/io/netty/handler/codec/http/EspressoHttpObjectEncoder.java b/internal/alpini/netty4/alpini-netty4-base/src/main/java/io/netty/handler/codec/http/EspressoHttpObjectEncoder.java deleted file mode 100644 index ce9c390c9c7..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/main/java/io/netty/handler/codec/http/EspressoHttpObjectEncoder.java +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project 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 io.netty.handler.codec.http; - -import static io.netty.buffer.Unpooled.directBuffer; -import static io.netty.buffer.Unpooled.unreleasableBuffer; -import static io.netty.handler.codec.http.HttpConstants.CR; -import static io.netty.handler.codec.http.HttpConstants.LF; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufUtil; -import io.netty.buffer.Unpooled; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.FileRegion; -import io.netty.handler.codec.EspressoMessageToMessageEncoder; -import io.netty.util.CharsetUtil; -import io.netty.util.internal.StringUtil; -import java.util.Iterator; -import java.util.List; -import java.util.Map.Entry; - - -/** - * Forked from Netty 4.1.42.Final. Main change is to extend EspressoMessageToMessageEncoder to avoid creating - * {@link io.netty.util.internal.TypeParameterMatcher}. - * - * Encodes an {@link HttpMessage} or an {@link HttpContent} into - * a {@link ByteBuf}. - * - *

Extensibility

- * - * Please note that this encoder is designed to be extended to implement - * a protocol derived from HTTP, such as - * RTSP and - * ICAP. - * To implement the encoder of such a derived protocol, extend this class and - * implement all abstract methods properly. - */ -public abstract class EspressoHttpObjectEncoder extends EspressoMessageToMessageEncoder { - static final int CRLF_SHORT = (CR << 8) | LF; - private static final int ZERO_CRLF_MEDIUM = ('0' << 16) | CRLF_SHORT; - private static final byte[] ZERO_CRLF_CRLF = { '0', CR, LF, CR, LF }; - private static final ByteBuf CRLF_BUF = unreleasableBuffer(directBuffer(2).writeByte(CR).writeByte(LF)); - private static final ByteBuf ZERO_CRLF_CRLF_BUF = - unreleasableBuffer(directBuffer(ZERO_CRLF_CRLF.length).writeBytes(ZERO_CRLF_CRLF)); - private static final float HEADERS_WEIGHT_NEW = 1 / 5f; - private static final float HEADERS_WEIGHT_HISTORICAL = 1 - HEADERS_WEIGHT_NEW; - private static final float TRAILERS_WEIGHT_NEW = HEADERS_WEIGHT_NEW; - private static final float TRAILERS_WEIGHT_HISTORICAL = HEADERS_WEIGHT_HISTORICAL; - - private static final int ST_INIT = 0; - private static final int ST_CONTENT_NON_CHUNK = 1; - private static final int ST_CONTENT_CHUNK = 2; - private static final int ST_CONTENT_ALWAYS_EMPTY = 3; - - @SuppressWarnings("RedundantFieldInitialization") - private int state = ST_INIT; - - /** - * Used to calculate an exponential moving average of the encoded size of the initial line and the headers for - * a guess for future buffer allocations. - */ - private float headersEncodedSizeAccumulator = 256; - - /** - * Used to calculate an exponential moving average of the encoded size of the trailers for - * a guess for future buffer allocations. - */ - private float trailersEncodedSizeAccumulator = 256; - - @Override - protected void encode(ChannelHandlerContext ctx, Object msg, List out) throws Exception { - ByteBuf buf = null; - if (msg instanceof HttpMessage) { - if (state != ST_INIT) { - throw new IllegalStateException( - "unexpected message type: " + StringUtil.simpleClassName(msg) + ", state: " + state); - } - - @SuppressWarnings({ "unchecked", "CastConflictsWithInstanceof" }) - H m = (H) msg; - - buf = ctx.alloc().buffer((int) headersEncodedSizeAccumulator); - // Encode the message. - encodeInitialLine(buf, m); - state = isContentAlwaysEmpty(m) - ? ST_CONTENT_ALWAYS_EMPTY - : HttpUtil.isTransferEncodingChunked(m) ? ST_CONTENT_CHUNK : ST_CONTENT_NON_CHUNK; - - sanitizeHeadersBeforeEncode(m, state == ST_CONTENT_ALWAYS_EMPTY); - - encodeHeaders(m.headers(), buf); - ByteBufUtil.writeShortBE(buf, CRLF_SHORT); - - headersEncodedSizeAccumulator = HEADERS_WEIGHT_NEW * padSizeForAccumulation(buf.readableBytes()) - + HEADERS_WEIGHT_HISTORICAL * headersEncodedSizeAccumulator; - } - - // Bypass the encoder in case of an empty buffer, so that the following idiom works: - // - // ch.write(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE); - // - // See https://github.com/netty/netty/issues/2983 for more information. - if (msg instanceof ByteBuf) { - final ByteBuf potentialEmptyBuf = (ByteBuf) msg; - if (!potentialEmptyBuf.isReadable()) { - out.add(potentialEmptyBuf.retain()); - return; - } - } - - if (msg instanceof HttpContent || msg instanceof ByteBuf || msg instanceof FileRegion) { - switch (state) { - case ST_INIT: - throw new IllegalStateException("unexpected message type: " + StringUtil.simpleClassName(msg)); - case ST_CONTENT_NON_CHUNK: - final long contentLength = contentLength(msg); - if (contentLength > 0) { - if (buf != null && buf.writableBytes() >= contentLength && msg instanceof HttpContent) { - // merge into other buffer for performance reasons - buf.writeBytes(((HttpContent) msg).content()); - out.add(buf); - } else { - if (buf != null) { - out.add(buf); - } - out.add(encodeAndRetain(msg)); - } - - if (msg instanceof LastHttpContent) { - state = ST_INIT; - } - - break; - } - - // fall-through! - case ST_CONTENT_ALWAYS_EMPTY: // SUPPRESS CHECKSTYLE FallThroughCheck - - if (buf != null) { - // We allocated a buffer so add it now. - out.add(buf); - } else { - // Need to produce some output otherwise an - // IllegalStateException will be thrown as we did not write anything - // Its ok to just write an EMPTY_BUFFER as if there are reference count issues these will be - // propagated as the caller of the encode(...) method will release the original - // buffer. - // Writing an empty buffer will not actually write anything on the wire, so if there is a user - // error with msg it will not be visible externally - out.add(Unpooled.EMPTY_BUFFER); - } - - break; - case ST_CONTENT_CHUNK: - if (buf != null) { - // We allocated a buffer so add it now. - out.add(buf); - } - encodeChunkedContent(ctx, msg, contentLength(msg), out); - - break; - default: - throw new Error(); - } - - if (msg instanceof LastHttpContent) { - state = ST_INIT; - } - } else if (buf != null) { - out.add(buf); - } - } - - /** - * Encode the {@link HttpHeaders} into a {@link ByteBuf}. - */ - protected void encodeHeaders(HttpHeaders headers, ByteBuf buf) { - Iterator> iter = headers.iteratorCharSequence(); - while (iter.hasNext()) { - Entry header = iter.next(); - HttpHeadersEncoder.encoderHeader(header.getKey(), header.getValue(), buf); - } - } - - private void encodeChunkedContent(ChannelHandlerContext ctx, Object msg, long contentLength, List out) { - if (contentLength > 0) { - String lengthHex = Long.toHexString(contentLength); - ByteBuf buf = ctx.alloc().buffer(lengthHex.length() + 2); - buf.writeCharSequence(lengthHex, CharsetUtil.US_ASCII); - ByteBufUtil.writeShortBE(buf, CRLF_SHORT); - out.add(buf); - out.add(encodeAndRetain(msg)); - out.add(CRLF_BUF.duplicate()); - } - - if (msg instanceof LastHttpContent) { - HttpHeaders headers = ((LastHttpContent) msg).trailingHeaders(); - if (headers.isEmpty()) { - out.add(ZERO_CRLF_CRLF_BUF.duplicate()); - } else { - ByteBuf buf = ctx.alloc().buffer((int) trailersEncodedSizeAccumulator); - ByteBufUtil.writeMediumBE(buf, ZERO_CRLF_MEDIUM); - encodeHeaders(headers, buf); - ByteBufUtil.writeShortBE(buf, CRLF_SHORT); - trailersEncodedSizeAccumulator = TRAILERS_WEIGHT_NEW * padSizeForAccumulation(buf.readableBytes()) - + TRAILERS_WEIGHT_HISTORICAL * trailersEncodedSizeAccumulator; - out.add(buf); - } - } else if (contentLength == 0) { - // Need to produce some output otherwise an - // IllegalStateException will be thrown - out.add(encodeAndRetain(msg)); - } - } - - /** - * Allows to sanitize headers of the message before encoding these. - */ - protected void sanitizeHeadersBeforeEncode(@SuppressWarnings("unused") H msg, boolean isAlwaysEmpty) { - // noop - } - - /** - * Determine whether a message has a content or not. Some message may have headers indicating - * a content without having an actual content, e.g the response to an HEAD or CONNECT request. - * - * @param msg the message to test - * @return {@code true} to signal the message has no content - */ - protected boolean isContentAlwaysEmpty(@SuppressWarnings("unused") H msg) { - return false; - } - - @Override - public boolean acceptOutboundMessage(Object msg) throws Exception { - return msg instanceof HttpObject || msg instanceof ByteBuf || msg instanceof FileRegion; - } - - private static Object encodeAndRetain(Object msg) { - if (msg instanceof ByteBuf) { - return ((ByteBuf) msg).retain(); - } - if (msg instanceof HttpContent) { - return ((HttpContent) msg).content().retain(); - } - if (msg instanceof FileRegion) { - return ((FileRegion) msg).retain(); - } - throw new IllegalStateException("unexpected message type: " + StringUtil.simpleClassName(msg)); - } - - private static long contentLength(Object msg) { - if (msg instanceof HttpContent) { - return ((HttpContent) msg).content().readableBytes(); - } - if (msg instanceof ByteBuf) { - return ((ByteBuf) msg).readableBytes(); - } - if (msg instanceof FileRegion) { - return ((FileRegion) msg).count(); - } - throw new IllegalStateException("unexpected message type: " + StringUtil.simpleClassName(msg)); - } - - /** - * Add some additional overhead to the buffer. The rational is that it is better to slightly over allocate and waste - * some memory, rather than under allocate and require a resize/copy. - * @param readableBytes The readable bytes in the buffer. - * @return The {@code readableBytes} with some additional padding. - */ - private static int padSizeForAccumulation(int readableBytes) { - return (readableBytes << 2) / 3; - } - - @Deprecated - protected static void encodeAscii(String s, ByteBuf buf) { - buf.writeCharSequence(s, CharsetUtil.US_ASCII); - } - - protected abstract void encodeInitialLine(ByteBuf buf, H message) throws Exception; -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/TestByteBufAsciiStringCharacter.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/TestByteBufAsciiStringCharacter.java deleted file mode 100644 index 566612175d2..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/TestByteBufAsciiStringCharacter.java +++ /dev/null @@ -1,801 +0,0 @@ -package com.linkedin.alpini.base; - -import com.linkedin.alpini.base.misc.ByteBufAsciiString; -import io.netty.buffer.UnpooledByteBufAllocator; -import io.netty.util.AsciiString; -import io.netty.util.CharsetUtil; -import java.nio.CharBuffer; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.Random; -import java.util.regex.Pattern; -import org.testng.Assert; -import org.testng.annotations.Test; - - -public class TestByteBufAsciiStringCharacter { - private static final Random r = new Random(); - - @Test(groups = "unit") - public void testGetBytesStringBuilder() { - final StringBuilder b = new StringBuilder(); - for (int i = 0; i < 1 << 16; ++i) { - b.append("eéaà"); - } - final String bString = b.toString(); - final Charset[] charsets = CharsetUtil.values(); - for (int i = 0; i < charsets.length; ++i) { - final Charset charset = charsets[i]; - byte[] expected = bString.getBytes(charset); - ByteBufAsciiString byteBufAsciiString = new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, b, charset); - byte[] actual = byteBufAsciiString.toByteArray(); - Assert.assertEquals(actual, expected, "failure for " + charset); - Assert.assertTrue(ByteBufAsciiString.contentEquals(byteBufAsciiString, new AsciiString(b, charset))); - Assert.assertTrue(ByteBufAsciiString.contentEquals(new AsciiString(b, charset), byteBufAsciiString)); - Assert - .assertTrue(ByteBufAsciiString.contentEquals(new AsciiString(b, charset), new AsciiString(bString, charset))); - Assert.assertTrue(ByteBufAsciiString.contentEquals(byteBufAsciiString, byteBufAsciiString)); - Assert.assertTrue( - ByteBufAsciiString - .contentEquals(byteBufAsciiString, new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, b, charset))); - } - } - - @Test(groups = "unit") - public void testGetBytesString() { - final StringBuilder b = new StringBuilder(); - for (int i = 0; i < 1 << 16; ++i) { - b.append("eéaà"); - } - final String bString = b.toString(); - final Charset[] charsets = CharsetUtil.values(); - for (int i = 0; i < charsets.length; ++i) { - final Charset charset = charsets[i]; - byte[] expected = bString.getBytes(charset); - ByteBufAsciiString byteBufAsciiString = - new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, bString, charset); - byte[] actual = byteBufAsciiString.toByteArray(); - Assert.assertEquals(actual, expected, "failure for " + charset); - Assert.assertTrue(ByteBufAsciiString.contentEquals(byteBufAsciiString, new AsciiString(bString, charset))); - Assert.assertTrue(ByteBufAsciiString.contentEquals(new AsciiString(bString, charset), byteBufAsciiString)); - } - } - - @Test(groups = "unit") - public void testGetBytesAsciiString() { - final StringBuilder b = new StringBuilder(); - for (int i = 0; i < 1 << 16; ++i) { - b.append("eéaà"); - } - final String bString = b.toString(); - // The AsciiString class actually limits the Charset to ISO_8859_1 - byte[] expected = bString.getBytes(CharsetUtil.ISO_8859_1); - byte[] actual = new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, bString).toByteArray(); - Assert.assertEquals(actual, expected); - } - - @Test(groups = "unit") - public void testComparisonWithString() { - String string = "shouldn't fail"; - ByteBufAsciiString ascii = new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, string.toCharArray()); - Assert.assertEquals(ascii.toString(), string); - } - - @Test(groups = "unit") - public void subSequenceTest() { - byte[] init = { 't', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't' }; - ByteBufAsciiString ascii = new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, init); - final int start = 2; - final int end = init.length; - ByteBufAsciiString sub1 = ascii.subSequence(start, end, false); - ByteBufAsciiString sub2 = ascii.subSequence(start, end); - Assert.assertEquals(sub1.hashCode(), sub2.hashCode()); - Assert.assertEquals(sub1, sub2); - for (int i = start; i < end; ++i) { - Assert.assertEquals(init[i], sub1.byteAt(i - start)); - } - Assert.assertThrows(IndexOutOfBoundsException.class, () -> sub1.byteAt(20)); - Assert.assertEquals(ascii.subSequence(10).toString(), "test"); - Assert.assertSame(ascii.subSequence(0, ascii.length()), ascii); - Assert.assertThrows(IndexOutOfBoundsException.class, () -> ascii.subSequence(0, ascii.length() + 1)); - char[] chars = ascii.toString().toCharArray(); - Assert.assertThrows( - IndexOutOfBoundsException.class, - () -> new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, chars, 0, 20)); - Assert.assertThrows( - IndexOutOfBoundsException.class, - () -> new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, ascii, 0, 20)); - } - - @Test(groups = "unit") - public void testContains() { - String[] falseLhs = { null, "a", "aa", "aaa" }; - String[] falseRhs = { null, "b", "ba", "baa" }; - for (int i = 0; i < falseLhs.length; ++i) { - for (int j = 0; j < falseRhs.length; ++j) { - assertContains(falseLhs[i], falseRhs[i], false, false); - } - } - - assertContains("", "", true, true); - assertContains("AsfdsF", "", true, true); - assertContains("", "b", false, false); - assertContains("a", "a", true, true); - assertContains("a", "b", false, false); - assertContains("a", "A", false, true); - String b = "xyz"; - String a = b; - assertContains(a, b, true, true); - - a = "a" + b; - assertContains(a, b, true, true); - - a = b + "a"; - assertContains(a, b, true, true); - - a = "a" + b + "a"; - assertContains(a, b, true, true); - - b = "xYz"; - a = "xyz"; - assertContains(a, b, false, true); - - b = "xYz"; - a = "xyzxxxXyZ" + b + "aaa"; - assertContains(a, b, true, true); - - b = "foOo"; - a = "fooofoO"; - assertContains(a, b, false, true); - - b = "Content-Equals: 10000"; - a = "content-equals: 1000"; - assertContains(a, b, false, false); - a += "0"; - assertContains(a, b, false, true); - } - - private static void assertContains(String a, String b, boolean caseSensitiveEquals, boolean caseInsenstaiveEquals) { - Assert.assertEquals(ByteBufAsciiString.contains(a, b), caseSensitiveEquals); - Assert.assertEquals(ByteBufAsciiString.containsIgnoreCase(a, b), caseInsenstaiveEquals); - - ByteBufAsciiString aString = a != null ? new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, a) : null; - ByteBufAsciiString bString = a != null ? new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, b) : null; - Assert.assertEquals(ByteBufAsciiString.contains(aString, bString), caseSensitiveEquals); - Assert.assertEquals(ByteBufAsciiString.containsIgnoreCase(aString, bString), caseInsenstaiveEquals); - } - - @Test(groups = "unit") - public void testCaseSensitivity() { - int i = 0; - for (; i < 32; i++) { - doCaseSensitivity(i); - } - final int min = i; - final int max = 4000; - final int len = r.nextInt((max - min) + 1) + min; - doCaseSensitivity(len); - } - - private static void doCaseSensitivity(int len) { - // Build an upper case and lower case string - final int upperA = 'A'; - final int upperZ = 'Z'; - final int upperToLower = (int) 'a' - upperA; - byte[] lowerCaseBytes = new byte[len]; - StringBuilder upperCaseBuilder = new StringBuilder(len); - for (int i = 0; i < len; ++i) { - char upper = (char) (r.nextInt((upperZ - upperA) + 1) + upperA); - upperCaseBuilder.append(upper); - lowerCaseBytes[i] = (byte) (upper + upperToLower); - } - String upperCaseString = upperCaseBuilder.toString(); - String lowerCaseString = new String(lowerCaseBytes); - ByteBufAsciiString lowerCaseAscii = new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, lowerCaseBytes); - ByteBufAsciiString upperCaseAscii = new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, upperCaseString); - - Assert.assertSame(lowerCaseAscii.toLowerCase(), lowerCaseAscii); - Assert.assertSame(upperCaseAscii.toUpperCase(), upperCaseAscii); - - final String errorString = "len: " + len; - // Test upper case hash codes are equal - final int upperCaseExpected = upperCaseAscii.hashCode(); - Assert.assertEquals(ByteBufAsciiString.hashCode(upperCaseBuilder), upperCaseExpected, errorString); - Assert.assertEquals(ByteBufAsciiString.hashCode(upperCaseString), upperCaseExpected, errorString); - Assert.assertEquals(upperCaseAscii.hashCode(), upperCaseExpected, errorString); - - // Test lower case hash codes are equal - final int lowerCaseExpected = lowerCaseAscii.hashCode(); - Assert.assertEquals(ByteBufAsciiString.hashCode(lowerCaseAscii), lowerCaseExpected, errorString); - Assert.assertEquals(ByteBufAsciiString.hashCode(lowerCaseString), lowerCaseExpected, errorString); - Assert.assertEquals(lowerCaseAscii.hashCode(), lowerCaseExpected, errorString); - - // Test case insensitive hash codes are equal - final int expectedCaseInsensitive = lowerCaseAscii.hashCode(); - Assert.assertEquals(ByteBufAsciiString.hashCode(upperCaseBuilder), expectedCaseInsensitive, errorString); - Assert.assertEquals(ByteBufAsciiString.hashCode(upperCaseString), expectedCaseInsensitive, errorString); - Assert.assertEquals(ByteBufAsciiString.hashCode(lowerCaseString), expectedCaseInsensitive, errorString); - Assert.assertEquals(ByteBufAsciiString.hashCode(lowerCaseAscii), expectedCaseInsensitive, errorString); - Assert.assertEquals(ByteBufAsciiString.hashCode(upperCaseAscii), expectedCaseInsensitive, errorString); - Assert.assertEquals(lowerCaseAscii.hashCode(), expectedCaseInsensitive); - Assert.assertEquals(upperCaseAscii.hashCode(), expectedCaseInsensitive); - - // Test that opposite cases are equal - Assert.assertEquals(ByteBufAsciiString.hashCode(upperCaseString), lowerCaseAscii.hashCode(), errorString); - Assert.assertEquals(ByteBufAsciiString.hashCode(lowerCaseString), upperCaseAscii.hashCode(), errorString); - - Assert.assertEquals(upperCaseAscii.toLowerCase(), lowerCaseAscii); - Assert.assertEquals(lowerCaseAscii.toUpperCase(), upperCaseAscii); - Assert.assertEquals( - upperCaseAscii, - new ByteBufAsciiString( - UnpooledByteBufAllocator.DEFAULT, - upperCaseAscii.toString().toCharArray(), - StandardCharsets.UTF_8)); - } - - @Test(groups = "unit") - public void caseInsensitiveHasherCharBuffer() { - String s1 = new String("TRANSFER-ENCODING"); - char[] array = new char[128]; - final int offset = 100; - for (int i = 0; i < s1.length(); ++i) { - array[offset + i] = s1.charAt(i); - } - CharBuffer buffer = CharBuffer.wrap(array, offset, s1.length()); - Assert.assertEquals(ByteBufAsciiString.hashCode(s1), ByteBufAsciiString.hashCode(buffer)); - } - - /*@Test(groups = "unit") - public void testBooleanUtilityMethods() { - assertTrue(new AsciiString(new byte[] { 1 }).parseBoolean()); - assertFalse(AsciiString.EMPTY_STRING.parseBoolean()); - assertFalse(new AsciiString(new byte[] { 0 }).parseBoolean()); - assertTrue(new AsciiString(new byte[] { 5 }).parseBoolean()); - assertTrue(new AsciiString(new byte[] { 2, 0 }).parseBoolean()); - }*/ - - @Test(groups = "unit") - public void testEqualsIgnoreCase() { - Assert.assertTrue(ByteBufAsciiString.contentEqualsIgnoreCase(null, null)); - Assert.assertFalse(ByteBufAsciiString.contentEqualsIgnoreCase(null, "foo")); - Assert.assertFalse(ByteBufAsciiString.contentEqualsIgnoreCase("bar", null)); - Assert.assertTrue(ByteBufAsciiString.contentEqualsIgnoreCase("FoO", "fOo")); - - // Test variations (Ascii + String, Ascii + Ascii, String + Ascii) - ByteBufAsciiString stringFoO = new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "FoO"); - Assert.assertFalse(stringFoO.contentEqualsIgnoreCase(null)); - Assert.assertTrue( - ByteBufAsciiString - .contentEqualsIgnoreCase(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, stringFoO), "fOo")); - Assert.assertTrue( - ByteBufAsciiString - .contentEqualsIgnoreCase(stringFoO, new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "fOo"))); - Assert.assertTrue( - ByteBufAsciiString - .contentEqualsIgnoreCase("FoO", new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "fOo"))); - - // Test variations (Ascii + String, Ascii + Ascii, String + Ascii) - Assert.assertFalse(ByteBufAsciiString.contentEqualsIgnoreCase(stringFoO, "bAr")); - Assert.assertFalse( - ByteBufAsciiString - .contentEqualsIgnoreCase(stringFoO, new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "bAr"))); - Assert.assertFalse( - ByteBufAsciiString - .contentEqualsIgnoreCase("FoO", new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "bAr"))); - } - - @Test(groups = "unit") - public void testIndexOfIgnoreCase() { - Assert.assertEquals(ByteBufAsciiString.indexOfIgnoreCase(null, "abc", 1), -1); - Assert.assertEquals(ByteBufAsciiString.indexOfIgnoreCase("abc", null, 1), -1); - Assert.assertEquals(ByteBufAsciiString.indexOfIgnoreCase("", "", 0), 0); - Assert.assertEquals(ByteBufAsciiString.indexOfIgnoreCase("aabaabaa", "A", 0), 0); - Assert.assertEquals(ByteBufAsciiString.indexOfIgnoreCase("aabaabaa", "B", 0), 2); - Assert.assertEquals(ByteBufAsciiString.indexOfIgnoreCase("aabaabaa", "AB", 0), 1); - Assert.assertEquals(ByteBufAsciiString.indexOfIgnoreCase("aabaabaa", "B", 3), 5); - Assert.assertEquals(ByteBufAsciiString.indexOfIgnoreCase("aabaabaa", "B", 9), -1); - Assert.assertEquals(ByteBufAsciiString.indexOfIgnoreCase("aabaabaa", "B", -1), 2); - Assert.assertEquals(ByteBufAsciiString.indexOfIgnoreCase("aabaabaa", "", 2), 2); - Assert.assertEquals(ByteBufAsciiString.indexOfIgnoreCase("abc", "", 9), -1); - Assert.assertEquals(ByteBufAsciiString.indexOfIgnoreCase("ãabaabaa", "Ã", 0), 0); - - Assert.assertEquals( - ByteBufAsciiString.indexOfIgnoreCase(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abc"), null, 1), - -1); - Assert.assertEquals(ByteBufAsciiString.indexOfIgnoreCase(ByteBufAsciiString.EMPTY_STRING, "", 0), 0); - Assert.assertEquals( - ByteBufAsciiString - .indexOfIgnoreCase(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "aabaabaa"), "A", 0), - 0); - Assert.assertEquals( - ByteBufAsciiString - .indexOfIgnoreCase(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "aabaabaa"), "B", 0), - 2); - Assert.assertEquals( - ByteBufAsciiString - .indexOfIgnoreCase(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "aabaabaa"), "AB", 0), - 1); - Assert.assertEquals( - ByteBufAsciiString - .indexOfIgnoreCase(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "aabaabaa"), "B", 3), - 5); - Assert.assertEquals( - ByteBufAsciiString - .indexOfIgnoreCase(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "aabaabaa"), "B", 9), - -1); - Assert.assertEquals( - ByteBufAsciiString - .indexOfIgnoreCase(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "aabaabaa"), "B", -1), - 2); - Assert.assertEquals( - ByteBufAsciiString - .indexOfIgnoreCase(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "aabaabaa"), "", 2), - 2); - Assert.assertEquals( - ByteBufAsciiString.indexOfIgnoreCase(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abc"), "", 9), - -1); - Assert.assertEquals( - ByteBufAsciiString - .indexOfIgnoreCase(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "ãabaabaa"), "Ã", 0), - -1); - } - - @Test(groups = "unit") - public void testIndexOfIgnoreCaseAscii() { - Assert.assertEquals(ByteBufAsciiString.indexOfIgnoreCaseAscii(null, "abc", 1), -1); - Assert.assertEquals(ByteBufAsciiString.indexOfIgnoreCaseAscii("abc", null, 1), -1); - Assert.assertEquals(ByteBufAsciiString.indexOfIgnoreCaseAscii("", "", 0), 0); - Assert.assertEquals(ByteBufAsciiString.indexOfIgnoreCaseAscii("aabaabaa", "A", 0), 0); - Assert.assertEquals(ByteBufAsciiString.indexOfIgnoreCaseAscii("aabaabaa", "B", 0), 2); - Assert.assertEquals(ByteBufAsciiString.indexOfIgnoreCaseAscii("aabaabaa", "AB", 0), 1); - Assert.assertEquals(ByteBufAsciiString.indexOfIgnoreCaseAscii("aabaabaa", "B", 3), 5); - Assert.assertEquals(ByteBufAsciiString.indexOfIgnoreCaseAscii("aabaabaa", "B", 9), -1); - Assert.assertEquals(ByteBufAsciiString.indexOfIgnoreCaseAscii("aabaabaa", "B", -1), 2); - Assert.assertEquals(ByteBufAsciiString.indexOfIgnoreCaseAscii("aabaabaa", "", 2), 2); - Assert.assertEquals(ByteBufAsciiString.indexOfIgnoreCaseAscii("abc", "", 9), -1); - - Assert.assertEquals( - ByteBufAsciiString - .indexOfIgnoreCaseAscii(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abc"), null, 1), - -1); - Assert.assertEquals(ByteBufAsciiString.indexOfIgnoreCaseAscii(ByteBufAsciiString.EMPTY_STRING, "", 0), 0); - Assert.assertEquals( - ByteBufAsciiString - .indexOfIgnoreCaseAscii(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "aabaabaa"), "A", 0), - 0); - Assert.assertEquals( - ByteBufAsciiString - .indexOfIgnoreCaseAscii(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "aabaabaa"), "B", 0), - 2); - Assert.assertEquals( - ByteBufAsciiString - .indexOfIgnoreCaseAscii(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "aabaabaa"), "AB", 0), - 1); - Assert.assertEquals( - ByteBufAsciiString - .indexOfIgnoreCaseAscii(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "aabaabaa"), "B", 3), - 5); - Assert.assertEquals( - ByteBufAsciiString - .indexOfIgnoreCaseAscii(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "aabaabaa"), "B", 9), - -1); - Assert.assertEquals( - ByteBufAsciiString - .indexOfIgnoreCaseAscii(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "aabaabaa"), "B", -1), - 2); - Assert.assertEquals( - ByteBufAsciiString - .indexOfIgnoreCaseAscii(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "aabaabaa"), "", 2), - 2); - Assert.assertEquals( - ByteBufAsciiString - .indexOfIgnoreCaseAscii(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abc"), "", 9), - -1); - } - - @Test(groups = "unit") - public void testTrim() { - Assert.assertEquals(ByteBufAsciiString.EMPTY_STRING.trim().toString(), ""); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, " abc").trim().toString(), "abc"); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abc ").trim().toString(), "abc"); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, " abc ").trim().toString(), "abc"); - - Assert.assertEquals( - ByteBufAsciiString.trim(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, " abc")).toString(), - "abc"); - Assert.assertEquals( - ByteBufAsciiString.trim(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abc ")).toString(), - "abc"); - Assert.assertEquals( - ByteBufAsciiString.trim(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, " abc ")).toString(), - "abc"); - - Assert.assertEquals(ByteBufAsciiString.trim(AsciiString.of(" abc")).toString(), "abc"); - Assert.assertEquals(ByteBufAsciiString.trim(AsciiString.of("abc ")).toString(), "abc"); - Assert.assertEquals(ByteBufAsciiString.trim(AsciiString.of(" abc ")).toString(), "abc"); - } - - @Test(groups = "unit") - public void testIndexOfChar() { - Assert.assertEquals(ByteBufAsciiString.indexOf(null, 'a', 0), -1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "").indexOf('a', 0), -1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abc").indexOf('d', 0), -1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "aabaabaa").indexOf('A', 0), -1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "aabaabaa").indexOf('a', 0), 0); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "aabaabaa").indexOf('a', 1), 1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "aabaabaa").indexOf('a', 2), 3); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "aabdabaa").indexOf('d', 1), 3); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd", 1, 2).indexOf('c', 0), 1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd", 1, 2).indexOf('c', -1), 1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd", 1, 3).indexOf('d', 2), 2); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd", 1, 2).indexOf('b', 0), 0); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd", 0, 2).indexOf('c', 0), -1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd", 1, 3).indexOf('a', 0), -1); - Assert - .assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd", 1, 3).indexOf('\u1077', 0), -1); - } - - @Test(groups = "unit") - public void testIndexOfCharSequence() { - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd").indexOf("abcd", 0), 0); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd").indexOf("abc", 0), 0); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd").indexOf("bcd", 0), 1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd").indexOf("bc", 0), 1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcdabcd").indexOf("bcd", 0), 1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd", 1, 2).indexOf("bc", 0), 0); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd", 1, 3).indexOf("bcd", 0), 0); - Assert - .assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcdabcd", 4, 4).indexOf("bcd", 0), 1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "012345").indexOf("345", 3), 3); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "012345").indexOf("345", 0), 3); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "012345").indexOf("345", -1), 3); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "012345").indexOf("\u1077345", 0), -1); - - // Test with empty string - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd").indexOf("", 0), 0); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd").indexOf("", 1), 1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd", 1, 3).indexOf("", 4), 3); - - // Test not found - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd").indexOf("abcde", 0), -1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcdbc").indexOf("bce", 0), -1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd", 1, 3).indexOf("abc", 0), -1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd", 1, 2).indexOf("bd", 0), -1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "012345").indexOf("345", 4), -1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "012345").indexOf("abc", 3), -1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "012345").indexOf("abc", 0), -1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "012345").indexOf("abcdefghi", 0), -1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "012345").indexOf("abcdefghi", 4), -1); - } - - @Test(groups = "unit") - public void testStaticIndexOfChar() { - Assert.assertEquals(ByteBufAsciiString.indexOf(null, 'a', 0), -1); - Assert.assertEquals(ByteBufAsciiString.indexOf("", 'a', 0), -1); - Assert.assertEquals(ByteBufAsciiString.indexOf("abc", 'd', 0), -1); - Assert.assertEquals(ByteBufAsciiString.indexOf("aabaabaa", 'A', 0), -1); - Assert.assertEquals(ByteBufAsciiString.indexOf("aabaabaa", 'a', 0), 0); - Assert.assertEquals(ByteBufAsciiString.indexOf("aabaabaa", 'a', 1), 1); - Assert.assertEquals(ByteBufAsciiString.indexOf("aabaabaa", 'a', 2), 3); - Assert.assertEquals(ByteBufAsciiString.indexOf("aabdabaa", 'd', 1), 3); - Assert.assertEquals(ByteBufAsciiString.indexOf("aabdabaa", '\u203d', 1), -1); - - Assert.assertEquals(ByteBufAsciiString.indexOf(ByteBufAsciiString.EMPTY_STRING, 'a', 0), -1); - Assert.assertEquals( - ByteBufAsciiString.indexOf(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abc"), 'd', 0), - -1); - Assert.assertEquals( - ByteBufAsciiString.indexOf(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "aabaabaa"), 'A', 0), - -1); - Assert.assertEquals( - ByteBufAsciiString.indexOf(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "aabaabaa"), 'a', 0), - 0); - Assert.assertEquals( - ByteBufAsciiString.indexOf(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "aabaabaa"), 'a', 1), - 1); - Assert.assertEquals( - ByteBufAsciiString.indexOf(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "aabaabaa"), 'a', 2), - 3); - Assert.assertEquals( - ByteBufAsciiString.indexOf(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "aabdabaa"), 'd', 1), - 3); - - Assert.assertEquals(ByteBufAsciiString.indexOf(AsciiString.EMPTY_STRING, 'a', 0), -1); - Assert.assertEquals(ByteBufAsciiString.indexOf(AsciiString.of("abc"), 'd', 0), -1); - Assert.assertEquals(ByteBufAsciiString.indexOf(AsciiString.of("aabaabaa"), 'A', 0), -1); - Assert.assertEquals(ByteBufAsciiString.indexOf(AsciiString.of("aabaabaa"), 'a', 0), 0); - Assert.assertEquals(ByteBufAsciiString.indexOf(AsciiString.of("aabaabaa"), 'a', 1), 1); - Assert.assertEquals(ByteBufAsciiString.indexOf(AsciiString.of("aabaabaa"), 'a', 2), 3); - Assert.assertEquals(ByteBufAsciiString.indexOf(AsciiString.of("aabdabaa"), 'd', 1), 3); - } - - @Test(groups = "unit") - public void testLastIndexOfCharSequence() { - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd").lastIndexOf("abcd", 0), 0); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd").lastIndexOf("abc", 4), 0); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd").lastIndexOf("bcd", 4), 1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd").lastIndexOf("bc", 4), 1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcdabcd").lastIndexOf("bcd", 10), 5); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcdabcd").lastIndexOf("bcd"), 5); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd", 1, 2).lastIndexOf("bc", 0), 0); - Assert - .assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd", 1, 3).lastIndexOf("bcd", 0), 0); - Assert.assertEquals( - new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcdabcd", 4, 4).lastIndexOf("bcd", 4), - 1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "012345").lastIndexOf("345", 3), 3); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "012345").lastIndexOf("345", 6), 3); - Assert.assertEquals( - new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "012345").lastIndexOf("\u1077345", 0), - -1); - - // Test with empty string - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd").lastIndexOf("", 0), 0); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd").lastIndexOf("", 1), 1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd", 1, 3).lastIndexOf("", 4), 3); - - // Test not found - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd").lastIndexOf("abcde", 0), -1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcdbc").lastIndexOf("bce", 0), -1); - Assert - .assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd", 1, 3).lastIndexOf("abc", 0), -1); - Assert - .assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd", 1, 2).lastIndexOf("bd", 0), -1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "012345").lastIndexOf("345", 2), -1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "012345").lastIndexOf("abc", 3), -1); - Assert.assertEquals(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "012345").lastIndexOf("abc", 0), -1); - Assert.assertEquals( - new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "012345").lastIndexOf("abcdefghi", 0), - -1); - Assert.assertEquals( - new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "012345").lastIndexOf("abcdefghi", 4), - -1); - } - - @Test(groups = "unit") - public void testReplace() { - ByteBufAsciiString abcd = new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd"); - Assert.assertEquals(abcd.replace('b', 'd'), new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "adcd")); - Assert.assertEquals(abcd.replace('a', 'd'), new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "dbcd")); - Assert.assertEquals(abcd.replace('d', 'a'), new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abca")); - Assert.assertSame(abcd.replace('x', 'a'), abcd); - Assert.assertSame(abcd.replace('\u203d', 'a'), abcd); - Assert.assertEquals( - new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd", 1, 2).replace('b', 'c'), - new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "cc")); - Assert.assertEquals( - new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcd", 1, 2).replace('c', 'b'), - new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "bb")); - Assert.assertEquals( - new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcdc", 1, 4).replace('c', 'd'), - new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "bddd")); - Assert.assertEquals( - new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abcada", 0, 5).replace('a', 'x'), - new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "xbcxd")); - } - - @Test(groups = "unit") - public void testSubStringHashCode() { - // two "123"s - Assert.assertEquals(ByteBufAsciiString.hashCode("123"), ByteBufAsciiString.hashCode("a123".substring(1))); - } - - @Test(groups = "unit") - public void testIndexOf() { - ByteBufAsciiString foo = new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "This is a test"); - int i1 = foo.indexOf(' ', 0); - Assert.assertEquals(i1, 4); - int i2 = foo.indexOf(' ', i1 + 1); - Assert.assertEquals(i2, 7); - int i3 = foo.indexOf(' ', i2 + 1); - Assert.assertEquals(i3, 9); - Assert.assertTrue(i3 + 1 < foo.length()); - int i4 = foo.indexOf(' ', i3 + 1); - Assert.assertEquals(i4, -1); - } - - @Test(groups = "unit") - public void testSplit() { - Pattern p = Pattern.compile(":"); - ByteBufAsciiString[] strings; - - ByteBufAsciiString s = new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "boo:and:foo"); - - strings = s.split(p); - Assert.assertEquals(strings.length, 3); - Assert.assertEquals(strings[0].toString(), "boo"); - Assert.assertEquals(strings[1].toString(), "and"); - Assert.assertEquals(strings[2].toString(), "foo"); - - strings = s.split(p, 2); - Assert.assertEquals(strings.length, 2); - Assert.assertEquals(strings[0].toString(), "boo"); - Assert.assertEquals(strings[1].toString(), "and:foo"); - - strings = s.split(p, 5); - Assert.assertEquals(strings.length, 3); - Assert.assertEquals(strings[0].toString(), "boo"); - Assert.assertEquals(strings[1].toString(), "and"); - Assert.assertEquals(strings[2].toString(), "foo"); - - strings = s.split(p, -2); - Assert.assertEquals(strings.length, 3); - Assert.assertEquals(strings[0].toString(), "boo"); - Assert.assertEquals(strings[1].toString(), "and"); - Assert.assertEquals(strings[2].toString(), "foo"); - - strings = s.split("x", 0); - Assert.assertEquals(strings.length, 1); - Assert.assertEquals(strings[0], s); - - p = Pattern.compile("o"); - - strings = s.split(p); - Assert.assertEquals(strings.length, 3); - Assert.assertEquals(strings[0].toString(), "b"); - Assert.assertEquals(strings[1].toString(), ""); - Assert.assertEquals(strings[2].toString(), ":and:f"); - - strings = s.split(p, 5); - Assert.assertEquals(strings.length, 5); - Assert.assertEquals(strings[0].toString(), "b"); - Assert.assertEquals(strings[1].toString(), ""); - Assert.assertEquals(strings[2].toString(), ":and:f"); - Assert.assertEquals(strings[3].toString(), ""); - Assert.assertEquals(strings[4].toString(), ""); - - strings = s.split(p, -2); - Assert.assertEquals(strings.length, 5); - Assert.assertEquals(strings[0].toString(), "b"); - Assert.assertEquals(strings[1].toString(), ""); - Assert.assertEquals(strings[2].toString(), ":and:f"); - Assert.assertEquals(strings[3].toString(), ""); - Assert.assertEquals(strings[4].toString(), ""); - - strings = s.split("o", 0); - Assert.assertEquals(strings.length, 3); - Assert.assertEquals(strings[0].toString(), "b"); - Assert.assertEquals(strings[1].toString(), ""); - Assert.assertEquals(strings[2].toString(), ":and:f"); - - strings = s.split(':'); - Assert.assertEquals(strings.length, 3); - Assert.assertEquals(strings[0].toString(), "boo"); - Assert.assertEquals(strings[1].toString(), "and"); - Assert.assertEquals(strings[2].toString(), "foo"); - - strings = s.split('o'); - Assert.assertEquals(strings.length, 3); - Assert.assertEquals(strings[0].toString(), "b"); - Assert.assertEquals(strings[1].toString(), ""); - Assert.assertEquals(strings[2].toString(), ":and:f"); - - strings = s.split('x'); - Assert.assertEquals(strings.length, 1); - Assert.assertEquals(strings[0], s); - } - - @Test(groups = "unit") - public void testEndsWith() { - Assert.assertTrue(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "hello world").endsWith("world")); - Assert.assertFalse(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "hello world!").endsWith("world")); - Assert.assertTrue(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "hello world").endsWith("")); - Assert.assertFalse(ByteBufAsciiString.EMPTY_STRING.endsWith("!")); - - Assert.assertTrue(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "hello world").matches(".*world")); - Assert.assertThrows( - NullPointerException.class, - () -> new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "hello world") - .regionMatches(true, 0, null, 0, 1)); - Assert.assertThrows( - NullPointerException.class, - () -> new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "hello world") - .regionMatches(false, 0, null, 0, 1)); - Assert.assertFalse( - new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "hello world").regionMatches(true, -1, "", 0, 1)); - Assert.assertFalse( - new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "hello world").regionMatches(true, 7, "world", 0, 5)); - Assert.assertFalse( - new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "hello world").regionMatches(true, 0, "", -1, 1)); - Assert.assertFalse( - new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "hello world").regionMatches(true, 0, "world", 6, 5)); - Assert.assertTrue( - new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "hello world").regionMatches(true, 6, "WORLD", 0, 5)); - Assert.assertTrue( - new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "hello world").regionMatches(false, 6, "world", 0, 5)); - - Assert.assertFalse( - ByteBufAsciiString.regionMatches( - new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "hello world"), - true, - -1, - null, - 0, - 1)); - Assert.assertFalse( - ByteBufAsciiString.regionMatchesAscii( - new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "hello world"), - true, - -1, - null, - 0, - 1)); - } - - @Test(groups = "unit") - public void testStartsWith() { - Assert.assertTrue(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "hello world").startsWith("hello")); - Assert.assertFalse(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "hello world").startsWith("hello", -1)); - Assert.assertFalse(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "hello world!").startsWith("Hello")); - Assert.assertTrue(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "hello world").startsWith("lo", 3)); - Assert.assertTrue(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "hello world").startsWith("")); - Assert.assertFalse(ByteBufAsciiString.EMPTY_STRING.startsWith("!")); - - Assert.assertFalse( - ByteBufAsciiString - .startsWith(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "hello world!"), "Hello")); - Assert.assertTrue( - ByteBufAsciiString - .startsWithIgnoreCase(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "hello world!"), "Hello")); - Assert.assertFalse( - ByteBufAsciiString - .startsWith(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "hello world!"), "LO", 3)); - Assert.assertTrue( - ByteBufAsciiString - .startsWithIgnoreCase(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "hello world!"), "LO", 3)); - Assert.assertTrue(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "hello world").matches("hello.*")); - - } - - @Test(groups = "unit") - public void testConcat() { - - ByteBufAsciiString abc = new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "abc"); - ByteBufAsciiString def = new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "def"); - - Assert.assertEquals(abc.concat(def).toString(), "abcdef"); - Assert.assertEquals(abc.concat("def").toString(), "abcdef"); - Assert.assertEquals(abc.concat("d", AsciiString.of("ef")).toString(), "abcdef"); - Assert.assertEquals(abc.toString(), "abc"); - Assert.assertSame(abc.concat(ByteBufAsciiString.EMPTY_STRING), abc); - Assert.assertSame(abc.concat(""), abc); - Assert.assertSame(abc.concat(), abc); - Assert.assertSame(ByteBufAsciiString.EMPTY_STRING.concat(def), def); - Assert.assertEquals(ByteBufAsciiString.EMPTY_STRING.concat("def"), def); - Assert.assertSame(ByteBufAsciiString.EMPTY_STRING.concat(""), ByteBufAsciiString.EMPTY_STRING); - } - - @Test(groups = "unit") - public void testToAsciiString() { - Assert.assertSame( - new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "").toAsciiString(), - AsciiString.EMPTY_STRING); - Assert.assertEquals( - new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "Hello World").toAsciiString(), - AsciiString.of("Hello World")); - Assert.assertEquals( - new ByteBufAsciiString("Hello World".getBytes(), 0, 11, false).toAsciiString(), - AsciiString.of("Hello World")); - - Assert.assertSame( - new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "").toString(0, 0), - AsciiString.EMPTY_STRING.toString()); - Assert.assertThrows( - IndexOutOfBoundsException.class, - () -> new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "").toString(1, 0)); - } - - @Test(groups = "unit") - public void testCompareTo() { - ByteBufAsciiString str = new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "Hello World"); - Assert.assertEquals(str.compareTo(str), 0); - Assert.assertEquals(str.compareTo(str.toAsciiString()), 0); - ByteBufAsciiString str2 = new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "Hello World!"); - Assert.assertEquals(str.compareTo(str2), -1); - Assert.assertEquals(str2.compareTo(str), +1); - ByteBufAsciiString str3 = new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "Hello Worldz"); - Assert.assertEquals(str2.compareTo(str3), '!' - 'z'); - Assert.assertEquals(str3.compareTo(str2), 'z' - '!'); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/TestByteBufAsciiStringMemory.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/TestByteBufAsciiStringMemory.java deleted file mode 100644 index 9e3d7b8fefe..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/TestByteBufAsciiStringMemory.java +++ /dev/null @@ -1,168 +0,0 @@ -package com.linkedin.alpini.base; - -import com.linkedin.alpini.base.misc.ByteBufAsciiString; -import io.netty.util.ByteProcessor; -import java.util.Random; -import java.util.concurrent.atomic.AtomicReference; -import org.testng.Assert; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - - -public class TestByteBufAsciiStringMemory { - private byte[] a; - private byte[] b; - private int aOffset = 22; - private int bOffset = 53; - private int length = 100; - private ByteBufAsciiString aAsciiString; - private ByteBufAsciiString bAsciiString; - private Random r = new Random(); - - @BeforeMethod(groups = "unit") - public void setUp() { - a = new byte[128]; - b = new byte[256]; - r.nextBytes(a); - r.nextBytes(b); - aOffset = 22; - bOffset = 53; - length = 100; - System.arraycopy(a, aOffset, b, bOffset, length); - aAsciiString = new ByteBufAsciiString(a, aOffset, length, false); - bAsciiString = new ByteBufAsciiString(b, bOffset, length, false); - } - - @Test(groups = "unit") - public void testSharedMemory() { - ++a[aOffset]; - ByteBufAsciiString aAsciiString1 = new ByteBufAsciiString(a, aOffset, length, true); - ByteBufAsciiString aAsciiString2 = new ByteBufAsciiString(a, aOffset, length, false); - Assert.assertEquals(aAsciiString1, aAsciiString); - Assert.assertEquals(aAsciiString2, aAsciiString); - for (int i = aOffset; i < length; ++i) { - Assert.assertEquals(a[i], aAsciiString.byteAt(i - aOffset)); - } - } - - @Test(groups = "unit") - public void testNotSharedMemory() { - ByteBufAsciiString aAsciiString1 = new ByteBufAsciiString(a, aOffset, length, true); - ++a[aOffset]; - Assert.assertNotEquals(aAsciiString1, aAsciiString); - int i = aOffset; - Assert.assertNotEquals(aAsciiString1.byteAt(i - aOffset), a[i]); - ++i; - for (; i < length; ++i) { - Assert.assertEquals(aAsciiString1.byteAt(i - aOffset), a[i]); - } - } - - @Test(groups = "unit") - public void forEachTest() { - final AtomicReference aCount = new AtomicReference(0); - final AtomicReference bCount = new AtomicReference(0); - aAsciiString.forEachByte(new ByteProcessor() { - int i; - - @Override - public boolean process(byte value) { - Assert.assertEquals(bAsciiString.byteAt(i++), value, "failed at index: " + i); - aCount.set(aCount.get() + 1); - return true; - } - }); - bAsciiString.forEachByte(new ByteProcessor() { - int i; - - @Override - public boolean process(byte value) { - Assert.assertEquals(aAsciiString.byteAt(i++), value, "failed at index: " + i); - bCount.set(bCount.get() + 1); - return true; - } - }); - Assert.assertEquals(aCount.get().intValue(), aAsciiString.length()); - Assert.assertEquals(bCount.get().intValue(), bAsciiString.length()); - } - - @Test(groups = "unit") - public void forEachWithIndexEndTest() { - Assert.assertNotEquals( - aAsciiString.forEachByte( - aAsciiString.length() - 1, - 1, - new ByteProcessor.IndexOfProcessor(aAsciiString.byteAt(aAsciiString.length() - 1))), - -1); - } - - @Test(groups = "unit") - public void forEachWithIndexBeginTest() { - Assert.assertNotEquals( - aAsciiString.forEachByte(0, 1, new ByteProcessor.IndexOfProcessor(aAsciiString.byteAt(0))), - -1); - } - - @Test(groups = "unit") - public void forEachDescTest() { - final AtomicReference aCount = new AtomicReference(0); - final AtomicReference bCount = new AtomicReference(0); - aAsciiString.forEachByteDesc(new ByteProcessor() { - int i = 1; - - @Override - public boolean process(byte value) throws Exception { - Assert.assertEquals(bAsciiString.byteAt(bAsciiString.length() - (i++)), value, "failed at index: " + i); - aCount.set(aCount.get() + 1); - return true; - } - }); - bAsciiString.forEachByteDesc(new ByteProcessor() { - int i = 1; - - @Override - public boolean process(byte value) throws Exception { - Assert.assertEquals(aAsciiString.byteAt(aAsciiString.length() - (i++)), value, "failed at index: " + i); - bCount.set(bCount.get() + 1); - return true; - } - }); - Assert.assertEquals(aCount.get().intValue(), aAsciiString.length()); - Assert.assertEquals(bCount.get().intValue(), bAsciiString.length()); - } - - @Test(groups = "unit") - public void forEachDescWithIndexEndTest() { - Assert.assertNotEquals( - bAsciiString.forEachByteDesc( - bAsciiString.length() - 1, - 1, - new ByteProcessor.IndexOfProcessor(bAsciiString.byteAt(bAsciiString.length() - 1))), - -1); - } - - @Test(groups = "unit") - public void forEachDescWithIndexBeginTest() { - Assert.assertNotEquals( - bAsciiString.forEachByteDesc(0, 1, new ByteProcessor.IndexOfProcessor(bAsciiString.byteAt(0))), - -1); - } - - @Test(groups = "unit") - public void subSequenceTest() { - final int start = 12; - final int end = aAsciiString.length(); - ByteBufAsciiString aSubSequence = aAsciiString.subSequence(start, end, false); - ByteBufAsciiString bSubSequence = bAsciiString.subSequence(start, end, true); - Assert.assertEquals(aSubSequence, bSubSequence); - Assert.assertEquals(aSubSequence.hashCode(), bSubSequence.hashCode()); - } - - /*@Test(groups = "unit") - public void copyTest() { - byte[] aCopy = new byte[aAsciiString.length()]; - aAsciiString.copy(0, aCopy, 0, aCopy.length); - AsciiString aAsciiStringCopy = new AsciiString(aCopy, false); - assertEquals(aAsciiString, aAsciiStringCopy); - }*/ -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/TestHeaderStringCache.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/TestHeaderStringCache.java deleted file mode 100644 index 72b40697db8..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/TestHeaderStringCache.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.linkedin.alpini.base; - -import com.linkedin.alpini.base.misc.ByteBufAsciiString; -import com.linkedin.alpini.base.misc.HeaderStringCache; -import com.linkedin.alpini.base.misc.Time; -import io.netty.buffer.UnpooledByteBufAllocator; -import io.netty.util.AsciiString; -import java.util.concurrent.TimeUnit; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - - -public class TestHeaderStringCache { - @BeforeClass(groups = "unit") - public void freezeTime() { - Time.freeze(); - } - - @AfterClass(groups = "unit", alwaysRun = true) - public void restoreTime() { - Time.restore(); - ; - } - - @Test(groups = "unit") - public void testHeaders() { - HeaderStringCache.Cache cache = HeaderStringCache.getAndExpireOld(); - - CharSequence s1 = cache.lookupName("Hello World"); - Assert.assertTrue(s1 instanceof String); - - CharSequence s2 = cache.lookupName(AsciiString.of("hello world")); - Assert.assertTrue(s2 instanceof String); - - Assert.assertSame(s1, s2); - - Time.advance(1, TimeUnit.SECONDS); - cache = HeaderStringCache.getAndExpireOld(); - - CharSequence s3 = cache.lookupName(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "hello world")); - Assert.assertTrue(s3 instanceof String); - - Assert.assertSame(s3, s2); - - Time.advance(1, TimeUnit.SECONDS); - HeaderStringCache.getAndExpireOld(); - - Time.advance(1, TimeUnit.SECONDS); // after two seconds, the cache should forget - cache = HeaderStringCache.getAndExpireOld(); - - CharSequence s4 = cache.lookupName("hello world"); - Assert.assertTrue(s4 instanceof String); - Assert.assertNotSame(s4, s3); - } - - @Test(groups = "unit") - public void testValues() { - HeaderStringCache.Cache cache = HeaderStringCache.getAndExpireOld(); - - CharSequence s1 = cache.lookupValue("Hello World"); - CharSequence t1 = cache.lookupValue("hello world"); - Assert.assertTrue(s1 instanceof AsciiString); - Assert.assertTrue(t1 instanceof AsciiString); - Assert.assertNotSame(s1, t1); - - CharSequence t2 = cache.lookupValue(AsciiString.of("hello world")); - Assert.assertTrue(t2 instanceof AsciiString); - - Assert.assertSame(t1, t2); - - Time.advance(1, TimeUnit.SECONDS); - cache = HeaderStringCache.getAndExpireOld(); - - CharSequence t3 = cache.lookupValue(new ByteBufAsciiString(UnpooledByteBufAllocator.DEFAULT, "hello world")); - Assert.assertTrue(t3 instanceof AsciiString); - - Assert.assertSame(t3, t2); - - Time.advance(1, TimeUnit.SECONDS); - HeaderStringCache.getAndExpireOld(); - - Time.advance(1, TimeUnit.SECONDS); // after two seconds, the cache should forget - cache = HeaderStringCache.getAndExpireOld(); - - CharSequence t4 = cache.lookupValue("hello world"); - Assert.assertTrue(t4 instanceof AsciiString); - Assert.assertNotSame(t4, t3); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/misc/TestNetty4ThrowException.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/misc/TestNetty4ThrowException.java deleted file mode 100644 index 3c9f4c6ecb7..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/misc/TestNetty4ThrowException.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.linkedin.alpini.base.misc; - -import java.io.IOException; -import org.testng.annotations.Test; - - -public class TestNetty4ThrowException { - @Test(groups = "unit", expectedExceptions = IOException.class, expectedExceptionsMessageRegExp = "Test Successful") - public void simpleTest() { - ExceptionUtil.throwException(new IOException("Test Successful")); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/misc/TestPromiseDelegate.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/misc/TestPromiseDelegate.java deleted file mode 100644 index c82780839c7..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/misc/TestPromiseDelegate.java +++ /dev/null @@ -1,274 +0,0 @@ -package com.linkedin.alpini.base.misc; - -import io.netty.util.concurrent.DefaultPromise; -import io.netty.util.concurrent.FutureListener; -import io.netty.util.concurrent.ImmediateEventExecutor; -import io.netty.util.concurrent.Promise; -import java.util.concurrent.TimeUnit; -import org.mockito.Mockito; -import org.testng.Assert; -import org.testng.annotations.Test; - - -@SuppressWarnings("unchecked") -@Test(groups = "unit") -public class TestPromiseDelegate { - public interface ObjectPromise extends Promise { - } - - public interface ObjectFutureListener extends FutureListener { - } - - public void testSetSuccess() { - Promise promise = Mockito.spy(new DefaultPromise<>(ImmediateEventExecutor.INSTANCE)); - Promise delegate = new PromiseDelegate<>(promise); - - Assert.assertSame(delegate.setSuccess(1), delegate); - Assert.assertThrows(IllegalStateException.class, () -> delegate.setSuccess(2)); - - Mockito.verify(promise).trySuccess(1); - Mockito.verify(promise).trySuccess(2); - Mockito.verifyNoMoreInteractions(promise); - Assert.assertEquals(delegate.getNow(), 1); - } - - public void testTrySuccess() { - - Promise promise = Mockito.spy(new DefaultPromise<>(ImmediateEventExecutor.INSTANCE)); - Promise delegate = new PromiseDelegate<>(promise); - Assert.assertTrue(delegate.trySuccess(1)); - Assert.assertFalse(delegate.trySuccess(2)); - - Mockito.verify(promise).trySuccess(1); - Mockito.verify(promise).trySuccess(2); - Mockito.verifyNoMoreInteractions(promise); - Assert.assertEquals(delegate.getNow(), 1); - } - - public void testSetFailure() { - class TestException extends Exception { - } - - Promise promise = Mockito.spy(new DefaultPromise<>(ImmediateEventExecutor.INSTANCE)); - Promise delegate = new PromiseDelegate<>(promise); - Assert.assertSame(delegate.setFailure(new TestException()), delegate); - Assert.assertThrows(IllegalStateException.class, () -> delegate.setFailure(new NullPointerException())); - - Mockito.verify(promise).tryFailure(Mockito.any(TestException.class)); - Mockito.verify(promise).tryFailure(Mockito.any(NullPointerException.class)); - Mockito.verifyNoMoreInteractions(promise); - Assert.assertTrue(delegate.cause() instanceof TestException); - } - - public void testTryFailure() { - class TestException extends Exception { - } - - Promise promise = Mockito.spy(new DefaultPromise<>(ImmediateEventExecutor.INSTANCE)); - Promise delegate = new PromiseDelegate<>(promise); - Assert.assertTrue(delegate.tryFailure(new TestException())); - Assert.assertFalse(delegate.tryFailure(new NullPointerException())); - - Mockito.verify(promise).tryFailure(Mockito.any(TestException.class)); - Mockito.verify(promise).tryFailure(Mockito.any(NullPointerException.class)); - Mockito.verifyNoMoreInteractions(promise); - Assert.assertTrue(delegate.cause() instanceof TestException); - } - - public void testSetUncancellable() { - Promise promise = Mockito.spy(new DefaultPromise<>(ImmediateEventExecutor.INSTANCE)); - Promise delegate = new PromiseDelegate<>(promise); - Assert.assertTrue(delegate.setUncancellable()); - Mockito.verify(promise).setUncancellable(); - Mockito.verifyNoMoreInteractions(promise); - } - - public void testIsSuccess() { - Promise promise = Mockito.spy(new DefaultPromise<>(ImmediateEventExecutor.INSTANCE)); - Promise delegate = new PromiseDelegate<>(promise); - Assert.assertFalse(delegate.isSuccess()); - Mockito.verify(promise).isSuccess(); - Mockito.verifyNoMoreInteractions(promise); - } - - public void testIsCancellable() { - Promise promise = Mockito.spy(new DefaultPromise<>(ImmediateEventExecutor.INSTANCE)); - Promise delegate = new PromiseDelegate<>(promise); - Assert.assertTrue(delegate.isCancellable()); - Mockito.verify(promise).isCancellable(); - Mockito.verifyNoMoreInteractions(promise); - } - - public void testAddListener() { - Promise promise = Mockito.mock(ObjectPromise.class); - Mockito.when(promise.addListener(Mockito.any())).thenReturn(promise); - Promise delegate = new PromiseDelegate<>(promise); - FutureListener listener = Mockito.mock(ObjectFutureListener.class); - Assert.assertSame(delegate.addListener(listener), delegate); - Mockito.verify(promise).addListener(listener); - Mockito.verifyNoMoreInteractions(promise, listener); - } - - public void testAddListeners() { - Promise promise = Mockito.mock(ObjectPromise.class); - Mockito.when(promise.addListeners(Mockito.any())).thenReturn(promise); - Promise delegate = new PromiseDelegate<>(promise); - FutureListener listener1 = Mockito.mock(ObjectFutureListener.class); - FutureListener listener2 = Mockito.mock(ObjectFutureListener.class); - Assert.assertSame(delegate.addListeners(listener1, listener2), delegate); - Mockito.verify(promise).addListeners(listener1, listener2); - Mockito.verifyNoMoreInteractions(promise, listener1, listener2); - } - - public void testRemoveListener() { - Promise promise = Mockito.mock(ObjectPromise.class); - Mockito.when(promise.addListener(Mockito.any())).thenReturn(promise); - Promise delegate = new PromiseDelegate<>(promise); - FutureListener listener = Mockito.mock(ObjectFutureListener.class); - Assert.assertSame(delegate.removeListener(listener), delegate); - Mockito.verify(promise).removeListener(listener); - Mockito.verifyNoMoreInteractions(promise, listener); - } - - public void testRemoveListeners() { - Promise promise = Mockito.mock(ObjectPromise.class); - Mockito.when(promise.addListeners(Mockito.any())).thenReturn(promise); - Promise delegate = new PromiseDelegate<>(promise); - FutureListener listener1 = Mockito.mock(ObjectFutureListener.class); - FutureListener listener2 = Mockito.mock(ObjectFutureListener.class); - Assert.assertSame(delegate.removeListeners(listener1, listener2), delegate); - Mockito.verify(promise).removeListeners(listener1, listener2); - Mockito.verifyNoMoreInteractions(promise, listener1, listener2); - } - - public void testAwait() throws InterruptedException { - Promise promise = Mockito.mock(ObjectPromise.class); - Mockito.when(promise.await()).thenReturn(promise); - Promise delegate = new PromiseDelegate<>(promise); - Assert.assertSame(delegate.await(), delegate); - Mockito.verify(promise).await(); - Mockito.verifyNoMoreInteractions(promise); - } - - public void testAwaitUninterruptibly() { - Promise promise = Mockito.mock(ObjectPromise.class); - Mockito.when(promise.awaitUninterruptibly()).thenReturn(promise); - Promise delegate = new PromiseDelegate<>(promise); - Assert.assertSame(delegate.awaitUninterruptibly(), delegate); - Mockito.verify(promise).awaitUninterruptibly(); - Mockito.verifyNoMoreInteractions(promise); - } - - public void testAwaitTimeUnit() throws InterruptedException { - Promise promise = Mockito.mock(ObjectPromise.class); - Mockito.when(promise.await(Mockito.anyLong(), Mockito.any(TimeUnit.class))).thenReturn(true); - Promise delegate = new PromiseDelegate<>(promise); - Assert.assertTrue(delegate.await(42, TimeUnit.NANOSECONDS)); - Mockito.verify(promise).await(42, TimeUnit.NANOSECONDS); - Mockito.verifyNoMoreInteractions(promise); - } - - public void testAwaitMillis() throws InterruptedException { - Promise promise = Mockito.mock(ObjectPromise.class); - Mockito.when(promise.await(Mockito.anyLong())).thenReturn(true); - Promise delegate = new PromiseDelegate<>(promise); - Assert.assertTrue(delegate.await(4242L)); - Mockito.verify(promise).await(4242L); - Mockito.verifyNoMoreInteractions(promise); - } - - public void testAwaitUninterruptiblyTimeUnit() { - Promise promise = Mockito.mock(ObjectPromise.class); - Mockito.when(promise.awaitUninterruptibly(Mockito.anyLong(), Mockito.any(TimeUnit.class))).thenReturn(true); - Promise delegate = new PromiseDelegate<>(promise); - Assert.assertTrue(delegate.awaitUninterruptibly(42, TimeUnit.NANOSECONDS)); - Mockito.verify(promise).awaitUninterruptibly(42, TimeUnit.NANOSECONDS); - Mockito.verifyNoMoreInteractions(promise); - } - - public void testAwaitUninterruptiblyMillis() { - Promise promise = Mockito.mock(ObjectPromise.class); - Mockito.when(promise.awaitUninterruptibly(Mockito.anyLong())).thenReturn(true); - Promise delegate = new PromiseDelegate<>(promise); - Assert.assertTrue(delegate.awaitUninterruptibly(4242L)); - Mockito.verify(promise).awaitUninterruptibly(4242L); - Mockito.verifyNoMoreInteractions(promise); - } - - public void testGetNow() { - Object value = Math.PI; - Promise promise = Mockito.mock(ObjectPromise.class); - Mockito.when(promise.getNow()).thenReturn(value); - Promise delegate = new PromiseDelegate<>(promise); - Assert.assertSame(delegate.getNow(), value); - Mockito.verify(promise).getNow(); - Mockito.verifyNoMoreInteractions(promise); - } - - public void testCancel() { - Promise promise = Mockito.spy(new DefaultPromise<>(ImmediateEventExecutor.INSTANCE)); - Promise delegate = new PromiseDelegate<>(promise); - Assert.assertTrue(delegate.cancel(false)); - Assert.assertFalse(delegate.cancel(false)); - Mockito.verify(promise, Mockito.times(2)).cancel(false); - Mockito.verifyNoMoreInteractions(promise); - } - - public void testIsCancelled() { - Promise promise = Mockito.spy(new DefaultPromise<>(ImmediateEventExecutor.INSTANCE)); - Promise delegate = new PromiseDelegate<>(promise); - Assert.assertFalse(delegate.isCancelled()); - Assert.assertTrue(promise.cancel(false)); - Assert.assertTrue(delegate.isCancelled()); - Mockito.verify(promise, Mockito.times(2)).isCancelled(); - Mockito.verify(promise).cancel(false); - Mockito.verifyNoMoreInteractions(promise); - } - - public void testIsDone() { - Promise promise = Mockito.spy(new DefaultPromise<>(ImmediateEventExecutor.INSTANCE)); - Promise delegate = new PromiseDelegate<>(promise); - Assert.assertFalse(delegate.isDone()); - Assert.assertTrue(promise.cancel(false)); - Assert.assertTrue(delegate.isDone()); - Mockito.verify(promise, Mockito.times(2)).isDone(); - Mockito.verify(promise).cancel(false); - Mockito.verifyNoMoreInteractions(promise); - } - - public void testGet() throws Exception { - Promise promise = Mockito.mock(ObjectPromise.class); - Mockito.when(promise.get()).thenReturn(42); - Promise delegate = new PromiseDelegate<>(promise); - Assert.assertSame(delegate.get(), 42); - Mockito.verify(promise).get(); - Mockito.verifyNoMoreInteractions(promise); - } - - public void testGetTimeUnit() throws Exception { - Promise promise = Mockito.mock(ObjectPromise.class); - Mockito.when(promise.get(Mockito.anyLong(), Mockito.any(TimeUnit.class))).thenReturn(42); - Promise delegate = new PromiseDelegate<>(promise); - Assert.assertSame(delegate.get(1234, TimeUnit.NANOSECONDS), 42); - Mockito.verify(promise).get(1234, TimeUnit.NANOSECONDS); - Mockito.verifyNoMoreInteractions(promise); - } - - public void testSync() throws InterruptedException { - Promise promise = Mockito.mock(ObjectPromise.class); - Mockito.when(promise.sync()).thenReturn(promise); - Promise delegate = new PromiseDelegate<>(promise); - Assert.assertSame(delegate.sync(), delegate); - Mockito.verify(promise).sync(); - Mockito.verifyNoMoreInteractions(promise); - } - - public void testSyncUninterruptibly() { - Promise promise = Mockito.mock(ObjectPromise.class); - Mockito.when(promise.syncUninterruptibly()).thenReturn(promise); - Promise delegate = new PromiseDelegate<>(promise); - Assert.assertSame(delegate.syncUninterruptibly(), delegate); - Mockito.verify(promise).syncUninterruptibly(); - Mockito.verifyNoMoreInteractions(promise); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/safealloc/AbstractByteBufTest.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/safealloc/AbstractByteBufTest.java deleted file mode 100644 index 64fb319920f..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/safealloc/AbstractByteBufTest.java +++ /dev/null @@ -1,4869 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project 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 com.linkedin.alpini.base.safealloc; - -import static io.netty.buffer.Unpooled.LITTLE_ENDIAN; -import static io.netty.buffer.Unpooled.buffer; -import static io.netty.buffer.Unpooled.copiedBuffer; -import static io.netty.buffer.Unpooled.directBuffer; -import static io.netty.buffer.Unpooled.unreleasableBuffer; -import static io.netty.buffer.Unpooled.wrappedBuffer; -import static org.testng.AssertJUnit.assertEquals; -import static org.testng.AssertJUnit.assertFalse; -import static org.testng.AssertJUnit.assertNull; -import static org.testng.AssertJUnit.assertSame; -import static org.testng.AssertJUnit.assertTrue; -import static org.testng.AssertJUnit.fail; - -import com.linkedin.alpini.base.misc.Time; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufUtil; -import io.netty.util.ByteProcessor; -import io.netty.util.CharsetUtil; -import io.netty.util.IllegalReferenceCountException; -import io.netty.util.internal.EmptyArrays; -import io.netty.util.internal.PlatformDependent; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.ReadOnlyBufferException; -import java.nio.channels.Channels; -import java.nio.channels.FileChannel; -import java.nio.channels.GatheringByteChannel; -import java.nio.channels.ScatteringByteChannel; -import java.nio.channels.WritableByteChannel; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Random; -import java.util.Set; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.CyclicBarrier; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; -import org.testng.SkipException; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - - -public abstract class AbstractByteBufTest { - private static final int CAPACITY = 4096; // Must be even - private static final int BLOCK_SIZE = 128; - private static final int JAVA_BYTEBUFFER_CONSISTENCY_ITERATIONS = 100; - - private long seed; - private Random random; - private ByteBuf buffer; - - protected final ByteBuf newBuffer(int capacity) { - return newBuffer(capacity, Integer.MAX_VALUE); - } - - protected abstract ByteBuf newBuffer(int capacity, int maxCapacity); - - protected boolean discardReadBytesDoesNotMoveWritableBytes() { - return true; - } - - @BeforeMethod(groups = "unit") - public void init() { - buffer = newBuffer(CAPACITY); - seed = Time.currentTimeMillis(); - random = new Random(seed); - } - - @AfterMethod(groups = "unit", alwaysRun = true) - public void dispose() throws InterruptedException { - if (buffer != null) { - assertTrue(buffer.release()); - assertEquals(buffer.refCnt(), 0); - - try { - buffer.release(); - } catch (Exception e) { - // Ignore. - } - buffer = null; - } - System.gc(); - Time.sleep(20); - } - - public static void assumeTrue(boolean test) { - if (!test) { - throw new SkipException("assumeTrue"); - } - } - - @Test(groups = "unit") - public void comparableInterfaceNotViolated() { - assumeTrue(buffer.isReadOnly()); - buffer.writerIndex(buffer.readerIndex()); - assumeTrue(buffer.writableBytes() >= 4); - - buffer.writeLong(0); - ByteBuf buffer2 = newBuffer(CAPACITY); - assumeTrue(buffer2.isReadOnly()); - buffer2.writerIndex(buffer2.readerIndex()); - // Write an unsigned integer that will cause buffer.getUnsignedInt() - buffer2.getUnsignedInt() to underflow the - // int type and wrap around on the negative side. - buffer2.writeLong(0xF0000000L); - assertTrue(buffer.compareTo(buffer2) < 0); - assertTrue(buffer2.compareTo(buffer) > 0); - buffer2.release(); - } - - @Test(groups = "unit") - public void initialState() { - assertEquals(CAPACITY, buffer.capacity()); - assertEquals(0, buffer.readerIndex()); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void readerIndexBoundaryCheck1() { - try { - buffer.writerIndex(0); - } catch (IndexOutOfBoundsException e) { - fail(); - } - buffer.readerIndex(-1); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void readerIndexBoundaryCheck2() { - try { - buffer.writerIndex(buffer.capacity()); - } catch (IndexOutOfBoundsException e) { - fail(); - } - buffer.readerIndex(buffer.capacity() + 1); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void readerIndexBoundaryCheck3() { - try { - buffer.writerIndex(CAPACITY / 2); - } catch (IndexOutOfBoundsException e) { - fail(); - } - buffer.readerIndex(CAPACITY * 3 / 2); - } - - @Test(groups = "unit") - public void readerIndexBoundaryCheck4() { - buffer.writerIndex(0); - buffer.readerIndex(0); - buffer.writerIndex(buffer.capacity()); - buffer.readerIndex(buffer.capacity()); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void writerIndexBoundaryCheck1() { - buffer.writerIndex(-1); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void writerIndexBoundaryCheck2() { - try { - buffer.writerIndex(CAPACITY); - buffer.readerIndex(CAPACITY); - } catch (IndexOutOfBoundsException e) { - fail(); - } - buffer.writerIndex(buffer.capacity() + 1); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void writerIndexBoundaryCheck3() { - try { - buffer.writerIndex(CAPACITY); - buffer.readerIndex(CAPACITY / 2); - } catch (IndexOutOfBoundsException e) { - fail(); - } - buffer.writerIndex(CAPACITY / 4); - } - - @Test(groups = "unit") - public void writerIndexBoundaryCheck4() { - buffer.writerIndex(0); - buffer.readerIndex(0); - buffer.writerIndex(CAPACITY); - - buffer.writeBytes(ByteBuffer.wrap(EmptyArrays.EMPTY_BYTES)); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void getBooleanBoundaryCheck1() { - buffer.getBoolean(-1); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void getBooleanBoundaryCheck2() { - buffer.getBoolean(buffer.capacity()); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void getByteBoundaryCheck1() { - buffer.getByte(-1); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void getByteBoundaryCheck2() { - buffer.getByte(buffer.capacity()); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void getShortBoundaryCheck1() { - buffer.getShort(-1); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void getShortBoundaryCheck2() { - buffer.getShort(buffer.capacity() - 1); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void getMediumBoundaryCheck1() { - buffer.getMedium(-1); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void getMediumBoundaryCheck2() { - buffer.getMedium(buffer.capacity() - 2); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void getIntBoundaryCheck1() { - buffer.getInt(-1); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void getIntBoundaryCheck2() { - buffer.getInt(buffer.capacity() - 3); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void getLongBoundaryCheck1() { - buffer.getLong(-1); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void getLongBoundaryCheck2() { - buffer.getLong(buffer.capacity() - 7); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void getByteArrayBoundaryCheck1() { - buffer.getBytes(-1, EmptyArrays.EMPTY_BYTES); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void getByteArrayBoundaryCheck2() { - buffer.getBytes(-1, EmptyArrays.EMPTY_BYTES, 0, 0); - } - - @Test(groups = "unit") - public void getByteArrayBoundaryCheck3() { - byte[] dst = new byte[4]; - buffer.setInt(0, 0x01020304); - try { - buffer.getBytes(0, dst, -1, 4); - fail(); - } catch (IndexOutOfBoundsException e) { - // Success - } - - // No partial copy is expected. - assertEquals(0, dst[0]); - assertEquals(0, dst[1]); - assertEquals(0, dst[2]); - assertEquals(0, dst[3]); - } - - @Test(groups = "unit") - public void getByteArrayBoundaryCheck4() { - byte[] dst = new byte[4]; - buffer.setInt(0, 0x01020304); - try { - buffer.getBytes(0, dst, 1, 4); - fail(); - } catch (IndexOutOfBoundsException e) { - // Success - } - - // No partial copy is expected. - assertEquals(0, dst[0]); - assertEquals(0, dst[1]); - assertEquals(0, dst[2]); - assertEquals(0, dst[3]); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void getByteBufferBoundaryCheck() { - buffer.getBytes(-1, ByteBuffer.allocate(0)); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void copyBoundaryCheck1() { - buffer.copy(-1, 0); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void copyBoundaryCheck2() { - buffer.copy(0, buffer.capacity() + 1); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void copyBoundaryCheck3() { - buffer.copy(buffer.capacity() + 1, 0); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void copyBoundaryCheck4() { - buffer.copy(buffer.capacity(), 1); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void setIndexBoundaryCheck1() { - buffer.setIndex(-1, CAPACITY); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void setIndexBoundaryCheck2() { - buffer.setIndex(CAPACITY / 2, CAPACITY / 4); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void setIndexBoundaryCheck3() { - buffer.setIndex(0, CAPACITY + 1); - } - - @Test(groups = "unit") - public void getByteBufferState() { - ByteBuffer dst = ByteBuffer.allocate(4); - dst.position(1); - dst.limit(3); - - buffer.setByte(0, (byte) 1); - buffer.setByte(1, (byte) 2); - buffer.setByte(2, (byte) 3); - buffer.setByte(3, (byte) 4); - buffer.getBytes(1, dst); - - assertEquals(3, dst.position()); - assertEquals(3, dst.limit()); - - dst.clear(); - assertEquals(0, dst.get(0)); - assertEquals(2, dst.get(1)); - assertEquals(3, dst.get(2)); - assertEquals(0, dst.get(3)); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void getDirectByteBufferBoundaryCheck() { - buffer.getBytes(-1, ByteBuffer.allocateDirect(0)); - } - - @Test(groups = "unit") - public void getDirectByteBufferState() { - ByteBuffer dst = ByteBuffer.allocateDirect(4); - dst.position(1); - dst.limit(3); - - buffer.setByte(0, (byte) 1); - buffer.setByte(1, (byte) 2); - buffer.setByte(2, (byte) 3); - buffer.setByte(3, (byte) 4); - buffer.getBytes(1, dst); - - assertEquals(3, dst.position()); - assertEquals(3, dst.limit()); - - dst.clear(); - assertEquals(0, dst.get(0)); - assertEquals(2, dst.get(1)); - assertEquals(3, dst.get(2)); - assertEquals(0, dst.get(3)); - } - - @Test(groups = "unit") - public void testRandomByteAccess() { - for (int i = 0; i < buffer.capacity(); i++) { - byte value = (byte) random.nextInt(); - buffer.setByte(i, value); - } - - random.setSeed(seed); - for (int i = 0; i < buffer.capacity(); i++) { - byte value = (byte) random.nextInt(); - assertEquals(value, buffer.getByte(i)); - } - } - - @Test(groups = "unit") - public void testRandomUnsignedByteAccess() { - for (int i = 0; i < buffer.capacity(); i++) { - byte value = (byte) random.nextInt(); - buffer.setByte(i, value); - } - - random.setSeed(seed); - for (int i = 0; i < buffer.capacity(); i++) { - int value = random.nextInt() & 0xFF; - assertEquals(value, buffer.getUnsignedByte(i)); - } - } - - @Test(groups = "unit") - public void testRandomShortAccess() { - testRandomShortAccess(true); - } - - @Test(groups = "unit") - public void testRandomShortLEAccess() { - testRandomShortAccess(false); - } - - private void testRandomShortAccess(boolean testBigEndian) { - for (int i = 0; i < buffer.capacity() - 1; i += 2) { - short value = (short) random.nextInt(); - if (testBigEndian) { - buffer.setShort(i, value); - } else { - buffer.setShortLE(i, value); - } - } - - random.setSeed(seed); - for (int i = 0; i < buffer.capacity() - 1; i += 2) { - short value = (short) random.nextInt(); - if (testBigEndian) { - assertEquals(value, buffer.getShort(i)); - } else { - assertEquals(value, buffer.getShortLE(i)); - } - } - } - - @Test(groups = "unit") - public void testShortConsistentWithByteBuffer() { - testShortConsistentWithByteBuffer(true, true); - testShortConsistentWithByteBuffer(true, false); - testShortConsistentWithByteBuffer(false, true); - testShortConsistentWithByteBuffer(false, false); - } - - private void testShortConsistentWithByteBuffer(boolean direct, boolean testBigEndian) { - for (int i = 0; i < JAVA_BYTEBUFFER_CONSISTENCY_ITERATIONS; ++i) { - ByteBuffer javaBuffer = - direct ? ByteBuffer.allocateDirect(buffer.capacity()) : ByteBuffer.allocate(buffer.capacity()); - if (!testBigEndian) { - javaBuffer = javaBuffer.order(ByteOrder.LITTLE_ENDIAN); - } - - short expected = (short) (random.nextInt() & 0xFFFF); - javaBuffer.putShort(expected); - - final int bufferIndex = buffer.capacity() - 2; - if (testBigEndian) { - buffer.setShort(bufferIndex, expected); - } else { - buffer.setShortLE(bufferIndex, expected); - } - javaBuffer.flip(); - - short javaActual = javaBuffer.getShort(); - assertEquals(expected, javaActual); - assertEquals(javaActual, testBigEndian ? buffer.getShort(bufferIndex) : buffer.getShortLE(bufferIndex)); - } - } - - @Test(groups = "unit") - public void testRandomUnsignedShortAccess() { - testRandomUnsignedShortAccess(true); - } - - @Test(groups = "unit") - public void testRandomUnsignedShortLEAccess() { - testRandomUnsignedShortAccess(false); - } - - private void testRandomUnsignedShortAccess(boolean testBigEndian) { - for (int i = 0; i < buffer.capacity() - 1; i += 2) { - short value = (short) random.nextInt(); - if (testBigEndian) { - buffer.setShort(i, value); - } else { - buffer.setShortLE(i, value); - } - } - - random.setSeed(seed); - for (int i = 0; i < buffer.capacity() - 1; i += 2) { - int value = random.nextInt() & 0xFFFF; - if (testBigEndian) { - assertEquals(value, buffer.getUnsignedShort(i)); - } else { - assertEquals(value, buffer.getUnsignedShortLE(i)); - } - } - } - - @Test(groups = "unit") - public void testRandomMediumAccess() { - testRandomMediumAccess(true); - } - - @Test(groups = "unit") - public void testRandomMediumLEAccess() { - testRandomMediumAccess(false); - } - - private void testRandomMediumAccess(boolean testBigEndian) { - for (int i = 0; i < buffer.capacity() - 2; i += 3) { - int value = random.nextInt(); - if (testBigEndian) { - buffer.setMedium(i, value); - } else { - buffer.setMediumLE(i, value); - } - } - - random.setSeed(seed); - for (int i = 0; i < buffer.capacity() - 2; i += 3) { - int value = random.nextInt() << 8 >> 8; - if (testBigEndian) { - assertEquals(value, buffer.getMedium(i)); - } else { - assertEquals(value, buffer.getMediumLE(i)); - } - } - } - - @Test(groups = "unit") - public void testRandomUnsignedMediumAccess() { - testRandomUnsignedMediumAccess(true); - } - - @Test(groups = "unit") - public void testRandomUnsignedMediumLEAccess() { - testRandomUnsignedMediumAccess(false); - } - - private void testRandomUnsignedMediumAccess(boolean testBigEndian) { - for (int i = 0; i < buffer.capacity() - 2; i += 3) { - int value = random.nextInt(); - if (testBigEndian) { - buffer.setMedium(i, value); - } else { - buffer.setMediumLE(i, value); - } - } - - random.setSeed(seed); - for (int i = 0; i < buffer.capacity() - 2; i += 3) { - int value = random.nextInt() & 0x00FFFFFF; - if (testBigEndian) { - assertEquals(value, buffer.getUnsignedMedium(i)); - } else { - assertEquals(value, buffer.getUnsignedMediumLE(i)); - } - } - } - - @Test(groups = "unit") - public void testMediumConsistentWithByteBuffer() { - testMediumConsistentWithByteBuffer(true, true); - testMediumConsistentWithByteBuffer(true, false); - testMediumConsistentWithByteBuffer(false, true); - testMediumConsistentWithByteBuffer(false, false); - } - - private void testMediumConsistentWithByteBuffer(boolean direct, boolean testBigEndian) { - for (int i = 0; i < JAVA_BYTEBUFFER_CONSISTENCY_ITERATIONS; ++i) { - ByteBuffer javaBuffer = - direct ? ByteBuffer.allocateDirect(buffer.capacity()) : ByteBuffer.allocate(buffer.capacity()); - if (!testBigEndian) { - javaBuffer = javaBuffer.order(ByteOrder.LITTLE_ENDIAN); - } - - int expected = random.nextInt() & 0x00FFFFFF; - javaBuffer.putInt(expected); - - final int bufferIndex = buffer.capacity() - 3; - if (testBigEndian) { - buffer.setMedium(bufferIndex, expected); - } else { - buffer.setMediumLE(bufferIndex, expected); - } - javaBuffer.flip(); - - int javaActual = javaBuffer.getInt(); - assertEquals(expected, javaActual); - assertEquals( - javaActual, - testBigEndian ? buffer.getUnsignedMedium(bufferIndex) : buffer.getUnsignedMediumLE(bufferIndex)); - } - } - - @Test(groups = "unit") - public void testRandomIntAccess() { - testRandomIntAccess(true); - } - - @Test(groups = "unit") - public void testRandomIntLEAccess() { - testRandomIntAccess(false); - } - - private void testRandomIntAccess(boolean testBigEndian) { - for (int i = 0; i < buffer.capacity() - 3; i += 4) { - int value = random.nextInt(); - if (testBigEndian) { - buffer.setInt(i, value); - } else { - buffer.setIntLE(i, value); - } - } - - random.setSeed(seed); - for (int i = 0; i < buffer.capacity() - 3; i += 4) { - int value = random.nextInt(); - if (testBigEndian) { - assertEquals(value, buffer.getInt(i)); - } else { - assertEquals(value, buffer.getIntLE(i)); - } - } - } - - @Test(groups = "unit") - public void testIntConsistentWithByteBuffer() { - testIntConsistentWithByteBuffer(true, true); - testIntConsistentWithByteBuffer(true, false); - testIntConsistentWithByteBuffer(false, true); - testIntConsistentWithByteBuffer(false, false); - } - - private void testIntConsistentWithByteBuffer(boolean direct, boolean testBigEndian) { - for (int i = 0; i < JAVA_BYTEBUFFER_CONSISTENCY_ITERATIONS; ++i) { - ByteBuffer javaBuffer = - direct ? ByteBuffer.allocateDirect(buffer.capacity()) : ByteBuffer.allocate(buffer.capacity()); - if (!testBigEndian) { - javaBuffer = javaBuffer.order(ByteOrder.LITTLE_ENDIAN); - } - - int expected = random.nextInt(); - javaBuffer.putInt(expected); - - final int bufferIndex = buffer.capacity() - 4; - if (testBigEndian) { - buffer.setInt(bufferIndex, expected); - } else { - buffer.setIntLE(bufferIndex, expected); - } - javaBuffer.flip(); - - int javaActual = javaBuffer.getInt(); - assertEquals(expected, javaActual); - assertEquals(javaActual, testBigEndian ? buffer.getInt(bufferIndex) : buffer.getIntLE(bufferIndex)); - } - } - - @Test(groups = "unit") - public void testRandomUnsignedIntAccess() { - testRandomUnsignedIntAccess(true); - } - - @Test(groups = "unit") - public void testRandomUnsignedIntLEAccess() { - testRandomUnsignedIntAccess(false); - } - - private void testRandomUnsignedIntAccess(boolean testBigEndian) { - for (int i = 0; i < buffer.capacity() - 3; i += 4) { - int value = random.nextInt(); - if (testBigEndian) { - buffer.setInt(i, value); - } else { - buffer.setIntLE(i, value); - } - } - - random.setSeed(seed); - for (int i = 0; i < buffer.capacity() - 3; i += 4) { - long value = random.nextInt() & 0xFFFFFFFFL; - if (testBigEndian) { - assertEquals(value, buffer.getUnsignedInt(i)); - } else { - assertEquals(value, buffer.getUnsignedIntLE(i)); - } - } - } - - @Test(groups = "unit") - public void testRandomLongAccess() { - testRandomLongAccess(true); - } - - @Test(groups = "unit") - public void testRandomLongLEAccess() { - testRandomLongAccess(false); - } - - private void testRandomLongAccess(boolean testBigEndian) { - for (int i = 0; i < buffer.capacity() - 7; i += 8) { - long value = random.nextLong(); - if (testBigEndian) { - buffer.setLong(i, value); - } else { - buffer.setLongLE(i, value); - } - } - - random.setSeed(seed); - for (int i = 0; i < buffer.capacity() - 7; i += 8) { - long value = random.nextLong(); - if (testBigEndian) { - assertEquals(value, buffer.getLong(i)); - } else { - assertEquals(value, buffer.getLongLE(i)); - } - } - } - - @Test(groups = "unit") - public void testLongConsistentWithByteBuffer() { - testLongConsistentWithByteBuffer(true, true); - testLongConsistentWithByteBuffer(true, false); - testLongConsistentWithByteBuffer(false, true); - testLongConsistentWithByteBuffer(false, false); - } - - private void testLongConsistentWithByteBuffer(boolean direct, boolean testBigEndian) { - for (int i = 0; i < JAVA_BYTEBUFFER_CONSISTENCY_ITERATIONS; ++i) { - ByteBuffer javaBuffer = - direct ? ByteBuffer.allocateDirect(buffer.capacity()) : ByteBuffer.allocate(buffer.capacity()); - if (!testBigEndian) { - javaBuffer = javaBuffer.order(ByteOrder.LITTLE_ENDIAN); - } - - long expected = random.nextLong(); - javaBuffer.putLong(expected); - - final int bufferIndex = buffer.capacity() - 8; - if (testBigEndian) { - buffer.setLong(bufferIndex, expected); - } else { - buffer.setLongLE(bufferIndex, expected); - } - javaBuffer.flip(); - - long javaActual = javaBuffer.getLong(); - assertEquals(expected, javaActual); - assertEquals(javaActual, testBigEndian ? buffer.getLong(bufferIndex) : buffer.getLongLE(bufferIndex)); - } - } - - @Test(groups = "unit") - public void testRandomFloatAccess() { - testRandomFloatAccess(true); - } - - @Test(groups = "unit") - public void testRandomFloatLEAccess() { - testRandomFloatAccess(false); - } - - private void testRandomFloatAccess(boolean testBigEndian) { - for (int i = 0; i < buffer.capacity() - 7; i += 8) { - float value = random.nextFloat(); - if (testBigEndian) { - buffer.setFloat(i, value); - } else { - buffer.setFloatLE(i, value); - } - } - - random.setSeed(seed); - for (int i = 0; i < buffer.capacity() - 7; i += 8) { - float expected = random.nextFloat(); - float actual = testBigEndian ? buffer.getFloat(i) : buffer.getFloatLE(i); - assertEquals(expected, actual, 0.01); - } - } - - @Test(groups = "unit") - public void testRandomDoubleAccess() { - testRandomDoubleAccess(true); - } - - @Test(groups = "unit") - public void testRandomDoubleLEAccess() { - testRandomDoubleAccess(false); - } - - private void testRandomDoubleAccess(boolean testBigEndian) { - for (int i = 0; i < buffer.capacity() - 7; i += 8) { - double value = random.nextDouble(); - if (testBigEndian) { - buffer.setDouble(i, value); - } else { - buffer.setDoubleLE(i, value); - } - } - - random.setSeed(seed); - for (int i = 0; i < buffer.capacity() - 7; i += 8) { - double expected = random.nextDouble(); - double actual = testBigEndian ? buffer.getDouble(i) : buffer.getDoubleLE(i); - assertEquals(expected, actual, 0.01); - } - } - - @Test(groups = "unit") - public void testSetZero() { - buffer.clear(); - while (buffer.isWritable()) { - buffer.writeByte((byte) 0xFF); - } - - for (int i = 0; i < buffer.capacity();) { - int length = Math.min(buffer.capacity() - i, random.nextInt(32)); - buffer.setZero(i, length); - i += length; - } - - for (int i = 0; i < buffer.capacity(); i++) { - assertEquals(0, buffer.getByte(i)); - } - } - - @Test(groups = "unit") - public void testSequentialByteAccess() { - buffer.writerIndex(0); - for (int i = 0; i < buffer.capacity(); i++) { - byte value = (byte) random.nextInt(); - assertEquals(i, buffer.writerIndex()); - assertTrue(buffer.isWritable()); - buffer.writeByte(value); - } - - assertEquals(0, buffer.readerIndex()); - assertEquals(buffer.capacity(), buffer.writerIndex()); - assertFalse(buffer.isWritable()); - - random.setSeed(seed); - for (int i = 0; i < buffer.capacity(); i++) { - byte value = (byte) random.nextInt(); - assertEquals(i, buffer.readerIndex()); - assertTrue(buffer.isReadable()); - assertEquals(value, buffer.readByte()); - } - - assertEquals(buffer.capacity(), buffer.readerIndex()); - assertEquals(buffer.capacity(), buffer.writerIndex()); - assertFalse(buffer.isReadable()); - assertFalse(buffer.isWritable()); - } - - @Test(groups = "unit") - public void testSequentialUnsignedByteAccess() { - buffer.writerIndex(0); - for (int i = 0; i < buffer.capacity(); i++) { - byte value = (byte) random.nextInt(); - assertEquals(i, buffer.writerIndex()); - assertTrue(buffer.isWritable()); - buffer.writeByte(value); - } - - assertEquals(0, buffer.readerIndex()); - assertEquals(buffer.capacity(), buffer.writerIndex()); - assertFalse(buffer.isWritable()); - - random.setSeed(seed); - for (int i = 0; i < buffer.capacity(); i++) { - int value = random.nextInt() & 0xFF; - assertEquals(i, buffer.readerIndex()); - assertTrue(buffer.isReadable()); - assertEquals(value, buffer.readUnsignedByte()); - } - - assertEquals(buffer.capacity(), buffer.readerIndex()); - assertEquals(buffer.capacity(), buffer.writerIndex()); - assertFalse(buffer.isReadable()); - assertFalse(buffer.isWritable()); - } - - @Test(groups = "unit") - public void testSequentialShortAccess() { - testSequentialShortAccess(true); - } - - @Test(groups = "unit") - public void testSequentialShortLEAccess() { - testSequentialShortAccess(false); - } - - private void testSequentialShortAccess(boolean testBigEndian) { - buffer.writerIndex(0); - for (int i = 0; i < buffer.capacity(); i += 2) { - short value = (short) random.nextInt(); - assertEquals(i, buffer.writerIndex()); - assertTrue(buffer.isWritable()); - if (testBigEndian) { - buffer.writeShort(value); - } else { - buffer.writeShortLE(value); - } - } - - assertEquals(0, buffer.readerIndex()); - assertEquals(buffer.capacity(), buffer.writerIndex()); - assertFalse(buffer.isWritable()); - - random.setSeed(seed); - for (int i = 0; i < buffer.capacity(); i += 2) { - short value = (short) random.nextInt(); - assertEquals(i, buffer.readerIndex()); - assertTrue(buffer.isReadable()); - if (testBigEndian) { - assertEquals(value, buffer.readShort()); - } else { - assertEquals(value, buffer.readShortLE()); - } - } - - assertEquals(buffer.capacity(), buffer.readerIndex()); - assertEquals(buffer.capacity(), buffer.writerIndex()); - assertFalse(buffer.isReadable()); - assertFalse(buffer.isWritable()); - } - - @Test(groups = "unit") - public void testSequentialUnsignedShortAccess() { - testSequentialUnsignedShortAccess(true); - } - - @Test(groups = "unit") - public void testSequentialUnsignedShortLEAccess() { - testSequentialUnsignedShortAccess(true); - } - - private void testSequentialUnsignedShortAccess(boolean testBigEndian) { - buffer.writerIndex(0); - for (int i = 0; i < buffer.capacity(); i += 2) { - short value = (short) random.nextInt(); - assertEquals(i, buffer.writerIndex()); - assertTrue(buffer.isWritable()); - if (testBigEndian) { - buffer.writeShort(value); - } else { - buffer.writeShortLE(value); - } - } - - assertEquals(0, buffer.readerIndex()); - assertEquals(buffer.capacity(), buffer.writerIndex()); - assertFalse(buffer.isWritable()); - - random.setSeed(seed); - for (int i = 0; i < buffer.capacity(); i += 2) { - int value = random.nextInt() & 0xFFFF; - assertEquals(i, buffer.readerIndex()); - assertTrue(buffer.isReadable()); - if (testBigEndian) { - assertEquals(value, buffer.readUnsignedShort()); - } else { - assertEquals(value, buffer.readUnsignedShortLE()); - } - } - - assertEquals(buffer.capacity(), buffer.readerIndex()); - assertEquals(buffer.capacity(), buffer.writerIndex()); - assertFalse(buffer.isReadable()); - assertFalse(buffer.isWritable()); - } - - @Test(groups = "unit") - public void testSequentialMediumAccess() { - testSequentialMediumAccess(true); - } - - @Test(groups = "unit") - public void testSequentialMediumLEAccess() { - testSequentialMediumAccess(false); - } - - private void testSequentialMediumAccess(boolean testBigEndian) { - buffer.writerIndex(0); - for (int i = 0; i < buffer.capacity() / 3 * 3; i += 3) { - int value = random.nextInt(); - assertEquals(i, buffer.writerIndex()); - assertTrue(buffer.isWritable()); - if (testBigEndian) { - buffer.writeMedium(value); - } else { - buffer.writeMediumLE(value); - } - } - - assertEquals(0, buffer.readerIndex()); - assertEquals(buffer.capacity() / 3 * 3, buffer.writerIndex()); - assertEquals(buffer.capacity() % 3, buffer.writableBytes()); - - random.setSeed(seed); - for (int i = 0; i < buffer.capacity() / 3 * 3; i += 3) { - int value = random.nextInt() << 8 >> 8; - assertEquals(i, buffer.readerIndex()); - assertTrue(buffer.isReadable()); - if (testBigEndian) { - assertEquals(value, buffer.readMedium()); - } else { - assertEquals(value, buffer.readMediumLE()); - } - } - - assertEquals(buffer.capacity() / 3 * 3, buffer.readerIndex()); - assertEquals(buffer.capacity() / 3 * 3, buffer.writerIndex()); - assertEquals(0, buffer.readableBytes()); - assertEquals(buffer.capacity() % 3, buffer.writableBytes()); - } - - @Test(groups = "unit") - public void testSequentialUnsignedMediumAccess() { - testSequentialUnsignedMediumAccess(true); - } - - @Test(groups = "unit") - public void testSequentialUnsignedMediumLEAccess() { - testSequentialUnsignedMediumAccess(false); - } - - private void testSequentialUnsignedMediumAccess(boolean testBigEndian) { - buffer.writerIndex(0); - for (int i = 0; i < buffer.capacity() / 3 * 3; i += 3) { - int value = random.nextInt() & 0x00FFFFFF; - assertEquals(i, buffer.writerIndex()); - assertTrue(buffer.isWritable()); - if (testBigEndian) { - buffer.writeMedium(value); - } else { - buffer.writeMediumLE(value); - } - } - - assertEquals(0, buffer.readerIndex()); - assertEquals(buffer.capacity() / 3 * 3, buffer.writerIndex()); - assertEquals(buffer.capacity() % 3, buffer.writableBytes()); - - random.setSeed(seed); - for (int i = 0; i < buffer.capacity() / 3 * 3; i += 3) { - int value = random.nextInt() & 0x00FFFFFF; - assertEquals(i, buffer.readerIndex()); - assertTrue(buffer.isReadable()); - if (testBigEndian) { - assertEquals(value, buffer.readUnsignedMedium()); - } else { - assertEquals(value, buffer.readUnsignedMediumLE()); - } - } - - assertEquals(buffer.capacity() / 3 * 3, buffer.readerIndex()); - assertEquals(buffer.capacity() / 3 * 3, buffer.writerIndex()); - assertEquals(0, buffer.readableBytes()); - assertEquals(buffer.capacity() % 3, buffer.writableBytes()); - } - - @Test(groups = "unit") - public void testSequentialIntAccess() { - testSequentialIntAccess(true); - } - - @Test(groups = "unit") - public void testSequentialIntLEAccess() { - testSequentialIntAccess(false); - } - - private void testSequentialIntAccess(boolean testBigEndian) { - buffer.writerIndex(0); - for (int i = 0; i < buffer.capacity(); i += 4) { - int value = random.nextInt(); - assertEquals(i, buffer.writerIndex()); - assertTrue(buffer.isWritable()); - if (testBigEndian) { - buffer.writeInt(value); - } else { - buffer.writeIntLE(value); - } - } - - assertEquals(0, buffer.readerIndex()); - assertEquals(buffer.capacity(), buffer.writerIndex()); - assertFalse(buffer.isWritable()); - - random.setSeed(seed); - for (int i = 0; i < buffer.capacity(); i += 4) { - int value = random.nextInt(); - assertEquals(i, buffer.readerIndex()); - assertTrue(buffer.isReadable()); - if (testBigEndian) { - assertEquals(value, buffer.readInt()); - } else { - assertEquals(value, buffer.readIntLE()); - } - } - - assertEquals(buffer.capacity(), buffer.readerIndex()); - assertEquals(buffer.capacity(), buffer.writerIndex()); - assertFalse(buffer.isReadable()); - assertFalse(buffer.isWritable()); - } - - @Test(groups = "unit") - public void testSequentialUnsignedIntAccess() { - testSequentialUnsignedIntAccess(true); - } - - @Test(groups = "unit") - public void testSequentialUnsignedIntLEAccess() { - testSequentialUnsignedIntAccess(false); - } - - private void testSequentialUnsignedIntAccess(boolean testBigEndian) { - buffer.writerIndex(0); - for (int i = 0; i < buffer.capacity(); i += 4) { - int value = random.nextInt(); - assertEquals(i, buffer.writerIndex()); - assertTrue(buffer.isWritable()); - if (testBigEndian) { - buffer.writeInt(value); - } else { - buffer.writeIntLE(value); - } - } - - assertEquals(0, buffer.readerIndex()); - assertEquals(buffer.capacity(), buffer.writerIndex()); - assertFalse(buffer.isWritable()); - - random.setSeed(seed); - for (int i = 0; i < buffer.capacity(); i += 4) { - long value = random.nextInt() & 0xFFFFFFFFL; - assertEquals(i, buffer.readerIndex()); - assertTrue(buffer.isReadable()); - if (testBigEndian) { - assertEquals(value, buffer.readUnsignedInt()); - } else { - assertEquals(value, buffer.readUnsignedIntLE()); - } - } - - assertEquals(buffer.capacity(), buffer.readerIndex()); - assertEquals(buffer.capacity(), buffer.writerIndex()); - assertFalse(buffer.isReadable()); - assertFalse(buffer.isWritable()); - } - - @Test(groups = "unit") - public void testSequentialLongAccess() { - testSequentialLongAccess(true); - } - - @Test(groups = "unit") - public void testSequentialLongLEAccess() { - testSequentialLongAccess(false); - } - - private void testSequentialLongAccess(boolean testBigEndian) { - buffer.writerIndex(0); - for (int i = 0; i < buffer.capacity(); i += 8) { - long value = random.nextLong(); - assertEquals(i, buffer.writerIndex()); - assertTrue(buffer.isWritable()); - if (testBigEndian) { - buffer.writeLong(value); - } else { - buffer.writeLongLE(value); - } - } - - assertEquals(0, buffer.readerIndex()); - assertEquals(buffer.capacity(), buffer.writerIndex()); - assertFalse(buffer.isWritable()); - - random.setSeed(seed); - for (int i = 0; i < buffer.capacity(); i += 8) { - long value = random.nextLong(); - assertEquals(i, buffer.readerIndex()); - assertTrue(buffer.isReadable()); - if (testBigEndian) { - assertEquals(value, buffer.readLong()); - } else { - assertEquals(value, buffer.readLongLE()); - } - } - - assertEquals(buffer.capacity(), buffer.readerIndex()); - assertEquals(buffer.capacity(), buffer.writerIndex()); - assertFalse(buffer.isReadable()); - assertFalse(buffer.isWritable()); - } - - @Test(groups = "unit") - public void testByteArrayTransfer() { - byte[] value = new byte[BLOCK_SIZE * 2]; - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(value); - buffer.setBytes(i, value, random.nextInt(BLOCK_SIZE), BLOCK_SIZE); - } - - random.setSeed(seed); - byte[] expectedValue = new byte[BLOCK_SIZE * 2]; - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(expectedValue); - int valueOffset = random.nextInt(BLOCK_SIZE); - buffer.getBytes(i, value, valueOffset, BLOCK_SIZE); - for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j++) { - assertEquals(expectedValue[j], value[j]); - } - } - } - - @Test(groups = "unit") - public void testRandomByteArrayTransfer1() { - byte[] value = new byte[BLOCK_SIZE]; - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(value); - buffer.setBytes(i, value); - } - - random.setSeed(seed); - byte[] expectedValueContent = new byte[BLOCK_SIZE]; - ByteBuf expectedValue = wrappedBuffer(expectedValueContent); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(expectedValueContent); - buffer.getBytes(i, value); - for (int j = 0; j < BLOCK_SIZE; j++) { - assertEquals(expectedValue.getByte(j), value[j]); - } - } - } - - @Test(groups = "unit") - public void testRandomByteArrayTransfer2() { - byte[] value = new byte[BLOCK_SIZE * 2]; - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(value); - buffer.setBytes(i, value, random.nextInt(BLOCK_SIZE), BLOCK_SIZE); - } - - random.setSeed(seed); - byte[] expectedValueContent = new byte[BLOCK_SIZE * 2]; - ByteBuf expectedValue = wrappedBuffer(expectedValueContent); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(expectedValueContent); - int valueOffset = random.nextInt(BLOCK_SIZE); - buffer.getBytes(i, value, valueOffset, BLOCK_SIZE); - for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j++) { - assertEquals(expectedValue.getByte(j), value[j]); - } - } - } - - @Test(groups = "unit") - public void testRandomHeapBufferTransfer1() { - byte[] valueContent = new byte[BLOCK_SIZE]; - ByteBuf value = wrappedBuffer(valueContent); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(valueContent); - value.setIndex(0, BLOCK_SIZE); - buffer.setBytes(i, value); - assertEquals(BLOCK_SIZE, value.readerIndex()); - assertEquals(BLOCK_SIZE, value.writerIndex()); - } - - random.setSeed(seed); - byte[] expectedValueContent = new byte[BLOCK_SIZE]; - ByteBuf expectedValue = wrappedBuffer(expectedValueContent); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(expectedValueContent); - value.clear(); - buffer.getBytes(i, value); - assertEquals(0, value.readerIndex()); - assertEquals(BLOCK_SIZE, value.writerIndex()); - for (int j = 0; j < BLOCK_SIZE; j++) { - assertEquals(expectedValue.getByte(j), value.getByte(j)); - } - } - } - - @Test(groups = "unit") - public void testRandomHeapBufferTransfer2() { - byte[] valueContent = new byte[BLOCK_SIZE * 2]; - ByteBuf value = wrappedBuffer(valueContent); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(valueContent); - buffer.setBytes(i, value, random.nextInt(BLOCK_SIZE), BLOCK_SIZE); - } - - random.setSeed(seed); - byte[] expectedValueContent = new byte[BLOCK_SIZE * 2]; - ByteBuf expectedValue = wrappedBuffer(expectedValueContent); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(expectedValueContent); - int valueOffset = random.nextInt(BLOCK_SIZE); - buffer.getBytes(i, value, valueOffset, BLOCK_SIZE); - for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j++) { - assertEquals(expectedValue.getByte(j), value.getByte(j)); - } - } - } - - @Test(groups = "unit") - public void testRandomDirectBufferTransfer() { - byte[] tmp = new byte[BLOCK_SIZE * 2]; - ByteBuf value = directBuffer(BLOCK_SIZE * 2); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(tmp); - value.setBytes(0, tmp, 0, value.capacity()); - buffer.setBytes(i, value, random.nextInt(BLOCK_SIZE), BLOCK_SIZE); - } - - random.setSeed(seed); - ByteBuf expectedValue = directBuffer(BLOCK_SIZE * 2); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(tmp); - expectedValue.setBytes(0, tmp, 0, expectedValue.capacity()); - int valueOffset = random.nextInt(BLOCK_SIZE); - buffer.getBytes(i, value, valueOffset, BLOCK_SIZE); - for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j++) { - assertEquals(expectedValue.getByte(j), value.getByte(j)); - } - } - value.release(); - expectedValue.release(); - } - - @Test(groups = "unit") - public void testRandomByteBufferTransfer() { - ByteBuffer value = ByteBuffer.allocate(BLOCK_SIZE * 2); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(value.array()); - value.clear().position(random.nextInt(BLOCK_SIZE)); - value.limit(value.position() + BLOCK_SIZE); - buffer.setBytes(i, value); - } - - random.setSeed(seed); - ByteBuffer expectedValue = ByteBuffer.allocate(BLOCK_SIZE * 2); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(expectedValue.array()); - int valueOffset = random.nextInt(BLOCK_SIZE); - value.clear().position(valueOffset).limit(valueOffset + BLOCK_SIZE); - buffer.getBytes(i, value); - assertEquals(valueOffset + BLOCK_SIZE, value.position()); - for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j++) { - assertEquals(expectedValue.get(j), value.get(j)); - } - } - } - - @Test(groups = "unit") - public void testSequentialByteArrayTransfer1() { - byte[] value = new byte[BLOCK_SIZE]; - buffer.writerIndex(0); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(value); - assertEquals(0, buffer.readerIndex()); - assertEquals(i, buffer.writerIndex()); - buffer.writeBytes(value); - } - - random.setSeed(seed); - byte[] expectedValue = new byte[BLOCK_SIZE]; - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(expectedValue); - assertEquals(i, buffer.readerIndex()); - assertEquals(CAPACITY, buffer.writerIndex()); - buffer.readBytes(value); - for (int j = 0; j < BLOCK_SIZE; j++) { - assertEquals(expectedValue[j], value[j]); - } - } - } - - @Test(groups = "unit") - public void testSequentialByteArrayTransfer2() { - byte[] value = new byte[BLOCK_SIZE * 2]; - buffer.writerIndex(0); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(value); - assertEquals(0, buffer.readerIndex()); - assertEquals(i, buffer.writerIndex()); - int readerIndex = random.nextInt(BLOCK_SIZE); - buffer.writeBytes(value, readerIndex, BLOCK_SIZE); - } - - random.setSeed(seed); - byte[] expectedValue = new byte[BLOCK_SIZE * 2]; - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(expectedValue); - int valueOffset = random.nextInt(BLOCK_SIZE); - assertEquals(i, buffer.readerIndex()); - assertEquals(CAPACITY, buffer.writerIndex()); - buffer.readBytes(value, valueOffset, BLOCK_SIZE); - for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j++) { - assertEquals(expectedValue[j], value[j]); - } - } - } - - @Test(groups = "unit") - public void testSequentialHeapBufferTransfer1() { - byte[] valueContent = new byte[BLOCK_SIZE * 2]; - ByteBuf value = wrappedBuffer(valueContent); - buffer.writerIndex(0); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(valueContent); - assertEquals(0, buffer.readerIndex()); - assertEquals(i, buffer.writerIndex()); - buffer.writeBytes(value, random.nextInt(BLOCK_SIZE), BLOCK_SIZE); - assertEquals(0, value.readerIndex()); - assertEquals(valueContent.length, value.writerIndex()); - } - - random.setSeed(seed); - byte[] expectedValueContent = new byte[BLOCK_SIZE * 2]; - ByteBuf expectedValue = wrappedBuffer(expectedValueContent); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(expectedValueContent); - int valueOffset = random.nextInt(BLOCK_SIZE); - assertEquals(i, buffer.readerIndex()); - assertEquals(CAPACITY, buffer.writerIndex()); - buffer.readBytes(value, valueOffset, BLOCK_SIZE); - for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j++) { - assertEquals(expectedValue.getByte(j), value.getByte(j)); - } - assertEquals(0, value.readerIndex()); - assertEquals(valueContent.length, value.writerIndex()); - } - } - - @Test(groups = "unit") - public void testSequentialHeapBufferTransfer2() { - byte[] valueContent = new byte[BLOCK_SIZE * 2]; - ByteBuf value = wrappedBuffer(valueContent); - buffer.writerIndex(0); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(valueContent); - assertEquals(0, buffer.readerIndex()); - assertEquals(i, buffer.writerIndex()); - int readerIndex = random.nextInt(BLOCK_SIZE); - value.readerIndex(readerIndex); - value.writerIndex(readerIndex + BLOCK_SIZE); - buffer.writeBytes(value); - assertEquals(readerIndex + BLOCK_SIZE, value.writerIndex()); - assertEquals(value.writerIndex(), value.readerIndex()); - } - - random.setSeed(seed); - byte[] expectedValueContent = new byte[BLOCK_SIZE * 2]; - ByteBuf expectedValue = wrappedBuffer(expectedValueContent); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(expectedValueContent); - int valueOffset = random.nextInt(BLOCK_SIZE); - assertEquals(i, buffer.readerIndex()); - assertEquals(CAPACITY, buffer.writerIndex()); - value.readerIndex(valueOffset); - value.writerIndex(valueOffset); - buffer.readBytes(value, BLOCK_SIZE); - for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j++) { - assertEquals(expectedValue.getByte(j), value.getByte(j)); - } - assertEquals(valueOffset, value.readerIndex()); - assertEquals(valueOffset + BLOCK_SIZE, value.writerIndex()); - } - } - - @Test(groups = "unit") - public void testSequentialDirectBufferTransfer1() { - byte[] valueContent = new byte[BLOCK_SIZE * 2]; - ByteBuf value = directBuffer(BLOCK_SIZE * 2); - buffer.writerIndex(0); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(valueContent); - value.setBytes(0, valueContent); - assertEquals(0, buffer.readerIndex()); - assertEquals(i, buffer.writerIndex()); - buffer.writeBytes(value, random.nextInt(BLOCK_SIZE), BLOCK_SIZE); - assertEquals(0, value.readerIndex()); - assertEquals(0, value.writerIndex()); - } - - random.setSeed(seed); - byte[] expectedValueContent = new byte[BLOCK_SIZE * 2]; - ByteBuf expectedValue = wrappedBuffer(expectedValueContent); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(expectedValueContent); - int valueOffset = random.nextInt(BLOCK_SIZE); - value.setBytes(0, valueContent); - assertEquals(i, buffer.readerIndex()); - assertEquals(CAPACITY, buffer.writerIndex()); - buffer.readBytes(value, valueOffset, BLOCK_SIZE); - for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j++) { - assertEquals(expectedValue.getByte(j), value.getByte(j)); - } - assertEquals(0, value.readerIndex()); - assertEquals(0, value.writerIndex()); - } - value.release(); - expectedValue.release(); - } - - @Test(groups = "unit") - public void testSequentialDirectBufferTransfer2() { - byte[] valueContent = new byte[BLOCK_SIZE * 2]; - ByteBuf value = directBuffer(BLOCK_SIZE * 2); - buffer.writerIndex(0); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(valueContent); - value.setBytes(0, valueContent); - assertEquals(0, buffer.readerIndex()); - assertEquals(i, buffer.writerIndex()); - int readerIndex = random.nextInt(BLOCK_SIZE); - value.readerIndex(0); - value.writerIndex(readerIndex + BLOCK_SIZE); - value.readerIndex(readerIndex); - buffer.writeBytes(value); - assertEquals(readerIndex + BLOCK_SIZE, value.writerIndex()); - assertEquals(value.writerIndex(), value.readerIndex()); - } - - random.setSeed(seed); - byte[] expectedValueContent = new byte[BLOCK_SIZE * 2]; - ByteBuf expectedValue = wrappedBuffer(expectedValueContent); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(expectedValueContent); - value.setBytes(0, valueContent); - int valueOffset = random.nextInt(BLOCK_SIZE); - assertEquals(i, buffer.readerIndex()); - assertEquals(CAPACITY, buffer.writerIndex()); - value.readerIndex(valueOffset); - value.writerIndex(valueOffset); - buffer.readBytes(value, BLOCK_SIZE); - for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j++) { - assertEquals(expectedValue.getByte(j), value.getByte(j)); - } - assertEquals(valueOffset, value.readerIndex()); - assertEquals(valueOffset + BLOCK_SIZE, value.writerIndex()); - } - value.release(); - expectedValue.release(); - } - - @Test(groups = "unit") - public void testSequentialByteBufferBackedHeapBufferTransfer1() { - byte[] valueContent = new byte[BLOCK_SIZE * 2]; - ByteBuf value = wrappedBuffer(ByteBuffer.allocate(BLOCK_SIZE * 2)); - value.writerIndex(0); - buffer.writerIndex(0); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(valueContent); - value.setBytes(0, valueContent); - assertEquals(0, buffer.readerIndex()); - assertEquals(i, buffer.writerIndex()); - buffer.writeBytes(value, random.nextInt(BLOCK_SIZE), BLOCK_SIZE); - assertEquals(0, value.readerIndex()); - assertEquals(0, value.writerIndex()); - } - - random.setSeed(seed); - byte[] expectedValueContent = new byte[BLOCK_SIZE * 2]; - ByteBuf expectedValue = wrappedBuffer(expectedValueContent); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(expectedValueContent); - int valueOffset = random.nextInt(BLOCK_SIZE); - value.setBytes(0, valueContent); - assertEquals(i, buffer.readerIndex()); - assertEquals(CAPACITY, buffer.writerIndex()); - buffer.readBytes(value, valueOffset, BLOCK_SIZE); - for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j++) { - assertEquals(expectedValue.getByte(j), value.getByte(j)); - } - assertEquals(0, value.readerIndex()); - assertEquals(0, value.writerIndex()); - } - } - - @Test(groups = "unit") - public void testSequentialByteBufferBackedHeapBufferTransfer2() { - byte[] valueContent = new byte[BLOCK_SIZE * 2]; - ByteBuf value = wrappedBuffer(ByteBuffer.allocate(BLOCK_SIZE * 2)); - value.writerIndex(0); - buffer.writerIndex(0); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(valueContent); - value.setBytes(0, valueContent); - assertEquals(0, buffer.readerIndex()); - assertEquals(i, buffer.writerIndex()); - int readerIndex = random.nextInt(BLOCK_SIZE); - value.readerIndex(0); - value.writerIndex(readerIndex + BLOCK_SIZE); - value.readerIndex(readerIndex); - buffer.writeBytes(value); - assertEquals(readerIndex + BLOCK_SIZE, value.writerIndex()); - assertEquals(value.writerIndex(), value.readerIndex()); - } - - random.setSeed(seed); - byte[] expectedValueContent = new byte[BLOCK_SIZE * 2]; - ByteBuf expectedValue = wrappedBuffer(expectedValueContent); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(expectedValueContent); - value.setBytes(0, valueContent); - int valueOffset = random.nextInt(BLOCK_SIZE); - assertEquals(i, buffer.readerIndex()); - assertEquals(CAPACITY, buffer.writerIndex()); - value.readerIndex(valueOffset); - value.writerIndex(valueOffset); - buffer.readBytes(value, BLOCK_SIZE); - for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j++) { - assertEquals(expectedValue.getByte(j), value.getByte(j)); - } - assertEquals(valueOffset, value.readerIndex()); - assertEquals(valueOffset + BLOCK_SIZE, value.writerIndex()); - } - } - - @Test(groups = "unit") - public void testSequentialByteBufferTransfer() { - buffer.writerIndex(0); - ByteBuffer value = ByteBuffer.allocate(BLOCK_SIZE * 2); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(value.array()); - value.clear().position(random.nextInt(BLOCK_SIZE)); - value.limit(value.position() + BLOCK_SIZE); - buffer.writeBytes(value); - } - - random.setSeed(seed); - ByteBuffer expectedValue = ByteBuffer.allocate(BLOCK_SIZE * 2); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(expectedValue.array()); - int valueOffset = random.nextInt(BLOCK_SIZE); - value.clear().position(valueOffset).limit(valueOffset + BLOCK_SIZE); - buffer.readBytes(value); - assertEquals(valueOffset + BLOCK_SIZE, value.position()); - for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j++) { - assertEquals(expectedValue.get(j), value.get(j)); - } - } - } - - @Test(groups = "unit") - public void testSequentialCopiedBufferTransfer1() { - buffer.writerIndex(0); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - byte[] value = new byte[BLOCK_SIZE]; - random.nextBytes(value); - assertEquals(0, buffer.readerIndex()); - assertEquals(i, buffer.writerIndex()); - buffer.writeBytes(value); - } - - random.setSeed(seed); - byte[] expectedValue = new byte[BLOCK_SIZE]; - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(expectedValue); - assertEquals(i, buffer.readerIndex()); - assertEquals(CAPACITY, buffer.writerIndex()); - ByteBuf actualValue = buffer.readBytes(BLOCK_SIZE); - assertEquals(wrappedBuffer(expectedValue), actualValue); - - // Make sure if it is a copied buffer. - actualValue.setByte(0, (byte) (actualValue.getByte(0) + 1)); - assertFalse(buffer.getByte(i) == actualValue.getByte(0)); - actualValue.release(); - } - } - - @Test(groups = "unit") - public void testSequentialSlice1() { - buffer.writerIndex(0); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - byte[] value = new byte[BLOCK_SIZE]; - random.nextBytes(value); - assertEquals(0, buffer.readerIndex()); - assertEquals(i, buffer.writerIndex()); - buffer.writeBytes(value); - } - - random.setSeed(seed); - byte[] expectedValue = new byte[BLOCK_SIZE]; - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - random.nextBytes(expectedValue); - assertEquals(i, buffer.readerIndex()); - assertEquals(CAPACITY, buffer.writerIndex()); - ByteBuf actualValue = buffer.readSlice(BLOCK_SIZE); - assertEquals(buffer.order(), actualValue.order()); - assertEquals(wrappedBuffer(expectedValue), actualValue); - - // Make sure if it is a sliced buffer. - actualValue.setByte(0, (byte) (actualValue.getByte(0) + 1)); - assertEquals(buffer.getByte(i), actualValue.getByte(0)); - } - } - - @Test(groups = "unit") - public void testWriteZero() { - try { - buffer.writeZero(-1); - fail(); - } catch (IllegalArgumentException e) { - // Expected - } - - buffer.clear(); - while (buffer.isWritable()) { - buffer.writeByte((byte) 0xFF); - } - - buffer.clear(); - for (int i = 0; i < buffer.capacity();) { - int length = Math.min(buffer.capacity() - i, random.nextInt(32)); - buffer.writeZero(length); - i += length; - } - - assertEquals(0, buffer.readerIndex()); - assertEquals(buffer.capacity(), buffer.writerIndex()); - - for (int i = 0; i < buffer.capacity(); i++) { - assertEquals(0, buffer.getByte(i)); - } - } - - @Test(groups = "unit") - public void testDiscardReadBytes() { - buffer.writerIndex(0); - for (int i = 0; i < buffer.capacity(); i += 4) { - buffer.writeInt(i); - } - ByteBuf copy = copiedBuffer(buffer); - - // Make sure there's no effect if called when readerIndex is 0. - buffer.readerIndex(CAPACITY / 4); - buffer.markReaderIndex(); - buffer.writerIndex(CAPACITY / 3); - buffer.markWriterIndex(); - buffer.readerIndex(0); - buffer.writerIndex(CAPACITY / 2); - buffer.discardReadBytes(); - - assertEquals(0, buffer.readerIndex()); - assertEquals(CAPACITY / 2, buffer.writerIndex()); - assertEquals(copy.slice(0, CAPACITY / 2), buffer.slice(0, CAPACITY / 2)); - buffer.resetReaderIndex(); - assertEquals(CAPACITY / 4, buffer.readerIndex()); - buffer.resetWriterIndex(); - assertEquals(CAPACITY / 3, buffer.writerIndex()); - - // Make sure bytes after writerIndex is not copied. - buffer.readerIndex(1); - buffer.writerIndex(CAPACITY / 2); - buffer.discardReadBytes(); - - assertEquals(0, buffer.readerIndex()); - assertEquals(CAPACITY / 2 - 1, buffer.writerIndex()); - assertEquals(copy.slice(1, CAPACITY / 2 - 1), buffer.slice(0, CAPACITY / 2 - 1)); - - if (discardReadBytesDoesNotMoveWritableBytes()) { - // If writable bytes were copied, the test should fail to avoid unnecessary memory bandwidth consumption. - assertFalse(copy.slice(CAPACITY / 2, CAPACITY / 2).equals(buffer.slice(CAPACITY / 2 - 1, CAPACITY / 2))); - } else { - assertEquals(copy.slice(CAPACITY / 2, CAPACITY / 2), buffer.slice(CAPACITY / 2 - 1, CAPACITY / 2)); - } - - // Marks also should be relocated. - buffer.resetReaderIndex(); - assertEquals(CAPACITY / 4 - 1, buffer.readerIndex()); - buffer.resetWriterIndex(); - assertEquals(CAPACITY / 3 - 1, buffer.writerIndex()); - copy.release(); - } - - /** - * The similar test case with {@link #testDiscardReadBytes()} but this one - * discards a large chunk at once. - */ - @Test(groups = "unit") - public void testDiscardReadBytes2() { - buffer.writerIndex(0); - for (int i = 0; i < buffer.capacity(); i++) { - buffer.writeByte((byte) i); - } - ByteBuf copy = copiedBuffer(buffer); - - // Discard the first (CAPACITY / 2 - 1) bytes. - buffer.setIndex(CAPACITY / 2 - 1, CAPACITY - 1); - buffer.discardReadBytes(); - assertEquals(0, buffer.readerIndex()); - assertEquals(CAPACITY / 2, buffer.writerIndex()); - for (int i = 0; i < CAPACITY / 2; i++) { - assertEquals(copy.slice(CAPACITY / 2 - 1 + i, CAPACITY / 2 - i), buffer.slice(i, CAPACITY / 2 - i)); - } - copy.release(); - } - - @Test(groups = "unit") - public void testStreamTransfer1() throws Exception { - byte[] expected = new byte[buffer.capacity()]; - random.nextBytes(expected); - - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - ByteArrayInputStream in = new ByteArrayInputStream(expected, i, BLOCK_SIZE); - assertEquals(BLOCK_SIZE, buffer.setBytes(i, in, BLOCK_SIZE)); - assertEquals(-1, buffer.setBytes(i, in, 0)); - } - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - buffer.getBytes(i, out, BLOCK_SIZE); - } - - assertTrue(Arrays.equals(expected, out.toByteArray())); - } - - @Test(groups = "unit") - public void testStreamTransfer2() throws Exception { - byte[] expected = new byte[buffer.capacity()]; - random.nextBytes(expected); - buffer.clear(); - - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - ByteArrayInputStream in = new ByteArrayInputStream(expected, i, BLOCK_SIZE); - assertEquals(i, buffer.writerIndex()); - buffer.writeBytes(in, BLOCK_SIZE); - assertEquals(i + BLOCK_SIZE, buffer.writerIndex()); - } - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - assertEquals(i, buffer.readerIndex()); - buffer.readBytes(out, BLOCK_SIZE); - assertEquals(i + BLOCK_SIZE, buffer.readerIndex()); - } - - assertTrue(Arrays.equals(expected, out.toByteArray())); - } - - @Test(groups = "unit") - public void testCopy() { - for (int i = 0; i < buffer.capacity(); i++) { - byte value = (byte) random.nextInt(); - buffer.setByte(i, value); - } - - final int readerIndex = CAPACITY / 3; - final int writerIndex = CAPACITY * 2 / 3; - buffer.setIndex(readerIndex, writerIndex); - - // Make sure all properties are copied. - ByteBuf copy = buffer.copy(); - assertEquals(0, copy.readerIndex()); - assertEquals(buffer.readableBytes(), copy.writerIndex()); - assertEquals(buffer.readableBytes(), copy.capacity()); - assertSame(buffer.order(), copy.order()); - for (int i = 0; i < copy.capacity(); i++) { - assertEquals(buffer.getByte(i + readerIndex), copy.getByte(i)); - } - - // Make sure the buffer content is independent from each other. - buffer.setByte(readerIndex, (byte) (buffer.getByte(readerIndex) + 1)); - assertTrue(buffer.getByte(readerIndex) != copy.getByte(0)); - copy.setByte(1, (byte) (copy.getByte(1) + 1)); - assertTrue(buffer.getByte(readerIndex + 1) != copy.getByte(1)); - copy.release(); - } - - @Test(groups = "unit") - public void testDuplicate() { - for (int i = 0; i < buffer.capacity(); i++) { - byte value = (byte) random.nextInt(); - buffer.setByte(i, value); - } - - final int readerIndex = CAPACITY / 3; - final int writerIndex = CAPACITY * 2 / 3; - buffer.setIndex(readerIndex, writerIndex); - - // Make sure all properties are copied. - ByteBuf duplicate = buffer.duplicate(); - assertSame(buffer.order(), duplicate.order()); - assertEquals(buffer.readableBytes(), duplicate.readableBytes()); - assertEquals(0, buffer.compareTo(duplicate)); - - // Make sure the buffer content is shared. - buffer.setByte(readerIndex, (byte) (buffer.getByte(readerIndex) + 1)); - assertEquals(buffer.getByte(readerIndex), duplicate.getByte(duplicate.readerIndex())); - duplicate.setByte(duplicate.readerIndex(), (byte) (duplicate.getByte(duplicate.readerIndex()) + 1)); - assertEquals(buffer.getByte(readerIndex), duplicate.getByte(duplicate.readerIndex())); - } - - @Test(groups = "unit") - public void testSliceEndianness() throws Exception { - assertEquals(buffer.order(), buffer.slice(0, buffer.capacity()).order()); - assertEquals(buffer.order(), buffer.slice(0, buffer.capacity() - 1).order()); - assertEquals(buffer.order(), buffer.slice(1, buffer.capacity() - 1).order()); - assertEquals(buffer.order(), buffer.slice(1, buffer.capacity() - 2).order()); - } - - @Test(groups = "unit") - public void testSliceIndex() throws Exception { - assertEquals(0, buffer.slice(0, buffer.capacity()).readerIndex()); - assertEquals(0, buffer.slice(0, buffer.capacity() - 1).readerIndex()); - assertEquals(0, buffer.slice(1, buffer.capacity() - 1).readerIndex()); - assertEquals(0, buffer.slice(1, buffer.capacity() - 2).readerIndex()); - - assertEquals(buffer.capacity(), buffer.slice(0, buffer.capacity()).writerIndex()); - assertEquals(buffer.capacity() - 1, buffer.slice(0, buffer.capacity() - 1).writerIndex()); - assertEquals(buffer.capacity() - 1, buffer.slice(1, buffer.capacity() - 1).writerIndex()); - assertEquals(buffer.capacity() - 2, buffer.slice(1, buffer.capacity() - 2).writerIndex()); - } - - @Test(groups = "unit") - public void testRetainedSliceIndex() throws Exception { - ByteBuf retainedSlice = buffer.retainedSlice(0, buffer.capacity()); - assertEquals(0, retainedSlice.readerIndex()); - retainedSlice.release(); - - retainedSlice = buffer.retainedSlice(0, buffer.capacity() - 1); - assertEquals(0, retainedSlice.readerIndex()); - retainedSlice.release(); - - retainedSlice = buffer.retainedSlice(1, buffer.capacity() - 1); - assertEquals(0, retainedSlice.readerIndex()); - retainedSlice.release(); - - retainedSlice = buffer.retainedSlice(1, buffer.capacity() - 2); - assertEquals(0, retainedSlice.readerIndex()); - retainedSlice.release(); - - retainedSlice = buffer.retainedSlice(0, buffer.capacity()); - assertEquals(buffer.capacity(), retainedSlice.writerIndex()); - retainedSlice.release(); - - retainedSlice = buffer.retainedSlice(0, buffer.capacity() - 1); - assertEquals(buffer.capacity() - 1, retainedSlice.writerIndex()); - retainedSlice.release(); - - retainedSlice = buffer.retainedSlice(1, buffer.capacity() - 1); - assertEquals(buffer.capacity() - 1, retainedSlice.writerIndex()); - retainedSlice.release(); - - retainedSlice = buffer.retainedSlice(1, buffer.capacity() - 2); - assertEquals(buffer.capacity() - 2, retainedSlice.writerIndex()); - retainedSlice.release(); - } - - @Test(groups = "unit") - @SuppressWarnings("ObjectEqualsNull") - public void testEquals() { - assertFalse(buffer.equals(null)); - assertFalse(buffer.equals(new Object())); - - byte[] value = new byte[32]; - buffer.setIndex(0, value.length); - random.nextBytes(value); - buffer.setBytes(0, value); - - assertEquals(buffer, wrappedBuffer(value)); - assertEquals(buffer, wrappedBuffer(value).order(LITTLE_ENDIAN)); - - value[0]++; - assertFalse(buffer.equals(wrappedBuffer(value))); - assertFalse(buffer.equals(wrappedBuffer(value).order(LITTLE_ENDIAN))); - } - - @Test(groups = "unit") - public void testCompareTo() { - try { - buffer.compareTo(null); - fail(); - } catch (NullPointerException e) { - // Expected - } - - // Fill the random stuff - byte[] value = new byte[32]; - random.nextBytes(value); - // Prevent overflow / underflow - if (value[0] == 0) { - value[0]++; - } else if (value[0] == -1) { - value[0]--; - } - - buffer.setIndex(0, value.length); - buffer.setBytes(0, value); - - assertEquals(0, buffer.compareTo(wrappedBuffer(value))); - assertEquals(0, buffer.compareTo(wrappedBuffer(value).order(LITTLE_ENDIAN))); - - value[0]++; - assertTrue(buffer.compareTo(wrappedBuffer(value)) < 0); - assertTrue(buffer.compareTo(wrappedBuffer(value).order(LITTLE_ENDIAN)) < 0); - value[0] -= 2; - assertTrue(buffer.compareTo(wrappedBuffer(value)) > 0); - assertTrue(buffer.compareTo(wrappedBuffer(value).order(LITTLE_ENDIAN)) > 0); - value[0]++; - - assertTrue(buffer.compareTo(wrappedBuffer(value, 0, 31)) > 0); - assertTrue(buffer.compareTo(wrappedBuffer(value, 0, 31).order(LITTLE_ENDIAN)) > 0); - assertTrue(buffer.slice(0, 31).compareTo(wrappedBuffer(value)) < 0); - assertTrue(buffer.slice(0, 31).compareTo(wrappedBuffer(value).order(LITTLE_ENDIAN)) < 0); - - ByteBuf retainedSlice = buffer.retainedSlice(0, 31); - assertTrue(retainedSlice.compareTo(wrappedBuffer(value)) < 0); - retainedSlice.release(); - - retainedSlice = buffer.retainedSlice(0, 31); - assertTrue(retainedSlice.compareTo(wrappedBuffer(value).order(LITTLE_ENDIAN)) < 0); - retainedSlice.release(); - } - - @Test(groups = "unit") - public void testCompareTo2() { - byte[] bytes = { 1, 2, 3, 4 }; - byte[] bytesReversed = { 4, 3, 2, 1 }; - - ByteBuf buf1 = newBuffer(4).clear().writeBytes(bytes).order(ByteOrder.LITTLE_ENDIAN); - ByteBuf buf2 = newBuffer(4).clear().writeBytes(bytesReversed).order(ByteOrder.LITTLE_ENDIAN); - ByteBuf buf3 = newBuffer(4).clear().writeBytes(bytes).order(ByteOrder.BIG_ENDIAN); - ByteBuf buf4 = newBuffer(4).clear().writeBytes(bytesReversed).order(ByteOrder.BIG_ENDIAN); - try { - assertEquals(buf1.compareTo(buf2), buf3.compareTo(buf4)); - assertEquals(buf2.compareTo(buf1), buf4.compareTo(buf3)); - assertEquals(buf1.compareTo(buf3), buf2.compareTo(buf4)); - assertEquals(buf3.compareTo(buf1), buf4.compareTo(buf2)); - } finally { - buf1.release(); - buf2.release(); - buf3.release(); - buf4.release(); - } - } - - @Test(groups = "unit") - public void testToString() { - ByteBuf copied = copiedBuffer("Hello, World!", CharsetUtil.ISO_8859_1); - buffer.clear(); - buffer.writeBytes(copied); - assertEquals("Hello, World!", buffer.toString(CharsetUtil.ISO_8859_1)); - copied.release(); - } - - @Test(groups = "unit", timeOut = 10000) - public void testToStringMultipleThreads() throws Throwable { - buffer.clear(); - buffer.writeBytes("Hello, World!".getBytes(CharsetUtil.ISO_8859_1)); - - final AtomicInteger counter = new AtomicInteger(30000); - final AtomicReference errorRef = new AtomicReference(); - List threads = new ArrayList(); - for (int i = 0; i < 10; i++) { - Thread thread = new Thread(new Runnable() { - @Override - public void run() { - try { - while (errorRef.get() == null && counter.decrementAndGet() > 0) { - assertEquals("Hello, World!", buffer.toString(CharsetUtil.ISO_8859_1)); - } - } catch (Throwable cause) { - errorRef.compareAndSet(null, cause); - } - } - }); - threads.add(thread); - } - for (Thread thread: threads) { - thread.start(); - } - - for (Thread thread: threads) { - thread.join(); - } - - Throwable error = errorRef.get(); - if (error != null) { - throw error; - } - } - - @Test(groups = "unit") - public void testIndexOf() { - buffer.clear(); - buffer.writeByte((byte) 1); - buffer.writeByte((byte) 2); - buffer.writeByte((byte) 3); - buffer.writeByte((byte) 2); - buffer.writeByte((byte) 1); - - assertEquals(-1, buffer.indexOf(1, 4, (byte) 1)); - assertEquals(-1, buffer.indexOf(4, 1, (byte) 1)); - assertEquals(1, buffer.indexOf(1, 4, (byte) 2)); - assertEquals(3, buffer.indexOf(4, 1, (byte) 2)); - } - - @Test(groups = "unit") - public void testNioBuffer1() { - assumeTrue(buffer.nioBufferCount() == 1); - - byte[] value = new byte[buffer.capacity()]; - random.nextBytes(value); - buffer.clear(); - buffer.writeBytes(value); - - assertRemainingEquals(ByteBuffer.wrap(value), buffer.nioBuffer()); - } - - @Test(groups = "unit") - public void testToByteBuffer2() { - assumeTrue(buffer.nioBufferCount() == 1); - - byte[] value = new byte[buffer.capacity()]; - random.nextBytes(value); - buffer.clear(); - buffer.writeBytes(value); - - for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) { - assertRemainingEquals(ByteBuffer.wrap(value, i, BLOCK_SIZE), buffer.nioBuffer(i, BLOCK_SIZE)); - } - } - - private static void assertRemainingEquals(ByteBuffer expected, ByteBuffer actual) { - int remaining = expected.remaining(); - int remaining2 = actual.remaining(); - - assertEquals(remaining, remaining2); - byte[] array1 = new byte[remaining]; - byte[] array2 = new byte[remaining2]; - expected.get(array1); - actual.get(array2); - assertEquals(array1, array2); - } - - @Test(groups = "unit") - public void testToByteBuffer3() { - assumeTrue(buffer.nioBufferCount() == 1); - - assertEquals(buffer.order(), buffer.nioBuffer().order()); - } - - @Test(groups = "unit") - public void testSkipBytes1() { - buffer.setIndex(CAPACITY / 4, CAPACITY / 2); - - buffer.skipBytes(CAPACITY / 4); - assertEquals(CAPACITY / 4 * 2, buffer.readerIndex()); - - try { - buffer.skipBytes(CAPACITY / 4 + 1); - fail(); - } catch (IndexOutOfBoundsException e) { - // Expected - } - - // Should remain unchanged. - assertEquals(CAPACITY / 4 * 2, buffer.readerIndex()); - } - - @Test(groups = "unit") - public void testHashCode() { - ByteBuf elemA = buffer(15); - ByteBuf elemB = directBuffer(15); - elemA.writeBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }); - elemB.writeBytes(new byte[] { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9 }); - - Set set = new HashSet(); - set.add(elemA); - set.add(elemB); - - assertEquals(2, set.size()); - ByteBuf elemACopy = elemA.copy(); - assertTrue(set.contains(elemACopy)); - - ByteBuf elemBCopy = elemB.copy(); - assertTrue(set.contains(elemBCopy)); - - buffer.clear(); - buffer.writeBytes(elemA.duplicate()); - - assertTrue(set.remove(buffer)); - assertFalse(set.contains(elemA)); - assertEquals(1, set.size()); - - buffer.clear(); - buffer.writeBytes(elemB.duplicate()); - assertTrue(set.remove(buffer)); - assertFalse(set.contains(elemB)); - assertEquals(0, set.size()); - elemA.release(); - elemB.release(); - elemACopy.release(); - elemBCopy.release(); - } - - // Test case for https://github.com/netty/netty/issues/325 - @Test(groups = "unit") - public void testDiscardAllReadBytes() { - buffer.writerIndex(buffer.capacity()); - buffer.readerIndex(buffer.writerIndex()); - buffer.discardReadBytes(); - } - - @Test(groups = "unit") - public void testForEachByte() { - buffer.clear(); - for (int i = 0; i < CAPACITY; i++) { - buffer.writeByte(i + 1); - } - - final AtomicInteger lastIndex = new AtomicInteger(); - buffer.setIndex(CAPACITY / 4, CAPACITY * 3 / 4); - assertEquals(buffer.forEachByte(new ByteProcessor() { - int i = CAPACITY / 4; - - @Override - public boolean process(byte value) throws Exception { - assertEquals(value, (byte) (i + 1)); - lastIndex.set(i); - i++; - return true; - } - }), -1); - - assertEquals(lastIndex.get(), CAPACITY * 3 / 4 - 1); - } - - @Test(groups = "unit") - public void testForEachByteAbort() { - buffer.clear(); - for (int i = 0; i < CAPACITY; i++) { - buffer.writeByte(i + 1); - } - - final int stop = CAPACITY / 2; - assertEquals(buffer.forEachByte(CAPACITY / 3, CAPACITY / 3, new ByteProcessor() { - int i = CAPACITY / 3; - - @Override - public boolean process(byte value) throws Exception { - assertEquals(value, (byte) (i + 1)); - if (i == stop) { - return false; - } - - i++; - return true; - } - }), stop); - } - - @Test(groups = "unit") - public void testForEachByteDesc() { - buffer.clear(); - for (int i = 0; i < CAPACITY; i++) { - buffer.writeByte(i + 1); - } - - final AtomicInteger lastIndex = new AtomicInteger(); - assertEquals(buffer.forEachByteDesc(CAPACITY / 4, CAPACITY * 2 / 4, new ByteProcessor() { - int i = CAPACITY * 3 / 4 - 1; - - @Override - public boolean process(byte value) throws Exception { - assertEquals(value, (byte) (i + 1)); - lastIndex.set(i); - i--; - return true; - } - }), -1); - - assertEquals(lastIndex.get(), CAPACITY / 4); - } - - @Test(groups = "unit") - public void testInternalNioBuffer() { - testInternalNioBuffer(128); - testInternalNioBuffer(1024); - testInternalNioBuffer(4 * 1024); - testInternalNioBuffer(64 * 1024); - testInternalNioBuffer(32 * 1024 * 1024); - testInternalNioBuffer(64 * 1024 * 1024); - } - - private void testInternalNioBuffer(int a) { - ByteBuf buffer = newBuffer(2); - ByteBuffer buf = buffer.internalNioBuffer(buffer.readerIndex(), 1); - assertEquals(1, buf.remaining()); - - byte[] data = new byte[a]; - PlatformDependent.threadLocalRandom().nextBytes(data); - buffer.writeBytes(data); - - buf = buffer.internalNioBuffer(buffer.readerIndex(), a); - assertEquals(a, buf.remaining()); - - for (int i = 0; i < a; i++) { - assertEquals(data[i], buf.get()); - } - assertFalse(buf.hasRemaining()); - buffer.release(); - } - - @Test(groups = "unit") - public void testDuplicateReadGatheringByteChannelMultipleThreads() throws Exception { - testReadGatheringByteChannelMultipleThreads(false); - } - - @Test(groups = "unit") - public void testSliceReadGatheringByteChannelMultipleThreads() throws Exception { - testReadGatheringByteChannelMultipleThreads(true); - } - - private void testReadGatheringByteChannelMultipleThreads(final boolean slice) throws Exception { - final byte[] bytes = new byte[8]; - random.nextBytes(bytes); - - final ByteBuf buffer = newBuffer(8); - buffer.writeBytes(bytes); - final CountDownLatch latch = new CountDownLatch(60000); - final CyclicBarrier barrier = new CyclicBarrier(11); - for (int i = 0; i < 10; i++) { - new Thread(new Runnable() { - @Override - public void run() { - while (latch.getCount() > 0) { - ByteBuf buf; - if (slice) { - buf = buffer.slice(); - } else { - buf = buffer.duplicate(); - } - TestGatheringByteChannel channel = new TestGatheringByteChannel(); - - while (buf.isReadable()) { - try { - buf.readBytes(channel, buf.readableBytes()); - } catch (IOException e) { - // Never happens - return; - } - } - assertEquals(bytes, channel.writtenBytes()); - latch.countDown(); - } - try { - barrier.await(); - } catch (Exception e) { - // ignore - } - } - }).start(); - } - latch.await(10, TimeUnit.SECONDS); - barrier.await(5, TimeUnit.SECONDS); - buffer.release(); - } - - @Test(groups = "unit") - public void testDuplicateReadOutputStreamMultipleThreads() throws Exception { - testReadOutputStreamMultipleThreads(false); - } - - @Test(groups = "unit") - public void testSliceReadOutputStreamMultipleThreads() throws Exception { - testReadOutputStreamMultipleThreads(true); - } - - private void testReadOutputStreamMultipleThreads(final boolean slice) throws Exception { - final byte[] bytes = new byte[8]; - random.nextBytes(bytes); - - final ByteBuf buffer = newBuffer(8); - buffer.writeBytes(bytes); - final CountDownLatch latch = new CountDownLatch(60000); - final CyclicBarrier barrier = new CyclicBarrier(11); - for (int i = 0; i < 10; i++) { - new Thread(new Runnable() { - @Override - public void run() { - while (latch.getCount() > 0) { - ByteBuf buf; - if (slice) { - buf = buffer.slice(); - } else { - buf = buffer.duplicate(); - } - ByteArrayOutputStream out = new ByteArrayOutputStream(); - - while (buf.isReadable()) { - try { - buf.readBytes(out, buf.readableBytes()); - } catch (IOException e) { - // Never happens - return; - } - } - assertEquals(bytes, out.toByteArray()); - latch.countDown(); - } - try { - barrier.await(); - } catch (Exception e) { - // ignore - } - } - }).start(); - } - latch.await(10, TimeUnit.SECONDS); - barrier.await(5, TimeUnit.SECONDS); - buffer.release(); - } - - @Test(groups = "unit") - public void testDuplicateBytesInArrayMultipleThreads() throws Exception { - testBytesInArrayMultipleThreads(false); - } - - @Test(groups = "unit") - public void testSliceBytesInArrayMultipleThreads() throws Exception { - testBytesInArrayMultipleThreads(true); - } - - private void testBytesInArrayMultipleThreads(final boolean slice) throws Exception { - final byte[] bytes = new byte[8]; - random.nextBytes(bytes); - - final ByteBuf buffer = newBuffer(8); - buffer.writeBytes(bytes); - final AtomicReference cause = new AtomicReference(); - final CountDownLatch latch = new CountDownLatch(60000); - final CyclicBarrier barrier = new CyclicBarrier(11); - for (int i = 0; i < 10; i++) { - new Thread(new Runnable() { - @Override - public void run() { - while (cause.get() == null && latch.getCount() > 0) { - ByteBuf buf; - if (slice) { - buf = buffer.slice(); - } else { - buf = buffer.duplicate(); - } - - byte[] array = new byte[8]; - buf.readBytes(array); - - assertEquals(bytes, array); - - Arrays.fill(array, (byte) 0); - buf.getBytes(0, array); - assertEquals(bytes, array); - - latch.countDown(); - } - try { - barrier.await(); - } catch (Exception e) { - // ignore - } - } - }).start(); - } - latch.await(10, TimeUnit.SECONDS); - barrier.await(5, TimeUnit.SECONDS); - assertNull(cause.get()); - buffer.release(); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void readByteThrowsIndexOutOfBoundsException() { - final ByteBuf buffer = newBuffer(8); - try { - buffer.writeByte(0); - assertEquals((byte) 0, buffer.readByte()); - buffer.readByte(); - } finally { - buffer.release(); - } - } - - @Test(groups = "unit") - @SuppressWarnings("ForLoopThatDoesntUseLoopVariable") - public void testNioBufferExposeOnlyRegion() { - final ByteBuf buffer = newBuffer(8); - byte[] data = new byte[8]; - random.nextBytes(data); - buffer.writeBytes(data); - - ByteBuffer nioBuf = buffer.nioBuffer(1, data.length - 2); - assertEquals(0, nioBuf.position()); - assertEquals(6, nioBuf.remaining()); - - for (int i = 1; nioBuf.hasRemaining(); i++) { - assertEquals(data[i], nioBuf.get()); - } - buffer.release(); - } - - @Test(groups = "unit") - public void ensureWritableWithForceDoesNotThrow() { - ensureWritableDoesNotThrow(true); - } - - @Test(groups = "unit") - public void ensureWritableWithOutForceDoesNotThrow() { - ensureWritableDoesNotThrow(false); - } - - private void ensureWritableDoesNotThrow(boolean force) { - final ByteBuf buffer = newBuffer(8); - buffer.writerIndex(buffer.capacity()); - buffer.ensureWritable(8, force); - buffer.release(); - } - - // See: - // - https://github.com/netty/netty/issues/2587 - // - https://github.com/netty/netty/issues/2580 - @Test(groups = "unit") - public void testLittleEndianWithExpand() { - ByteBuf buffer = newBuffer(0).order(LITTLE_ENDIAN); - buffer.writeInt(0x12345678); - assertEquals("78563412", ByteBufUtil.hexDump(buffer)); - buffer.release(); - } - - private ByteBuf releasedBuffer() { - ByteBuf buffer = newBuffer(8); - - // Clear the buffer so we are sure the reader and writer indices are 0. - // This is important as we may return a slice from newBuffer(...). - buffer.clear(); - assertTrue(buffer.release()); - return buffer; - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testDiscardReadBytesAfterRelease() { - releasedBuffer().discardReadBytes(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testDiscardSomeReadBytesAfterRelease() { - releasedBuffer().discardSomeReadBytes(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testEnsureWritableAfterRelease() { - releasedBuffer().ensureWritable(16); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetBooleanAfterRelease() { - releasedBuffer().getBoolean(0); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetByteAfterRelease() { - releasedBuffer().getByte(0); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetUnsignedByteAfterRelease() { - releasedBuffer().getUnsignedByte(0); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetShortAfterRelease() { - releasedBuffer().getShort(0); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetShortLEAfterRelease() { - releasedBuffer().getShortLE(0); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetUnsignedShortAfterRelease() { - releasedBuffer().getUnsignedShort(0); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetUnsignedShortLEAfterRelease() { - releasedBuffer().getUnsignedShortLE(0); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetMediumAfterRelease() { - releasedBuffer().getMedium(0); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetMediumLEAfterRelease() { - releasedBuffer().getMediumLE(0); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetUnsignedMediumAfterRelease() { - releasedBuffer().getUnsignedMedium(0); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetIntAfterRelease() { - releasedBuffer().getInt(0); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetIntLEAfterRelease() { - releasedBuffer().getIntLE(0); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetUnsignedIntAfterRelease() { - releasedBuffer().getUnsignedInt(0); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetUnsignedIntLEAfterRelease() { - releasedBuffer().getUnsignedIntLE(0); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetLongAfterRelease() { - releasedBuffer().getLong(0); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetLongLEAfterRelease() { - releasedBuffer().getLongLE(0); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetCharAfterRelease() { - releasedBuffer().getChar(0); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetFloatAfterRelease() { - releasedBuffer().getFloat(0); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetFloatLEAfterRelease() { - releasedBuffer().getFloatLE(0); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetDoubleAfterRelease() { - releasedBuffer().getDouble(0); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetDoubleLEAfterRelease() { - releasedBuffer().getDoubleLE(0); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetBytesAfterRelease() { - ByteBuf buffer = buffer(8); - try { - releasedBuffer().getBytes(0, buffer); - } finally { - buffer.release(); - } - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetBytesAfterRelease2() { - ByteBuf buffer = buffer(); - try { - releasedBuffer().getBytes(0, buffer, 1); - } finally { - buffer.release(); - } - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetBytesAfterRelease3() { - ByteBuf buffer = buffer(); - try { - releasedBuffer().getBytes(0, buffer, 0, 1); - } finally { - buffer.release(); - } - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetBytesAfterRelease4() { - releasedBuffer().getBytes(0, new byte[8]); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetBytesAfterRelease5() { - releasedBuffer().getBytes(0, new byte[8], 0, 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetBytesAfterRelease6() { - releasedBuffer().getBytes(0, ByteBuffer.allocate(8)); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetBytesAfterRelease7() throws IOException { - releasedBuffer().getBytes(0, new ByteArrayOutputStream(), 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testGetBytesAfterRelease8() throws IOException { - releasedBuffer().getBytes(0, new DevNullGatheringByteChannel(), 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSetBooleanAfterRelease() { - releasedBuffer().setBoolean(0, true); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSetByteAfterRelease() { - releasedBuffer().setByte(0, 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSetShortAfterRelease() { - releasedBuffer().setShort(0, 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSetShortLEAfterRelease() { - releasedBuffer().setShortLE(0, 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSetMediumAfterRelease() { - releasedBuffer().setMedium(0, 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSetMediumLEAfterRelease() { - releasedBuffer().setMediumLE(0, 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSetIntAfterRelease() { - releasedBuffer().setInt(0, 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSetIntLEAfterRelease() { - releasedBuffer().setIntLE(0, 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSetLongAfterRelease() { - releasedBuffer().setLong(0, 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSetLongLEAfterRelease() { - releasedBuffer().setLongLE(0, 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSetCharAfterRelease() { - releasedBuffer().setChar(0, 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSetFloatAfterRelease() { - releasedBuffer().setFloat(0, 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSetDoubleAfterRelease() { - releasedBuffer().setDouble(0, 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSetBytesAfterRelease() { - ByteBuf buffer = buffer(); - try { - releasedBuffer().setBytes(0, buffer); - } finally { - buffer.release(); - } - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSetBytesAfterRelease2() { - ByteBuf buffer = buffer(); - try { - releasedBuffer().setBytes(0, buffer, 1); - } finally { - buffer.release(); - } - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSetBytesAfterRelease3() { - ByteBuf buffer = buffer(); - try { - releasedBuffer().setBytes(0, buffer, 0, 1); - } finally { - buffer.release(); - } - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSetUsAsciiCharSequenceAfterRelease() { - testSetCharSequenceAfterRelease0(CharsetUtil.US_ASCII); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSetIso88591CharSequenceAfterRelease() { - testSetCharSequenceAfterRelease0(CharsetUtil.ISO_8859_1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSetUtf8CharSequenceAfterRelease() { - testSetCharSequenceAfterRelease0(CharsetUtil.UTF_8); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSetUtf16CharSequenceAfterRelease() { - testSetCharSequenceAfterRelease0(CharsetUtil.UTF_16); - } - - private void testSetCharSequenceAfterRelease0(Charset charset) { - releasedBuffer().setCharSequence(0, "x", charset); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSetBytesAfterRelease4() { - releasedBuffer().setBytes(0, new byte[8]); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSetBytesAfterRelease5() { - releasedBuffer().setBytes(0, new byte[8], 0, 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSetBytesAfterRelease6() { - releasedBuffer().setBytes(0, ByteBuffer.allocate(8)); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSetBytesAfterRelease7() throws IOException { - releasedBuffer().setBytes(0, new ByteArrayInputStream(new byte[8]), 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSetBytesAfterRelease8() throws IOException { - releasedBuffer().setBytes(0, new TestScatteringByteChannel(), 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSetZeroAfterRelease() { - releasedBuffer().setZero(0, 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadBooleanAfterRelease() { - releasedBuffer().readBoolean(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadByteAfterRelease() { - releasedBuffer().readByte(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadUnsignedByteAfterRelease() { - releasedBuffer().readUnsignedByte(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadShortAfterRelease() { - releasedBuffer().readShort(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadShortLEAfterRelease() { - releasedBuffer().readShortLE(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadUnsignedShortAfterRelease() { - releasedBuffer().readUnsignedShort(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadUnsignedShortLEAfterRelease() { - releasedBuffer().readUnsignedShortLE(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadMediumAfterRelease() { - releasedBuffer().readMedium(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadMediumLEAfterRelease() { - releasedBuffer().readMediumLE(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadUnsignedMediumAfterRelease() { - releasedBuffer().readUnsignedMedium(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadUnsignedMediumLEAfterRelease() { - releasedBuffer().readUnsignedMediumLE(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadIntAfterRelease() { - releasedBuffer().readInt(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadIntLEAfterRelease() { - releasedBuffer().readIntLE(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadUnsignedIntAfterRelease() { - releasedBuffer().readUnsignedInt(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadUnsignedIntLEAfterRelease() { - releasedBuffer().readUnsignedIntLE(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadLongAfterRelease() { - releasedBuffer().readLong(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadLongLEAfterRelease() { - releasedBuffer().readLongLE(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadCharAfterRelease() { - releasedBuffer().readChar(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadFloatAfterRelease() { - releasedBuffer().readFloat(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadFloatLEAfterRelease() { - releasedBuffer().readFloatLE(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadDoubleAfterRelease() { - releasedBuffer().readDouble(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadDoubleLEAfterRelease() { - releasedBuffer().readDoubleLE(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadBytesAfterRelease() { - releasedBuffer().readBytes(1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadBytesAfterRelease2() { - ByteBuf buffer = buffer(8); - try { - releasedBuffer().readBytes(buffer); - } finally { - buffer.release(); - } - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadBytesAfterRelease3() { - ByteBuf buffer = buffer(8); - try { - releasedBuffer().readBytes(buffer); - } finally { - buffer.release(); - } - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadBytesAfterRelease4() { - ByteBuf buffer = buffer(8); - try { - releasedBuffer().readBytes(buffer, 0, 1); - } finally { - buffer.release(); - } - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadBytesAfterRelease5() { - releasedBuffer().readBytes(new byte[8]); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadBytesAfterRelease6() { - releasedBuffer().readBytes(new byte[8], 0, 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadBytesAfterRelease7() { - releasedBuffer().readBytes(ByteBuffer.allocate(8)); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadBytesAfterRelease8() throws IOException { - releasedBuffer().readBytes(new ByteArrayOutputStream(), 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadBytesAfterRelease9() throws IOException { - releasedBuffer().readBytes(new ByteArrayOutputStream(), 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testReadBytesAfterRelease10() throws IOException { - releasedBuffer().readBytes(new DevNullGatheringByteChannel(), 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteBooleanAfterRelease() { - releasedBuffer().writeBoolean(true); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteByteAfterRelease() { - releasedBuffer().writeByte(1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteShortAfterRelease() { - releasedBuffer().writeShort(1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteShortLEAfterRelease() { - releasedBuffer().writeShortLE(1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteMediumAfterRelease() { - releasedBuffer().writeMedium(1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteMediumLEAfterRelease() { - releasedBuffer().writeMediumLE(1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteIntAfterRelease() { - releasedBuffer().writeInt(1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteIntLEAfterRelease() { - releasedBuffer().writeIntLE(1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteLongAfterRelease() { - releasedBuffer().writeLong(1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteLongLEAfterRelease() { - releasedBuffer().writeLongLE(1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteCharAfterRelease() { - releasedBuffer().writeChar(1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteFloatAfterRelease() { - releasedBuffer().writeFloat(1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteFloatLEAfterRelease() { - releasedBuffer().writeFloatLE(1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteDoubleAfterRelease() { - releasedBuffer().writeDouble(1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteDoubleLEAfterRelease() { - releasedBuffer().writeDoubleLE(1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteBytesAfterRelease() { - ByteBuf buffer = buffer(8); - try { - releasedBuffer().writeBytes(buffer); - } finally { - buffer.release(); - } - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteBytesAfterRelease2() { - ByteBuf buffer = copiedBuffer(new byte[8]); - try { - releasedBuffer().writeBytes(buffer, 1); - } finally { - buffer.release(); - } - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteBytesAfterRelease3() { - ByteBuf buffer = buffer(8); - try { - releasedBuffer().writeBytes(buffer, 0, 1); - } finally { - buffer.release(); - } - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteBytesAfterRelease4() { - releasedBuffer().writeBytes(new byte[8]); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteBytesAfterRelease5() { - releasedBuffer().writeBytes(new byte[8], 0, 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteBytesAfterRelease6() { - releasedBuffer().writeBytes(ByteBuffer.allocate(8)); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteBytesAfterRelease7() throws IOException { - releasedBuffer().writeBytes(new ByteArrayInputStream(new byte[8]), 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteBytesAfterRelease8() throws IOException { - releasedBuffer().writeBytes(new TestScatteringByteChannel(), 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteZeroAfterRelease() throws IOException { - releasedBuffer().writeZero(1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteUsAsciiCharSequenceAfterRelease() { - testWriteCharSequenceAfterRelease0(CharsetUtil.US_ASCII); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteIso88591CharSequenceAfterRelease() { - testWriteCharSequenceAfterRelease0(CharsetUtil.ISO_8859_1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteUtf8CharSequenceAfterRelease() { - testWriteCharSequenceAfterRelease0(CharsetUtil.UTF_8); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testWriteUtf16CharSequenceAfterRelease() { - testWriteCharSequenceAfterRelease0(CharsetUtil.UTF_16); - } - - private void testWriteCharSequenceAfterRelease0(Charset charset) { - releasedBuffer().writeCharSequence("x", charset); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testForEachByteAfterRelease() { - releasedBuffer().forEachByte(new TestByteProcessor()); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testForEachByteAfterRelease1() { - releasedBuffer().forEachByte(0, 1, new TestByteProcessor()); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testForEachByteDescAfterRelease() { - releasedBuffer().forEachByteDesc(new TestByteProcessor()); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testForEachByteDescAfterRelease1() { - releasedBuffer().forEachByteDesc(0, 1, new TestByteProcessor()); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testCopyAfterRelease() { - releasedBuffer().copy(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testCopyAfterRelease1() { - releasedBuffer().copy(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testNioBufferAfterRelease() { - releasedBuffer().nioBuffer(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testNioBufferAfterRelease1() { - releasedBuffer().nioBuffer(0, 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testInternalNioBufferAfterRelease() { - ByteBuf releasedBuffer = releasedBuffer(); - releasedBuffer.internalNioBuffer(releasedBuffer.readerIndex(), 1); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testNioBuffersAfterRelease() { - releasedBuffer().nioBuffers(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testNioBuffersAfterRelease2() { - releasedBuffer().nioBuffers(0, 1); - } - - @Test(groups = "unit") - public void testArrayAfterRelease() { - ByteBuf buf = releasedBuffer(); - if (buf.hasArray()) { - try { - buf.array(); - fail(); - } catch (IllegalReferenceCountException e) { - // expected - } - } - } - - @Test(groups = "unit") - public void testMemoryAddressAfterRelease() { - ByteBuf buf = releasedBuffer(); - if (buf.hasMemoryAddress()) { - try { - buf.memoryAddress(); - fail(); - } catch (IllegalReferenceCountException e) { - // expected - } - } - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSliceAfterRelease() { - releasedBuffer().slice(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testSliceAfterRelease2() { - releasedBuffer().slice(0, 1); - } - - private static void assertSliceFailAfterRelease(ByteBuf... bufs) { - for (ByteBuf buf: bufs) { - if (buf.refCnt() > 0) { - buf.release(); - } - } - for (ByteBuf buf: bufs) { - try { - assertEquals(0, buf.refCnt()); - buf.slice(); - fail(); - } catch (IllegalReferenceCountException ignored) { - // as expected - } - } - } - - @Test(groups = "unit") - public void testSliceAfterReleaseRetainedSlice() { - ByteBuf buf = newBuffer(1); - ByteBuf buf2 = buf.retainedSlice(0, 1); - assertSliceFailAfterRelease(buf, buf2); - } - - @Test(groups = "unit") - public void testSliceAfterReleaseRetainedSliceDuplicate() { - ByteBuf buf = newBuffer(1); - ByteBuf buf2 = buf.retainedSlice(0, 1); - ByteBuf buf3 = buf2.duplicate(); - assertSliceFailAfterRelease(buf, buf2, buf3); - } - - @Test(groups = "unit") - public void testSliceAfterReleaseRetainedSliceRetainedDuplicate() { - ByteBuf buf = newBuffer(1); - ByteBuf buf2 = buf.retainedSlice(0, 1); - ByteBuf buf3 = buf2.retainedDuplicate(); - assertSliceFailAfterRelease(buf, buf2, buf3); - } - - @Test(groups = "unit") - public void testSliceAfterReleaseRetainedDuplicate() { - ByteBuf buf = newBuffer(1); - ByteBuf buf2 = buf.retainedDuplicate(); - assertSliceFailAfterRelease(buf, buf2); - } - - @Test(groups = "unit") - public void testSliceAfterReleaseRetainedDuplicateSlice() { - ByteBuf buf = newBuffer(1); - ByteBuf buf2 = buf.retainedDuplicate(); - ByteBuf buf3 = buf2.slice(0, 1); - assertSliceFailAfterRelease(buf, buf2, buf3); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testRetainedSliceAfterRelease() { - releasedBuffer().retainedSlice(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testRetainedSliceAfterRelease2() { - releasedBuffer().retainedSlice(0, 1); - } - - private static void assertRetainedSliceFailAfterRelease(ByteBuf... bufs) { - for (ByteBuf buf: bufs) { - if (buf.refCnt() > 0) { - buf.release(); - } - } - for (ByteBuf buf: bufs) { - try { - assertEquals(0, buf.refCnt()); - buf.retainedSlice(); - fail(); - } catch (IllegalReferenceCountException ignored) { - // as expected - } - } - } - - @Test(groups = "unit") - public void testRetainedSliceAfterReleaseRetainedSlice() { - ByteBuf buf = newBuffer(1); - ByteBuf buf2 = buf.retainedSlice(0, 1); - assertRetainedSliceFailAfterRelease(buf, buf2); - } - - @Test(groups = "unit") - public void testRetainedSliceAfterReleaseRetainedSliceDuplicate() { - ByteBuf buf = newBuffer(1); - ByteBuf buf2 = buf.retainedSlice(0, 1); - ByteBuf buf3 = buf2.duplicate(); - assertRetainedSliceFailAfterRelease(buf, buf2, buf3); - } - - @Test(groups = "unit") - public void testRetainedSliceAfterReleaseRetainedSliceRetainedDuplicate() { - ByteBuf buf = newBuffer(1); - ByteBuf buf2 = buf.retainedSlice(0, 1); - ByteBuf buf3 = buf2.retainedDuplicate(); - assertRetainedSliceFailAfterRelease(buf, buf2, buf3); - } - - @Test(groups = "unit") - public void testRetainedSliceAfterReleaseRetainedDuplicate() { - ByteBuf buf = newBuffer(1); - ByteBuf buf2 = buf.retainedDuplicate(); - assertRetainedSliceFailAfterRelease(buf, buf2); - } - - @Test(groups = "unit") - public void testRetainedSliceAfterReleaseRetainedDuplicateSlice() { - ByteBuf buf = newBuffer(1); - ByteBuf buf2 = buf.retainedDuplicate(); - ByteBuf buf3 = buf2.slice(0, 1); - assertRetainedSliceFailAfterRelease(buf, buf2, buf3); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testDuplicateAfterRelease() { - releasedBuffer().duplicate(); - } - - @Test(groups = "unit", expectedExceptions = IllegalReferenceCountException.class) - public void testRetainedDuplicateAfterRelease() { - releasedBuffer().retainedDuplicate(); - } - - private static void assertDuplicateFailAfterRelease(ByteBuf... bufs) { - for (ByteBuf buf: bufs) { - if (buf.refCnt() > 0) { - buf.release(); - } - } - for (ByteBuf buf: bufs) { - try { - assertEquals(0, buf.refCnt()); - buf.duplicate(); - fail(); - } catch (IllegalReferenceCountException ignored) { - // as expected - } - } - } - - @Test(groups = "unit") - public void testDuplicateAfterReleaseRetainedSliceDuplicate() { - ByteBuf buf = newBuffer(1); - ByteBuf buf2 = buf.retainedSlice(0, 1); - ByteBuf buf3 = buf2.duplicate(); - assertDuplicateFailAfterRelease(buf, buf2, buf3); - } - - @Test(groups = "unit") - public void testDuplicateAfterReleaseRetainedDuplicate() { - ByteBuf buf = newBuffer(1); - ByteBuf buf2 = buf.retainedDuplicate(); - assertDuplicateFailAfterRelease(buf, buf2); - } - - @Test(groups = "unit") - public void testDuplicateAfterReleaseRetainedDuplicateSlice() { - ByteBuf buf = newBuffer(1); - ByteBuf buf2 = buf.retainedDuplicate(); - ByteBuf buf3 = buf2.slice(0, 1); - assertDuplicateFailAfterRelease(buf, buf2, buf3); - } - - private static void assertRetainedDuplicateFailAfterRelease(ByteBuf... bufs) { - for (ByteBuf buf: bufs) { - if (buf.refCnt() > 0) { - buf.release(); - } - } - for (ByteBuf buf: bufs) { - try { - assertEquals(0, buf.refCnt()); - buf.retainedDuplicate(); - fail(); - } catch (IllegalReferenceCountException ignored) { - // as expected - } - } - } - - @Test(groups = "unit") - public void testRetainedDuplicateAfterReleaseRetainedDuplicate() { - ByteBuf buf = newBuffer(1); - ByteBuf buf2 = buf.retainedDuplicate(); - assertRetainedDuplicateFailAfterRelease(buf, buf2); - } - - @Test(groups = "unit") - public void testRetainedDuplicateAfterReleaseDuplicate() { - ByteBuf buf = newBuffer(1); - ByteBuf buf2 = buf.duplicate(); - assertRetainedDuplicateFailAfterRelease(buf, buf2); - } - - @Test(groups = "unit") - public void testRetainedDuplicateAfterReleaseRetainedSlice() { - ByteBuf buf = newBuffer(1); - ByteBuf buf2 = buf.retainedSlice(0, 1); - assertRetainedDuplicateFailAfterRelease(buf, buf2); - } - - @Test(groups = "unit") - public void testSliceRelease() { - ByteBuf buf = newBuffer(8); - assertEquals(1, buf.refCnt()); - assertTrue(buf.slice().release()); - assertEquals(0, buf.refCnt()); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void testReadSliceOutOfBounds() { - testReadSliceOutOfBounds(false); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void testReadRetainedSliceOutOfBounds() { - testReadSliceOutOfBounds(true); - } - - private void testReadSliceOutOfBounds(boolean retainedSlice) { - ByteBuf buf = newBuffer(100); - try { - buf.writeZero(50); - if (retainedSlice) { - buf.readRetainedSlice(51); - } else { - buf.readSlice(51); - } - fail(); - } finally { - buf.release(); - } - } - - @Test(groups = "unit") - public void testWriteUsAsciiCharSequenceExpand() { - testWriteCharSequenceExpand(CharsetUtil.US_ASCII); - } - - @Test(groups = "unit") - public void testWriteUtf8CharSequenceExpand() { - testWriteCharSequenceExpand(CharsetUtil.UTF_8); - } - - @Test(groups = "unit") - public void testWriteIso88591CharSequenceExpand() { - testWriteCharSequenceExpand(CharsetUtil.ISO_8859_1); - } - - @Test(groups = "unit") - public void testWriteUtf16CharSequenceExpand() { - testWriteCharSequenceExpand(CharsetUtil.UTF_16); - } - - private void testWriteCharSequenceExpand(Charset charset) { - ByteBuf buf = newBuffer(1); - try { - int writerIndex = buf.capacity() - 1; - buf.writerIndex(writerIndex); - int written = buf.writeCharSequence("AB", charset); - assertEquals(writerIndex, buf.writerIndex() - written); - } finally { - buf.release(); - } - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void testSetUsAsciiCharSequenceNoExpand() { - testSetCharSequenceNoExpand(CharsetUtil.US_ASCII); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void testSetUtf8CharSequenceNoExpand() { - testSetCharSequenceNoExpand(CharsetUtil.UTF_8); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void testSetIso88591CharSequenceNoExpand() { - testSetCharSequenceNoExpand(CharsetUtil.ISO_8859_1); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void testSetUtf16CharSequenceNoExpand() { - testSetCharSequenceNoExpand(CharsetUtil.UTF_16); - } - - private void testSetCharSequenceNoExpand(Charset charset) { - ByteBuf buf = newBuffer(1); - try { - buf.setCharSequence(0, "AB", charset); - } finally { - buf.release(); - } - } - - @Test(groups = "unit") - public void testSetUsAsciiCharSequence() { - testSetGetCharSequence(CharsetUtil.US_ASCII); - } - - @Test(groups = "unit") - public void testSetUtf8CharSequence() { - testSetGetCharSequence(CharsetUtil.UTF_8); - } - - @Test(groups = "unit") - public void testSetIso88591CharSequence() { - testSetGetCharSequence(CharsetUtil.ISO_8859_1); - } - - @Test(groups = "unit") - public void testSetUtf16CharSequence() { - testSetGetCharSequence(CharsetUtil.UTF_16); - } - - private void testSetGetCharSequence(Charset charset) { - ByteBuf buf = newBuffer(16); - String sequence = "AB"; - int bytes = buf.setCharSequence(1, sequence, charset); - assertEquals(sequence, buf.getCharSequence(1, bytes, charset).toString()); - buf.release(); - } - - @Test(groups = "unit") - public void testWriteReadUsAsciiCharSequence() { - testWriteReadCharSequence(CharsetUtil.US_ASCII); - } - - @Test(groups = "unit") - public void testWriteReadUtf8CharSequence() { - testWriteReadCharSequence(CharsetUtil.UTF_8); - } - - @Test(groups = "unit") - public void testWriteReadIso88591CharSequence() { - testWriteReadCharSequence(CharsetUtil.ISO_8859_1); - } - - @Test(groups = "unit") - public void testWriteReadUtf16CharSequence() { - testWriteReadCharSequence(CharsetUtil.UTF_16); - } - - private void testWriteReadCharSequence(Charset charset) { - ByteBuf buf = newBuffer(16); - String sequence = "AB"; - buf.writerIndex(1); - int bytes = buf.writeCharSequence(sequence, charset); - buf.readerIndex(1); - assertEquals(sequence, buf.readCharSequence(bytes, charset).toString()); - buf.release(); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void testRetainedSliceIndexOutOfBounds() { - testSliceOutOfBounds(true, true, true); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void testRetainedSliceLengthOutOfBounds() { - testSliceOutOfBounds(true, true, false); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void testMixedSliceAIndexOutOfBounds() { - testSliceOutOfBounds(true, false, true); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void testMixedSliceALengthOutOfBounds() { - testSliceOutOfBounds(true, false, false); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void testMixedSliceBIndexOutOfBounds() { - testSliceOutOfBounds(false, true, true); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void testMixedSliceBLengthOutOfBounds() { - testSliceOutOfBounds(false, true, false); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void testSliceIndexOutOfBounds() { - testSliceOutOfBounds(false, false, true); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void testSliceLengthOutOfBounds() { - testSliceOutOfBounds(false, false, false); - } - - @Test(groups = "unit") - public void testRetainedSliceAndRetainedDuplicateContentIsExpected() { - ByteBuf buf = newBuffer(8).resetWriterIndex(); - ByteBuf expected1 = newBuffer(6).resetWriterIndex(); - ByteBuf expected2 = newBuffer(5).resetWriterIndex(); - ByteBuf expected3 = newBuffer(4).resetWriterIndex(); - ByteBuf expected4 = newBuffer(3).resetWriterIndex(); - buf.writeBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }); - expected1.writeBytes(new byte[] { 2, 3, 4, 5, 6, 7 }); - expected2.writeBytes(new byte[] { 3, 4, 5, 6, 7 }); - expected3.writeBytes(new byte[] { 4, 5, 6, 7 }); - expected4.writeBytes(new byte[] { 5, 6, 7 }); - - ByteBuf slice1 = buf.retainedSlice(buf.readerIndex() + 1, 6); - assertEquals(0, slice1.compareTo(expected1)); - assertEquals(0, slice1.compareTo(buf.slice(buf.readerIndex() + 1, 6))); - // Simulate a handler that releases the original buffer, and propagates a slice. - buf.release(); - - // Advance the reader index on the slice. - slice1.readByte(); - - ByteBuf dup1 = slice1.retainedDuplicate(); - assertEquals(0, dup1.compareTo(expected2)); - assertEquals(0, dup1.compareTo(slice1.duplicate())); - - // Advance the reader index on dup1. - dup1.readByte(); - - ByteBuf dup2 = dup1.duplicate(); - assertEquals(0, dup2.compareTo(expected3)); - - // Advance the reader index on dup2. - dup2.readByte(); - - ByteBuf slice2 = dup2.retainedSlice(dup2.readerIndex(), 3); - assertEquals(0, slice2.compareTo(expected4)); - assertEquals(0, slice2.compareTo(dup2.slice(dup2.readerIndex(), 3))); - - // Cleanup the expected buffers used for testing. - assertTrue(expected1.release()); - assertTrue(expected2.release()); - assertTrue(expected3.release()); - assertTrue(expected4.release()); - - slice2.release(); - dup2.release(); - - assertEquals(slice2.refCnt(), dup2.refCnt()); - assertEquals(dup2.refCnt(), dup1.refCnt()); - - // The handler is now done with the original slice - assertTrue(slice1.release()); - - // Reference counting may be shared, or may be independently tracked, but at this point all buffers should - // be deallocated and have a reference count of 0. - assertEquals(0, buf.refCnt()); - assertEquals(0, slice1.refCnt()); - assertEquals(0, slice2.refCnt()); - assertEquals(0, dup1.refCnt()); - assertEquals(0, dup2.refCnt()); - } - - @Test(groups = "unit") - public void testRetainedDuplicateAndRetainedSliceContentIsExpected() { - ByteBuf buf = newBuffer(8).resetWriterIndex(); - ByteBuf expected1 = newBuffer(6).resetWriterIndex(); - ByteBuf expected2 = newBuffer(5).resetWriterIndex(); - ByteBuf expected3 = newBuffer(4).resetWriterIndex(); - buf.writeBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }); - expected1.writeBytes(new byte[] { 2, 3, 4, 5, 6, 7 }); - expected2.writeBytes(new byte[] { 3, 4, 5, 6, 7 }); - expected3.writeBytes(new byte[] { 5, 6, 7 }); - - ByteBuf dup1 = buf.retainedDuplicate(); - assertEquals(0, dup1.compareTo(buf)); - assertEquals(0, dup1.compareTo(buf.slice())); - // Simulate a handler that releases the original buffer, and propagates a slice. - buf.release(); - - // Advance the reader index on the dup. - dup1.readByte(); - - ByteBuf slice1 = dup1.retainedSlice(dup1.readerIndex(), 6); - assertEquals(0, slice1.compareTo(expected1)); - assertEquals(0, slice1.compareTo(slice1.duplicate())); - - // Advance the reader index on slice1. - slice1.readByte(); - - ByteBuf dup2 = slice1.duplicate(); - assertEquals(0, dup2.compareTo(slice1)); - - // Advance the reader index on dup2. - dup2.readByte(); - - ByteBuf slice2 = dup2.retainedSlice(dup2.readerIndex() + 1, 3); - assertEquals(0, slice2.compareTo(expected3)); - assertEquals(0, slice2.compareTo(dup2.slice(dup2.readerIndex() + 1, 3))); - - // Cleanup the expected buffers used for testing. - assertTrue(expected1.release()); - assertTrue(expected2.release()); - assertTrue(expected3.release()); - - slice2.release(); - slice1.release(); - - assertEquals(slice2.refCnt(), dup2.refCnt()); - assertEquals(dup2.refCnt(), slice1.refCnt()); - - // The handler is now done with the original slice - assertTrue(dup1.release()); - - // Reference counting may be shared, or may be independently tracked, but at this point all buffers should - // be deallocated and have a reference count of 0. - assertEquals(0, buf.refCnt()); - assertEquals(0, slice1.refCnt()); - assertEquals(0, slice2.refCnt()); - assertEquals(0, dup1.refCnt()); - assertEquals(0, dup2.refCnt()); - } - - @Test(groups = "unit") - public void testRetainedSliceContents() { - testSliceContents(true); - } - - @Test(groups = "unit") - public void testMultipleLevelRetainedSlice1() { - testMultipleLevelRetainedSliceWithNonRetained(true, true); - } - - @Test(groups = "unit") - public void testMultipleLevelRetainedSlice2() { - testMultipleLevelRetainedSliceWithNonRetained(true, false); - } - - @Test(groups = "unit") - public void testMultipleLevelRetainedSlice3() { - testMultipleLevelRetainedSliceWithNonRetained(false, true); - } - - @Test(groups = "unit") - public void testMultipleLevelRetainedSlice4() { - testMultipleLevelRetainedSliceWithNonRetained(false, false); - } - - @Test(groups = "unit") - public void testRetainedSliceReleaseOriginal1() { - testSliceReleaseOriginal(true, true); - } - - @Test(groups = "unit") - public void testRetainedSliceReleaseOriginal2() { - testSliceReleaseOriginal(true, false); - } - - @Test(groups = "unit") - public void testRetainedSliceReleaseOriginal3() { - testSliceReleaseOriginal(false, true); - } - - @Test(groups = "unit") - public void testRetainedSliceReleaseOriginal4() { - testSliceReleaseOriginal(false, false); - } - - @Test(groups = "unit") - public void testRetainedDuplicateReleaseOriginal1() { - testDuplicateReleaseOriginal(true, true); - } - - @Test(groups = "unit") - public void testRetainedDuplicateReleaseOriginal2() { - testDuplicateReleaseOriginal(true, false); - } - - @Test(groups = "unit") - public void testRetainedDuplicateReleaseOriginal3() { - testDuplicateReleaseOriginal(false, true); - } - - @Test(groups = "unit") - public void testRetainedDuplicateReleaseOriginal4() { - testDuplicateReleaseOriginal(false, false); - } - - @Test(groups = "unit") - public void testMultipleRetainedSliceReleaseOriginal1() { - testMultipleRetainedSliceReleaseOriginal(true, true); - } - - @Test(groups = "unit") - public void testMultipleRetainedSliceReleaseOriginal2() { - testMultipleRetainedSliceReleaseOriginal(true, false); - } - - @Test(groups = "unit") - public void testMultipleRetainedSliceReleaseOriginal3() { - testMultipleRetainedSliceReleaseOriginal(false, true); - } - - @Test(groups = "unit") - public void testMultipleRetainedSliceReleaseOriginal4() { - testMultipleRetainedSliceReleaseOriginal(false, false); - } - - @Test(groups = "unit") - public void testMultipleRetainedDuplicateReleaseOriginal1() { - testMultipleRetainedDuplicateReleaseOriginal(true, true); - } - - @Test(groups = "unit") - public void testMultipleRetainedDuplicateReleaseOriginal2() { - testMultipleRetainedDuplicateReleaseOriginal(true, false); - } - - @Test(groups = "unit") - public void testMultipleRetainedDuplicateReleaseOriginal3() { - testMultipleRetainedDuplicateReleaseOriginal(false, true); - } - - @Test(groups = "unit") - public void testMultipleRetainedDuplicateReleaseOriginal4() { - testMultipleRetainedDuplicateReleaseOriginal(false, false); - } - - @Test(groups = "unit") - public void testSliceContents() { - testSliceContents(false); - } - - @Test(groups = "unit") - public void testRetainedDuplicateContents() { - testDuplicateContents(true); - } - - @Test(groups = "unit") - public void testDuplicateContents() { - testDuplicateContents(false); - } - - @Test(groups = "unit", enabled = false) - public void testDuplicateCapacityChange() { - testDuplicateCapacityChange(false); - } - - @Test(groups = "unit", enabled = false) - public void testRetainedDuplicateCapacityChange() { - testDuplicateCapacityChange(true); - } - - @Test(groups = "unit", expectedExceptions = UnsupportedOperationException.class) - public void testSliceCapacityChange() { - testSliceCapacityChange(false); - } - - @Test(groups = "unit", expectedExceptions = UnsupportedOperationException.class) - public void testRetainedSliceCapacityChange() { - testSliceCapacityChange(true); - } - - @Test(groups = "unit") - public void testRetainedSliceUnreleasable1() { - testRetainedSliceUnreleasable(true, true); - } - - @Test(groups = "unit") - public void testRetainedSliceUnreleasable2() { - testRetainedSliceUnreleasable(true, false); - } - - @Test(groups = "unit") - public void testRetainedSliceUnreleasable3() { - testRetainedSliceUnreleasable(false, true); - } - - @Test(groups = "unit") - public void testRetainedSliceUnreleasable4() { - testRetainedSliceUnreleasable(false, false); - } - - @Test(groups = "unit") - public void testReadRetainedSliceUnreleasable1() { - testReadRetainedSliceUnreleasable(true, true); - } - - @Test(groups = "unit") - public void testReadRetainedSliceUnreleasable2() { - testReadRetainedSliceUnreleasable(true, false); - } - - @Test(groups = "unit") - public void testReadRetainedSliceUnreleasable3() { - testReadRetainedSliceUnreleasable(false, true); - } - - @Test(groups = "unit") - public void testReadRetainedSliceUnreleasable4() { - testReadRetainedSliceUnreleasable(false, false); - } - - @Test(groups = "unit") - public void testRetainedDuplicateUnreleasable1() { - testRetainedDuplicateUnreleasable(true, true); - } - - @Test(groups = "unit") - public void testRetainedDuplicateUnreleasable2() { - testRetainedDuplicateUnreleasable(true, false); - } - - @Test(groups = "unit") - public void testRetainedDuplicateUnreleasable3() { - testRetainedDuplicateUnreleasable(false, true); - } - - @Test(groups = "unit") - public void testRetainedDuplicateUnreleasable4() { - testRetainedDuplicateUnreleasable(false, false); - } - - private void testRetainedSliceUnreleasable(boolean initRetainedSlice, boolean finalRetainedSlice) { - ByteBuf buf = newBuffer(8); - ByteBuf buf1 = initRetainedSlice ? buf.retainedSlice() : buf.slice().retain(); - ByteBuf buf2 = unreleasableBuffer(buf1); - ByteBuf buf3 = finalRetainedSlice ? buf2.retainedSlice() : buf2.slice().retain(); - assertFalse(buf3.release()); - assertFalse(buf2.release()); - buf1.release(); - assertTrue(buf.release()); - assertEquals(0, buf1.refCnt()); - assertEquals(0, buf.refCnt()); - } - - private void testReadRetainedSliceUnreleasable(boolean initRetainedSlice, boolean finalRetainedSlice) { - ByteBuf buf = newBuffer(8); - ByteBuf buf1 = initRetainedSlice ? buf.retainedSlice() : buf.slice().retain(); - ByteBuf buf2 = unreleasableBuffer(buf1); - ByteBuf buf3 = finalRetainedSlice - ? buf2.readRetainedSlice(buf2.readableBytes()) - : buf2.readSlice(buf2.readableBytes()).retain(); - assertFalse(buf3.release()); - assertFalse(buf2.release()); - buf1.release(); - assertTrue(buf.release()); - assertEquals(0, buf1.refCnt()); - assertEquals(0, buf.refCnt()); - } - - private void testRetainedDuplicateUnreleasable(boolean initRetainedDuplicate, boolean finalRetainedDuplicate) { - ByteBuf buf = newBuffer(8); - ByteBuf buf1 = initRetainedDuplicate ? buf.retainedDuplicate() : buf.duplicate().retain(); - ByteBuf buf2 = unreleasableBuffer(buf1); - ByteBuf buf3 = finalRetainedDuplicate ? buf2.retainedDuplicate() : buf2.duplicate().retain(); - assertFalse(buf3.release()); - assertFalse(buf2.release()); - buf1.release(); - assertTrue(buf.release()); - assertEquals(0, buf1.refCnt()); - assertEquals(0, buf.refCnt()); - } - - private void testDuplicateCapacityChange(boolean retainedDuplicate) { - ByteBuf buf = newBuffer(8); - ByteBuf dup = retainedDuplicate ? buf.retainedDuplicate() : buf.duplicate(); - try { - dup.capacity(10); - assertEquals(buf.capacity(), dup.capacity()); - dup.capacity(5); - assertEquals(buf.capacity(), dup.capacity()); - } finally { - if (retainedDuplicate) { - dup.release(); - } - buf.release(); - } - } - - private void testSliceCapacityChange(boolean retainedSlice) { - ByteBuf buf = newBuffer(8); - ByteBuf slice = retainedSlice ? buf.retainedSlice(buf.readerIndex() + 1, 3) : buf.slice(buf.readerIndex() + 1, 3); - try { - slice.capacity(10); - } finally { - if (retainedSlice) { - slice.release(); - } - buf.release(); - } - } - - private void testSliceOutOfBounds(boolean initRetainedSlice, boolean finalRetainedSlice, boolean indexOutOfBounds) { - ByteBuf buf = newBuffer(8); - ByteBuf slice = - initRetainedSlice ? buf.retainedSlice(buf.readerIndex() + 1, 2) : buf.slice(buf.readerIndex() + 1, 2); - try { - assertEquals(2, slice.capacity()); - assertEquals(2, slice.maxCapacity()); - final int index = indexOutOfBounds ? 3 : 0; - final int length = indexOutOfBounds ? 0 : 3; - if (finalRetainedSlice) { - // This is expected to fail ... so no need to release. - slice.retainedSlice(index, length); - } else { - slice.slice(index, length); - } - } finally { - if (initRetainedSlice) { - slice.release(); - } - buf.release(); - } - } - - private void testSliceContents(boolean retainedSlice) { - ByteBuf buf = newBuffer(8).resetWriterIndex(); - ByteBuf expected = newBuffer(3).resetWriterIndex(); - buf.writeBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }); - expected.writeBytes(new byte[] { 4, 5, 6 }); - ByteBuf slice = retainedSlice ? buf.retainedSlice(buf.readerIndex() + 3, 3) : buf.slice(buf.readerIndex() + 3, 3); - try { - assertEquals(0, slice.compareTo(expected)); - assertEquals(0, slice.compareTo(slice.duplicate())); - ByteBuf b = slice.retainedDuplicate(); - assertEquals(0, slice.compareTo(b)); - b.release(); - assertEquals(0, slice.compareTo(slice.slice(0, slice.capacity()))); - } finally { - if (retainedSlice) { - slice.release(); - } - buf.release(); - expected.release(); - } - } - - private void testSliceReleaseOriginal(boolean retainedSlice1, boolean retainedSlice2) { - ByteBuf buf = newBuffer(8).resetWriterIndex(); - ByteBuf expected1 = newBuffer(3).resetWriterIndex(); - ByteBuf expected2 = newBuffer(2).resetWriterIndex(); - buf.writeBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }); - expected1.writeBytes(new byte[] { 6, 7, 8 }); - expected2.writeBytes(new byte[] { 7, 8 }); - ByteBuf slice1 = - retainedSlice1 ? buf.retainedSlice(buf.readerIndex() + 5, 3) : buf.slice(buf.readerIndex() + 5, 3).retain(); - assertEquals(0, slice1.compareTo(expected1)); - // Simulate a handler that releases the original buffer, and propagates a slice. - buf.release(); - - ByteBuf slice2 = retainedSlice2 - ? slice1.retainedSlice(slice1.readerIndex() + 1, 2) - : slice1.slice(slice1.readerIndex() + 1, 2).retain(); - assertEquals(0, slice2.compareTo(expected2)); - - // Cleanup the expected buffers used for testing. - assertTrue(expected1.release()); - assertTrue(expected2.release()); - - // The handler created a slice of the slice and is now done with it. - slice2.release(); - - // The handler is now done with the original slice - assertTrue(slice1.release()); - - // Reference counting may be shared, or may be independently tracked, but at this point all buffers should - // be deallocated and have a reference count of 0. - assertEquals(0, buf.refCnt()); - assertEquals(0, slice1.refCnt()); - assertEquals(0, slice2.refCnt()); - } - - private void testMultipleLevelRetainedSliceWithNonRetained(boolean doSlice1, boolean doSlice2) { - ByteBuf buf = newBuffer(8).resetWriterIndex(); - ByteBuf expected1 = newBuffer(6).resetWriterIndex(); - ByteBuf expected2 = newBuffer(4).resetWriterIndex(); - ByteBuf expected3 = newBuffer(2).resetWriterIndex(); - ByteBuf expected4SliceSlice = newBuffer(1).resetWriterIndex(); - ByteBuf expected4DupSlice = newBuffer(1).resetWriterIndex(); - buf.writeBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }); - expected1.writeBytes(new byte[] { 2, 3, 4, 5, 6, 7 }); - expected2.writeBytes(new byte[] { 3, 4, 5, 6 }); - expected3.writeBytes(new byte[] { 4, 5 }); - expected4SliceSlice.writeBytes(new byte[] { 5 }); - expected4DupSlice.writeBytes(new byte[] { 4 }); - - ByteBuf slice1 = buf.retainedSlice(buf.readerIndex() + 1, 6); - assertEquals(0, slice1.compareTo(expected1)); - // Simulate a handler that releases the original buffer, and propagates a slice. - buf.release(); - - ByteBuf slice2 = slice1.retainedSlice(slice1.readerIndex() + 1, 4); - assertEquals(0, slice2.compareTo(expected2)); - assertEquals(0, slice2.compareTo(slice2.duplicate())); - assertEquals(0, slice2.compareTo(slice2.slice())); - - ByteBuf tmpBuf = slice2.retainedDuplicate(); - assertEquals(0, slice2.compareTo(tmpBuf)); - tmpBuf.release(); - tmpBuf = slice2.retainedSlice(); - assertEquals(0, slice2.compareTo(tmpBuf)); - tmpBuf.release(); - - ByteBuf slice3 = doSlice1 ? slice2.slice(slice2.readerIndex() + 1, 2) : slice2.duplicate(); - if (doSlice1) { - assertEquals(0, slice3.compareTo(expected3)); - } else { - assertEquals(0, slice3.compareTo(expected2)); - } - - ByteBuf slice4 = doSlice2 ? slice3.slice(slice3.readerIndex() + 1, 1) : slice3.duplicate(); - if (doSlice1 && doSlice2) { - assertEquals(0, slice4.compareTo(expected4SliceSlice)); - } else if (doSlice2) { - assertEquals(0, slice4.compareTo(expected4DupSlice)); - } else { - assertEquals(0, slice3.compareTo(slice4)); - } - - // Cleanup the expected buffers used for testing. - assertTrue(expected1.release()); - assertTrue(expected2.release()); - assertTrue(expected3.release()); - assertTrue(expected4SliceSlice.release()); - assertTrue(expected4DupSlice.release()); - - // Slice 4, 3, and 2 should effectively "share" a reference count. - slice4.release(); - assertEquals(slice3.refCnt(), slice2.refCnt()); - assertEquals(slice3.refCnt(), slice4.refCnt()); - - // Slice 1 should also release the original underlying buffer without throwing exceptions - assertTrue(slice1.release()); - - // Reference counting may be shared, or may be independently tracked, but at this point all buffers should - // be deallocated and have a reference count of 0. - assertEquals(0, buf.refCnt()); - assertEquals(0, slice1.refCnt()); - assertEquals(0, slice2.refCnt()); - assertEquals(0, slice3.refCnt()); - } - - private void testDuplicateReleaseOriginal(boolean retainedDuplicate1, boolean retainedDuplicate2) { - ByteBuf buf = newBuffer(8).resetWriterIndex(); - ByteBuf expected = newBuffer(8).resetWriterIndex(); - buf.writeBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }); - expected.writeBytes(buf, buf.readerIndex(), buf.readableBytes()); - ByteBuf dup1 = retainedDuplicate1 ? buf.retainedDuplicate() : buf.duplicate().retain(); - assertEquals(0, dup1.compareTo(expected)); - // Simulate a handler that releases the original buffer, and propagates a slice. - buf.release(); - - ByteBuf dup2 = retainedDuplicate2 ? dup1.retainedDuplicate() : dup1.duplicate().retain(); - assertEquals(0, dup2.compareTo(expected)); - - // Cleanup the expected buffers used for testing. - assertTrue(expected.release()); - - // The handler created a slice of the slice and is now done with it. - dup2.release(); - - // The handler is now done with the original slice - assertTrue(dup1.release()); - - // Reference counting may be shared, or may be independently tracked, but at this point all buffers should - // be deallocated and have a reference count of 0. - assertEquals(0, buf.refCnt()); - assertEquals(0, dup1.refCnt()); - assertEquals(0, dup2.refCnt()); - } - - private void testMultipleRetainedSliceReleaseOriginal(boolean retainedSlice1, boolean retainedSlice2) { - ByteBuf buf = newBuffer(8).resetWriterIndex(); - ByteBuf expected1 = newBuffer(3).resetWriterIndex(); - ByteBuf expected2 = newBuffer(2).resetWriterIndex(); - ByteBuf expected3 = newBuffer(2).resetWriterIndex(); - buf.writeBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }); - expected1.writeBytes(new byte[] { 6, 7, 8 }); - expected2.writeBytes(new byte[] { 7, 8 }); - expected3.writeBytes(new byte[] { 6, 7 }); - ByteBuf slice1 = - retainedSlice1 ? buf.retainedSlice(buf.readerIndex() + 5, 3) : buf.slice(buf.readerIndex() + 5, 3).retain(); - assertEquals(0, slice1.compareTo(expected1)); - // Simulate a handler that releases the original buffer, and propagates a slice. - buf.release(); - - ByteBuf slice2 = retainedSlice2 - ? slice1.retainedSlice(slice1.readerIndex() + 1, 2) - : slice1.slice(slice1.readerIndex() + 1, 2).retain(); - assertEquals(0, slice2.compareTo(expected2)); - - // The handler created a slice of the slice and is now done with it. - slice2.release(); - - ByteBuf slice3 = slice1.retainedSlice(slice1.readerIndex(), 2); - assertEquals(0, slice3.compareTo(expected3)); - - // The handler created another slice of the slice and is now done with it. - slice3.release(); - - // The handler is now done with the original slice - assertTrue(slice1.release()); - - // Cleanup the expected buffers used for testing. - assertTrue(expected1.release()); - assertTrue(expected2.release()); - assertTrue(expected3.release()); - - // Reference counting may be shared, or may be independently tracked, but at this point all buffers should - // be deallocated and have a reference count of 0. - assertEquals(0, buf.refCnt()); - assertEquals(0, slice1.refCnt()); - assertEquals(0, slice2.refCnt()); - assertEquals(0, slice3.refCnt()); - } - - private void testMultipleRetainedDuplicateReleaseOriginal(boolean retainedDuplicate1, boolean retainedDuplicate2) { - ByteBuf buf = newBuffer(8).resetWriterIndex(); - ByteBuf expected = newBuffer(8).resetWriterIndex(); - buf.writeBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }); - expected.writeBytes(buf, buf.readerIndex(), buf.readableBytes()); - ByteBuf dup1 = retainedDuplicate1 ? buf.retainedDuplicate() : buf.duplicate().retain(); - assertEquals(0, dup1.compareTo(expected)); - // Simulate a handler that releases the original buffer, and propagates a slice. - buf.release(); - - ByteBuf dup2 = retainedDuplicate2 ? dup1.retainedDuplicate() : dup1.duplicate().retain(); - assertEquals(0, dup2.compareTo(expected)); - assertEquals(0, dup2.compareTo(dup2.duplicate())); - assertEquals(0, dup2.compareTo(dup2.slice())); - - ByteBuf tmpBuf = dup2.retainedDuplicate(); - assertEquals(0, dup2.compareTo(tmpBuf)); - tmpBuf.release(); - tmpBuf = dup2.retainedSlice(); - assertEquals(0, dup2.compareTo(tmpBuf)); - tmpBuf.release(); - - // The handler created a slice of the slice and is now done with it. - dup2.release(); - - ByteBuf dup3 = dup1.retainedDuplicate(); - assertEquals(0, dup3.compareTo(expected)); - - // The handler created another slice of the slice and is now done with it. - dup3.release(); - - // The handler is now done with the original slice - assertTrue(dup1.release()); - - // Cleanup the expected buffers used for testing. - assertTrue(expected.release()); - - // Reference counting may be shared, or may be independently tracked, but at this point all buffers should - // be deallocated and have a reference count of 0. - assertEquals(0, buf.refCnt()); - assertEquals(0, dup1.refCnt()); - assertEquals(0, dup2.refCnt()); - assertEquals(0, dup3.refCnt()); - } - - private void testDuplicateContents(boolean retainedDuplicate) { - ByteBuf buf = newBuffer(8).resetWriterIndex(); - buf.writeBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }); - ByteBuf dup = retainedDuplicate ? buf.retainedDuplicate() : buf.duplicate(); - try { - assertEquals(0, dup.compareTo(buf)); - assertEquals(0, dup.compareTo(dup.duplicate())); - ByteBuf b = dup.retainedDuplicate(); - assertEquals(0, dup.compareTo(b)); - b.release(); - assertEquals(0, dup.compareTo(dup.slice(dup.readerIndex(), dup.readableBytes()))); - } finally { - if (retainedDuplicate) { - dup.release(); - } - buf.release(); - } - } - - @Test(groups = "unit") - public void testDuplicateRelease() { - ByteBuf buf = newBuffer(8); - assertEquals(1, buf.refCnt()); - assertTrue(buf.duplicate().release()); - assertEquals(0, buf.refCnt()); - } - - // Test-case trying to reproduce: - // https://github.com/netty/netty/issues/2843 - @Test(groups = "unit") - public void testRefCnt() throws Exception { - testRefCnt0(false); - } - - // Test-case trying to reproduce: - // https://github.com/netty/netty/issues/2843 - @Test(groups = "unit") - public void testRefCnt2() throws Exception { - testRefCnt0(true); - } - - @Test(groups = "unit") - public void testEmptyNioBuffers() throws Exception { - ByteBuf buffer = newBuffer(8); - buffer.clear(); - assertFalse(buffer.isReadable()); - ByteBuffer[] nioBuffers = buffer.nioBuffers(); - assertEquals(1, nioBuffers.length); - assertFalse(nioBuffers[0].hasRemaining()); - buffer.release(); - } - - @Test(groups = "unit") - public void testGetReadOnlyDirectDst() { - testGetReadOnlyDst(true); - } - - @Test(groups = "unit") - public void testGetReadOnlyHeapDst() { - testGetReadOnlyDst(false); - } - - private void testGetReadOnlyDst(boolean direct) { - byte[] bytes = { 'a', 'b', 'c', 'd' }; - - ByteBuf buffer = newBuffer(bytes.length); - buffer.writeBytes(bytes); - - ByteBuffer dst = direct ? ByteBuffer.allocateDirect(bytes.length) : ByteBuffer.allocate(bytes.length); - ByteBuffer readOnlyDst = dst.asReadOnlyBuffer(); - try { - buffer.getBytes(0, readOnlyDst); - fail(); - } catch (ReadOnlyBufferException e) { - // expected - } - assertEquals(0, readOnlyDst.position()); - buffer.release(); - } - - @Test(groups = "unit") - public void testReadBytesAndWriteBytesWithFileChannel() throws IOException { - File file = File.createTempFile("file-channel", ".tmp"); - RandomAccessFile randomAccessFile = null; - try { - randomAccessFile = new RandomAccessFile(file, "rw"); - FileChannel channel = randomAccessFile.getChannel(); - // channelPosition should never be changed - long channelPosition = channel.position(); - - byte[] bytes = { 'a', 'b', 'c', 'd' }; - int len = bytes.length; - ByteBuf buffer = newBuffer(len); - buffer.resetReaderIndex(); - buffer.resetWriterIndex(); - buffer.writeBytes(bytes); - - int oldReaderIndex = buffer.readerIndex(); - assertEquals(len, buffer.readBytes(channel, 10, len)); - assertEquals(oldReaderIndex + len, buffer.readerIndex()); - assertEquals(channelPosition, channel.position()); - - ByteBuf buffer2 = newBuffer(len); - buffer2.resetReaderIndex(); - buffer2.resetWriterIndex(); - int oldWriterIndex = buffer2.writerIndex(); - assertEquals(len, buffer2.writeBytes(channel, 10, len)); - assertEquals(channelPosition, channel.position()); - assertEquals(oldWriterIndex + len, buffer2.writerIndex()); - assertEquals('a', buffer2.getByte(0)); - assertEquals('b', buffer2.getByte(1)); - assertEquals('c', buffer2.getByte(2)); - assertEquals('d', buffer2.getByte(3)); - buffer.release(); - buffer2.release(); - } finally { - if (randomAccessFile != null) { - randomAccessFile.close(); - } - file.delete(); - } - } - - @Test(groups = "unit") - public void testGetBytesAndSetBytesWithFileChannel() throws IOException { - File file = File.createTempFile("file-channel", ".tmp"); - RandomAccessFile randomAccessFile = null; - try { - randomAccessFile = new RandomAccessFile(file, "rw"); - FileChannel channel = randomAccessFile.getChannel(); - // channelPosition should never be changed - long channelPosition = channel.position(); - - byte[] bytes = { 'a', 'b', 'c', 'd' }; - int len = bytes.length; - ByteBuf buffer = newBuffer(len); - buffer.resetReaderIndex(); - buffer.resetWriterIndex(); - buffer.writeBytes(bytes); - - int oldReaderIndex = buffer.readerIndex(); - assertEquals(len, buffer.getBytes(oldReaderIndex, channel, 10, len)); - assertEquals(oldReaderIndex, buffer.readerIndex()); - assertEquals(channelPosition, channel.position()); - - ByteBuf buffer2 = newBuffer(len); - buffer2.resetReaderIndex(); - buffer2.resetWriterIndex(); - int oldWriterIndex = buffer2.writerIndex(); - assertEquals(buffer2.setBytes(oldWriterIndex, channel, 10, len), len); - assertEquals(channelPosition, channel.position()); - - assertEquals(oldWriterIndex, buffer2.writerIndex()); - assertEquals('a', buffer2.getByte(oldWriterIndex)); - assertEquals('b', buffer2.getByte(oldWriterIndex + 1)); - assertEquals('c', buffer2.getByte(oldWriterIndex + 2)); - assertEquals('d', buffer2.getByte(oldWriterIndex + 3)); - - buffer.release(); - buffer2.release(); - } finally { - if (randomAccessFile != null) { - randomAccessFile.close(); - } - file.delete(); - } - } - - @Test(groups = "unit") - public void testReadBytes() { - ByteBuf buffer = newBuffer(8); - byte[] bytes = new byte[8]; - buffer.writeBytes(bytes); - - ByteBuf buffer2 = buffer.readBytes(4); - assertSame(buffer.alloc(), buffer2.alloc()); - assertEquals(4, buffer.readerIndex()); - assertTrue(buffer.release()); - assertEquals(0, buffer.refCnt()); - assertTrue(buffer2.release()); - assertEquals(0, buffer2.refCnt()); - } - - @Test(groups = "unit") - public void testForEachByteDesc2() { - byte[] expected = { 1, 2, 3, 4 }; - ByteBuf buf = newBuffer(expected.length); - try { - buf.writeBytes(expected); - final byte[] bytes = new byte[expected.length]; - int i = buf.forEachByteDesc(new ByteProcessor() { - private int index = bytes.length - 1; - - @Override - public boolean process(byte value) throws Exception { - bytes[index--] = value; - return true; - } - }); - assertEquals(-1, i); - assertEquals(expected, bytes); - } finally { - buf.release(); - } - } - - @Test(groups = "unit") - public void testForEachByte2() { - byte[] expected = { 1, 2, 3, 4 }; - ByteBuf buf = newBuffer(expected.length); - try { - buf.writeBytes(expected); - final byte[] bytes = new byte[expected.length]; - int i = buf.forEachByte(new ByteProcessor() { - private int index; - - @Override - public boolean process(byte value) throws Exception { - bytes[index++] = value; - return true; - } - }); - assertEquals(-1, i); - assertEquals(expected, bytes); - } finally { - buf.release(); - } - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void testGetBytesByteBuffer() { - byte[] bytes = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' }; - // Ensure destination buffer is bigger then what is in the ByteBuf. - ByteBuffer nioBuffer = ByteBuffer.allocate(bytes.length + 1); - ByteBuf buffer = newBuffer(bytes.length); - try { - buffer.writeBytes(bytes); - buffer.getBytes(buffer.readerIndex(), nioBuffer); - } finally { - buffer.release(); - } - } - - private void testRefCnt0(final boolean parameter) throws Exception { - for (int i = 0; i < 10; i++) { - final CountDownLatch latch = new CountDownLatch(1); - final CountDownLatch innerLatch = new CountDownLatch(1); - - final ByteBuf buffer = newBuffer(4); - assertEquals(1, buffer.refCnt()); - final AtomicInteger cnt = new AtomicInteger(Integer.MAX_VALUE); - Thread t1 = new Thread(new Runnable() { - @Override - public void run() { - boolean released; - if (parameter) { - released = buffer.release(buffer.refCnt()); - } else { - released = buffer.release(); - } - assertTrue(released); - Thread t2 = new Thread(new Runnable() { - @Override - public void run() { - cnt.set(buffer.refCnt()); - latch.countDown(); - } - }); - t2.start(); - try { - // Keep Thread alive a bit so the ThreadLocal caches are not freed - innerLatch.await(); - } catch (InterruptedException ignore) { - // ignore - } - } - }); - t1.start(); - - latch.await(); - assertEquals(0, cnt.get()); - innerLatch.countDown(); - } - } - - static final class TestGatheringByteChannel implements GatheringByteChannel { - private final ByteArrayOutputStream out = new ByteArrayOutputStream(); - private final WritableByteChannel channel = Channels.newChannel(out); - private final int limit; - - TestGatheringByteChannel(int limit) { - this.limit = limit; - } - - TestGatheringByteChannel() { - this(Integer.MAX_VALUE); - } - - @Override - public long write(ByteBuffer[] srcs, int offset, int length) throws IOException { - long written = 0; - for (; offset < length; offset++) { - written += write(srcs[offset]); - if (written >= limit) { - break; - } - } - return written; - } - - @Override - public long write(ByteBuffer[] srcs) throws IOException { - return write(srcs, 0, srcs.length); - } - - @Override - public int write(ByteBuffer src) throws IOException { - int oldLimit = src.limit(); - if (limit < src.remaining()) { - src.limit(src.position() + limit); - } - int w = channel.write(src); - src.limit(oldLimit); - return w; - } - - @Override - public boolean isOpen() { - return channel.isOpen(); - } - - @Override - public void close() throws IOException { - channel.close(); - } - - public byte[] writtenBytes() { - return out.toByteArray(); - } - } - - private static final class DevNullGatheringByteChannel implements GatheringByteChannel { - @Override - public long write(ByteBuffer[] srcs, int offset, int length) { - throw new UnsupportedOperationException(); - } - - @Override - public long write(ByteBuffer[] srcs) { - throw new UnsupportedOperationException(); - } - - @Override - public int write(ByteBuffer src) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isOpen() { - return false; - } - - @Override - public void close() { - throw new UnsupportedOperationException(); - } - } - - private static final class TestScatteringByteChannel implements ScatteringByteChannel { - @Override - public long read(ByteBuffer[] dsts, int offset, int length) { - throw new UnsupportedOperationException(); - } - - @Override - public long read(ByteBuffer[] dsts) { - throw new UnsupportedOperationException(); - } - - @Override - public int read(ByteBuffer dst) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isOpen() { - return false; - } - - @Override - public void close() { - throw new UnsupportedOperationException(); - } - } - - private static final class TestByteProcessor implements ByteProcessor { - @Override - public boolean process(byte value) throws Exception { - return true; - } - } - - @Test(groups = "unit", expectedExceptions = IllegalArgumentException.class) - public void testCapacityEnforceMaxCapacity() { - ByteBuf buffer = newBuffer(3, 13); - assertEquals(13, buffer.maxCapacity()); - assertEquals(3, buffer.capacity()); - try { - buffer.capacity(14); - } finally { - buffer.release(); - } - } - - @Test(groups = "unit", expectedExceptions = IllegalArgumentException.class) - public void testCapacityNegative() { - ByteBuf buffer = newBuffer(3, 13); - assertEquals(13, buffer.maxCapacity()); - assertEquals(3, buffer.capacity()); - try { - buffer.capacity(-1); - } finally { - buffer.release(); - } - } - - @Test(groups = "unit") - public void testCapacityDecrease() { - ByteBuf buffer = newBuffer(3, 13); - assertEquals(13, buffer.maxCapacity()); - assertEquals(3, buffer.capacity()); - try { - buffer.capacity(2); - assertEquals(2, buffer.capacity()); - assertEquals(13, buffer.maxCapacity()); - } finally { - buffer.release(); - } - } - - @Test(groups = "unit") - public void testCapacityIncrease() { - ByteBuf buffer = newBuffer(3, 13); - assertEquals(13, buffer.maxCapacity()); - assertEquals(3, buffer.capacity()); - try { - buffer.capacity(4); - assertEquals(4, buffer.capacity()); - assertEquals(13, buffer.maxCapacity()); - } finally { - buffer.release(); - } - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void testReaderIndexLargerThanWriterIndex() { - String content1 = "hello"; - String content2 = "world"; - int length = content1.length() + content2.length(); - ByteBuf buffer = newBuffer(length); - buffer.setIndex(0, 0); - buffer.writeCharSequence(content1, CharsetUtil.US_ASCII); - buffer.markWriterIndex(); - buffer.skipBytes(content1.length()); - buffer.writeCharSequence(content2, CharsetUtil.US_ASCII); - buffer.skipBytes(content2.length()); - assertTrue(buffer.readerIndex() <= buffer.writerIndex()); - - try { - buffer.resetWriterIndex(); - } finally { - buffer.release(); - } - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/safealloc/DuplicatedByteBufTest.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/safealloc/DuplicatedByteBufTest.java deleted file mode 100644 index 8b9e2f451bc..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/safealloc/DuplicatedByteBufTest.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project 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 com.linkedin.alpini.base.safealloc; - -import static org.testng.AssertJUnit.assertEquals; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; -import io.netty.buffer.PooledByteBufAllocator; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - - -public class DuplicatedByteBufTest extends AbstractByteBufTest { - ByteBufAllocator _safeAlloc; - - @BeforeClass(groups = "unit") - public void beforeClass() { - _safeAlloc = new SafeAllocator(PooledByteBufAllocator.DEFAULT); - } - - @Override - protected ByteBuf newBuffer(int length, int maxCapacity) { - ByteBuf wrapped = _safeAlloc.heapBuffer(length, maxCapacity); - ByteBuf buffer = wrapped.duplicate(); - assertEquals(wrapped.writerIndex(), buffer.writerIndex()); - assertEquals(wrapped.readerIndex(), buffer.readerIndex()); - return buffer; - } - - // See https://github.com/netty/netty/issues/1800 - @Test(groups = "unit") - public void testIncreaseCapacityWrapped() { - ByteBuf buffer = newBuffer(8); - ByteBuf wrapped = buffer.unwrap(); - wrapped.writeByte(0); - wrapped.readerIndex(wrapped.readerIndex() + 1); - buffer.writerIndex(buffer.writerIndex() + 1); - wrapped.capacity(wrapped.capacity() * 2); - - assertEquals((byte) 0, buffer.readByte()); - } - - @Test(groups = "unit") - public void testMarksInitialized() { - ByteBuf wrapped = _safeAlloc.heapBuffer(8); - try { - wrapped.writerIndex(6); - wrapped.readerIndex(1); - ByteBuf duplicate = wrapped.duplicate(); - - // Test writer mark - duplicate.writerIndex(duplicate.writerIndex() + 1); - duplicate.resetWriterIndex(); - assertEquals(wrapped.writerIndex(), duplicate.writerIndex()); - - // Test reader mark - duplicate.readerIndex(duplicate.readerIndex() + 1); - duplicate.resetReaderIndex(); - assertEquals(wrapped.readerIndex(), duplicate.readerIndex()); - } finally { - wrapped.release(); - } - } - - @Test(groups = "unit", enabled = false) - public void testSliceCapacityChange() { - } - - @Test(groups = "unit", enabled = false) - public void testRetainedSliceCapacityChange() { - } - - @Test(groups = "unit", enabled = false) - public void testDiscardReadBytes() { - } - - @Test(groups = "unit", enabled = false) - public void testDiscardReadBytes2() { - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/safealloc/ReadOnlyByteBufferBufTest.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/safealloc/ReadOnlyByteBufferBufTest.java deleted file mode 100644 index 05cc40e2e23..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/safealloc/ReadOnlyByteBufferBufTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2013 The Netty Project - * - * The Netty Project 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 com.linkedin.alpini.base.safealloc; - -import static org.testng.AssertJUnit.assertEquals; - -import io.netty.buffer.ByteBuf; -import io.netty.util.internal.PlatformDependent; -import java.nio.ByteBuffer; -import org.testng.annotations.Test; - - -public class ReadOnlyByteBufferBufTest extends ReadOnlyDirectByteBufferBufTest { - @Override - protected ByteBuffer allocate(int size) { - return ByteBuffer.allocate(size); - } - - @Test(groups = "unit") - public void testCopyDirect() { - testCopy(true); - } - - @Test(groups = "unit") - public void testCopyHeap() { - testCopy(false); - } - - private void testCopy(boolean direct) { - byte[] bytes = new byte[1024]; - PlatformDependent.threadLocalRandom().nextBytes(bytes); - - ByteBuffer nioBuffer = direct ? ByteBuffer.allocateDirect(bytes.length) : ByteBuffer.allocate(bytes.length); - nioBuffer.put(bytes).flip(); - - ByteBuf buf = buffer(nioBuffer.asReadOnlyBuffer()); - ByteBuf copy = buf.copy(); - - assertEquals(buf, copy); - assertEquals(buf.alloc(), copy.alloc()); - assertEquals(buf.isDirect(), copy.isDirect()); - - copy.release(); - buf.release(); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/safealloc/ReadOnlyDirectByteBufferBufTest.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/safealloc/ReadOnlyDirectByteBufferBufTest.java deleted file mode 100644 index 6bb1cc070bc..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/safealloc/ReadOnlyDirectByteBufferBufTest.java +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Copyright 2013 The Netty Project - * - * The Netty Project 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 com.linkedin.alpini.base.safealloc; - -import static org.testng.AssertJUnit.assertEquals; -import static org.testng.AssertJUnit.assertFalse; -import static org.testng.AssertJUnit.assertTrue; -import static org.testng.AssertJUnit.fail; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; -import io.netty.buffer.ByteBufUtil; -import io.netty.buffer.PooledByteBufAllocator; -import io.netty.buffer.Unpooled; -import io.netty.util.internal.PlatformDependent; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.ReadOnlyBufferException; -import java.nio.channels.FileChannel; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - - -public class ReadOnlyDirectByteBufferBufTest { - ByteBufAllocator _safeAlloc; - - @BeforeClass(groups = "unit") - public void beforeClass() { - _safeAlloc = new SafeAllocator(PooledByteBufAllocator.DEFAULT); - } - - protected ByteBuf buffer(ByteBuffer buffer) { - if (!buffer.isReadOnly()) { - throw new IllegalArgumentException(); - } - return (buffer.isDirect() ? _safeAlloc.directBuffer(buffer.remaining()) : _safeAlloc.heapBuffer(buffer.remaining())) - .writeBytes(buffer) - .asReadOnly(); - } - - protected ByteBuffer allocate(int size) { - return ByteBuffer.allocateDirect(size); - } - - @Test(groups = "unit", expectedExceptions = IllegalArgumentException.class) - public void testConstructWithWritable() { - buffer(allocate(1)); - } - - @Test(groups = "unit") - public void shouldIndicateNotWritable() { - ByteBuf buf = buffer(allocate(8).asReadOnlyBuffer()).clear(); - try { - assertFalse(buf.isWritable()); - } finally { - buf.release(); - } - } - - @Test(groups = "unit") - public void shouldIndicateNotWritableAnyNumber() { - ByteBuf buf = buffer(allocate(8).asReadOnlyBuffer()).clear(); - try { - assertFalse(buf.isWritable(1)); - } finally { - buf.release(); - } - } - - @Test(groups = "unit") - public void ensureWritableIntStatusShouldFailButNotThrow() { - ByteBuf buf = buffer(allocate(8).asReadOnlyBuffer()).clear(); - try { - int result = buf.ensureWritable(1, false); - assertEquals(1, result); - } finally { - buf.release(); - } - } - - @Test(groups = "unit") - public void ensureWritableForceIntStatusShouldFailButNotThrow() { - ByteBuf buf = buffer(allocate(8).asReadOnlyBuffer()).clear(); - try { - int result = buf.ensureWritable(1, true); - assertEquals(1, result); - } finally { - buf.release(); - } - } - - @Test(groups = "unit", expectedExceptions = ReadOnlyBufferException.class) - public void ensureWritableShouldThrow() { - ByteBuf buf = buffer(allocate(8).asReadOnlyBuffer()).clear(); - try { - buf.ensureWritable(1); - } finally { - buf.release(); - } - } - - @Test(groups = "unit", expectedExceptions = ReadOnlyBufferException.class) - public void testSetByte() { - ByteBuf buf = buffer(allocate(8).asReadOnlyBuffer()); - try { - buf.setByte(0, 1); - } finally { - buf.release(); - } - } - - @Test(groups = "unit", expectedExceptions = ReadOnlyBufferException.class) - public void testSetInt() { - ByteBuf buf = buffer(allocate(8).asReadOnlyBuffer()); - try { - buf.setInt(0, 1); - } finally { - buf.release(); - } - } - - @Test(groups = "unit", expectedExceptions = ReadOnlyBufferException.class) - public void testSetShort() { - ByteBuf buf = buffer(allocate(8).asReadOnlyBuffer()); - try { - buf.setShort(0, 1); - } finally { - buf.release(); - } - } - - @Test(groups = "unit", expectedExceptions = ReadOnlyBufferException.class) - public void testSetMedium() { - ByteBuf buf = buffer(allocate(8).asReadOnlyBuffer()); - try { - buf.setMedium(0, 1); - } finally { - buf.release(); - } - } - - @Test(groups = "unit", expectedExceptions = ReadOnlyBufferException.class) - public void testSetLong() { - ByteBuf buf = buffer(allocate(8).asReadOnlyBuffer()); - try { - buf.setLong(0, 1); - } finally { - buf.release(); - } - } - - @Test(groups = "unit", expectedExceptions = ReadOnlyBufferException.class) - public void testSetBytesViaArray() { - ByteBuf buf = buffer(allocate(8).asReadOnlyBuffer()); - try { - buf.setBytes(0, "test".getBytes()); - } finally { - buf.release(); - } - } - - @Test(groups = "unit", expectedExceptions = ReadOnlyBufferException.class) - public void testSetBytesViaBuffer() { - ByteBuf buf = buffer(allocate(8).asReadOnlyBuffer()); - ByteBuf copy = Unpooled.copyInt(1); - try { - buf.setBytes(0, copy); - } finally { - buf.release(); - copy.release(); - } - } - - @Test(groups = "unit", expectedExceptions = ReadOnlyBufferException.class) - public void testSetBytesViaStream() throws IOException { - ByteBuf buf = buffer(ByteBuffer.allocateDirect(8).asReadOnlyBuffer()); - try { - buf.setBytes(0, new ByteArrayInputStream("test".getBytes()), 2); - } finally { - buf.release(); - } - } - - @Test(groups = "unit") - public void testGetReadByte() { - ByteBuf buf = buffer(((ByteBuffer) allocate(2).put(new byte[] { (byte) 1, (byte) 2 }).flip()).asReadOnlyBuffer()); - - assertEquals(1, buf.getByte(0)); - assertEquals(2, buf.getByte(1)); - - assertEquals(1, buf.readByte()); - assertEquals(2, buf.readByte()); - assertFalse(buf.isReadable()); - - buf.release(); - } - - @Test(groups = "unit") - public void testGetReadInt() { - ByteBuf buf = buffer(((ByteBuffer) allocate(8).putInt(1).putInt(2).flip()).asReadOnlyBuffer()); - - assertEquals(1, buf.getInt(0)); - assertEquals(2, buf.getInt(4)); - - assertEquals(1, buf.readInt()); - assertEquals(2, buf.readInt()); - assertFalse(buf.isReadable()); - - buf.release(); - } - - @Test(groups = "unit") - public void testGetReadShort() { - ByteBuf buf = buffer(((ByteBuffer) allocate(8).putShort((short) 1).putShort((short) 2).flip()).asReadOnlyBuffer()); - - assertEquals(1, buf.getShort(0)); - assertEquals(2, buf.getShort(2)); - - assertEquals(1, buf.readShort()); - assertEquals(2, buf.readShort()); - assertFalse(buf.isReadable()); - - buf.release(); - } - - @Test(groups = "unit") - public void testGetReadLong() { - ByteBuf buf = buffer(((ByteBuffer) allocate(16).putLong(1).putLong(2).flip()).asReadOnlyBuffer()); - - assertEquals(1, buf.getLong(0)); - assertEquals(2, buf.getLong(8)); - - assertEquals(1, buf.readLong()); - assertEquals(2, buf.readLong()); - assertFalse(buf.isReadable()); - - buf.release(); - } - - @Test(groups = "unit") - public void testCopy() { - ByteBuf buf = buffer(((ByteBuffer) allocate(16).putLong(1).putLong(2).flip()).asReadOnlyBuffer()); - ByteBuf copy = buf.copy(); - - assertEquals(buf, copy); - - buf.release(); - copy.release(); - } - - @Test(groups = "unit") - public void testCopyWithOffset() { - ByteBuf buf = buffer(((ByteBuffer) allocate(16).putLong(1).putLong(2).flip()).asReadOnlyBuffer()); - ByteBuf copy = buf.copy(1, 9); - - assertTrue(ByteBufUtil.equals(buf.slice(1, 9), copy)); - - buf.release(); - copy.release(); - } - - // Test for https://github.com/netty/netty/issues/1708 - @Test(groups = "unit") - public void testWrapBufferWithNonZeroPosition() { - ByteBuf buf = buffer(((ByteBuffer) allocate(16).putLong(1).flip().position(1)).asReadOnlyBuffer()); - - ByteBuf slice = buf.slice(); - assertEquals(buf, slice); - - buf.release(); - } - - @Test(groups = "unit") - public void testWrapBufferRoundTrip() { - ByteBuf buf = buffer(((ByteBuffer) allocate(16).putInt(1).putInt(2).flip()).asReadOnlyBuffer()); - - assertEquals(1, buf.readInt()); - - ByteBuffer nioBuffer = buf.nioBuffer(); - - // Ensure this can be accessed without throwing a BufferUnderflowException - assertEquals(2, nioBuffer.getInt()); - - buf.release(); - } - - @Test(groups = "unit") - public void testWrapMemoryMapped() throws Exception { - File file = File.createTempFile("netty-test", "tmp"); - FileChannel output = null; - FileChannel input = null; - ByteBuf b1 = null; - ByteBuf b2 = null; - - try { - output = new FileOutputStream(file).getChannel(); - byte[] bytes = new byte[1024]; - PlatformDependent.threadLocalRandom().nextBytes(bytes); - output.write(ByteBuffer.wrap(bytes)); - - input = new FileInputStream(file).getChannel(); - ByteBuffer m = input.map(FileChannel.MapMode.READ_ONLY, 0, input.size()); - - b1 = buffer(m); - - ByteBuffer dup = m.duplicate(); - dup.position(2); - dup.limit(4); - - b2 = buffer(dup); - - assertEquals(b2, b1.slice(2, 2)); - } finally { - if (b1 != null) { - b1.release(); - } - if (b2 != null) { - b2.release(); - } - if (output != null) { - output.close(); - } - if (input != null) { - input.close(); - } - file.delete(); - } - } - - @Test(groups = "unit") - public void testMemoryAddress() { - ByteBuf buf = buffer(allocate(8).asReadOnlyBuffer()); - try { - assertFalse(buf.hasMemoryAddress()); - try { - buf.memoryAddress(); - fail(); - } catch (UnsupportedOperationException expected) { - // expected - } - } finally { - buf.release(); - } - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/safealloc/RetainedSlicedByteBufTest.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/safealloc/RetainedSlicedByteBufTest.java deleted file mode 100644 index 2cd0938af79..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/safealloc/RetainedSlicedByteBufTest.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2016 The Netty Project - * - * The Netty Project 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 com.linkedin.alpini.base.safealloc; - -import static org.testng.AssertJUnit.assertEquals; - -import io.netty.buffer.ByteBuf; - - -public class RetainedSlicedByteBufTest extends SlicedByteBufTest { - @Override - protected ByteBuf newSlice(ByteBuf buffer, int offset, int length) { - ByteBuf slice = buffer.retainedSlice(offset, length); - buffer.release(); - assertEquals(buffer.refCnt(), slice.refCnt()); - return slice; - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/safealloc/SlicedByteBufTest.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/safealloc/SlicedByteBufTest.java deleted file mode 100644 index 8e456d04558..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/safealloc/SlicedByteBufTest.java +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project 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 com.linkedin.alpini.base.safealloc; - -import static org.testng.AssertJUnit.assertEquals; -import static org.testng.AssertJUnit.assertFalse; -import static org.testng.AssertJUnit.assertTrue; -import static org.testng.AssertJUnit.fail; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; -import io.netty.buffer.PooledByteBufAllocator; -import io.netty.buffer.Unpooled; -import io.netty.util.internal.PlatformDependent; -import java.nio.ByteBuffer; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - - -public class SlicedByteBufTest extends AbstractByteBufTest { - ByteBufAllocator _safeAlloc; - - @BeforeClass(groups = "unit") - public void beforeClass() { - _safeAlloc = new SafeAllocator(PooledByteBufAllocator.DEFAULT); - } - - @Override - protected final ByteBuf newBuffer(int length, int maxCapacity) { - assumeTrue(maxCapacity == Integer.MAX_VALUE); - int offset = length == 0 ? 0 : PlatformDependent.threadLocalRandom().nextInt(length); - ByteBuf buffer = _safeAlloc.buffer(length * 2); - ByteBuf slice = newSlice(buffer, offset, length); - assertEquals(0, slice.readerIndex()); - assertEquals(length, slice.writerIndex()); - return slice; - } - - protected ByteBuf newSlice(ByteBuf buffer, int offset, int length) { - return buffer.slice(offset, length); - } - - @Test(groups = "unit", expectedExceptions = NullPointerException.class) - public void shouldNotAllowNullInConstructor() { - new SafeByteBuf(null); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - @Override - public void testInternalNioBuffer() { - super.testInternalNioBuffer(); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - @Override - public void testDuplicateReadGatheringByteChannelMultipleThreads() throws Exception { - super.testDuplicateReadGatheringByteChannelMultipleThreads(); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - @Override - public void testSliceReadGatheringByteChannelMultipleThreads() throws Exception { - super.testSliceReadGatheringByteChannelMultipleThreads(); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - @Override - public void testDuplicateReadOutputStreamMultipleThreads() throws Exception { - super.testDuplicateReadOutputStreamMultipleThreads(); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - @Override - public void testSliceReadOutputStreamMultipleThreads() throws Exception { - super.testSliceReadOutputStreamMultipleThreads(); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - @Override - public void testDuplicateBytesInArrayMultipleThreads() throws Exception { - super.testDuplicateBytesInArrayMultipleThreads(); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - @Override - public void testSliceBytesInArrayMultipleThreads() throws Exception { - super.testSliceBytesInArrayMultipleThreads(); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - @Override - public void testNioBufferExposeOnlyRegion() { - super.testNioBufferExposeOnlyRegion(); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - @Override - public void testGetReadOnlyDirectDst() { - super.testGetReadOnlyDirectDst(); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - @Override - public void testGetReadOnlyHeapDst() { - super.testGetReadOnlyHeapDst(); - } - - @Test(groups = "unit", enabled = false) - @Override - public void testLittleEndianWithExpand() { - // ignore for SlicedByteBuf - } - - @Test(groups = "unit", enabled = false) - @Override - public void testReadBytes() { - // ignore for SlicedByteBuf - } - - @Test(groups = "unit", enabled = false) - @Override - public void testForEachByteDesc2() { - // Ignore for SlicedByteBuf - } - - @Test(groups = "unit", enabled = false) - @Override - public void testForEachByte2() { - // Ignore for SlicedByteBuf - } - - @Test(groups = "unit", enabled = false) - @Override - public void testDiscardReadBytes() { - } - - @Test(groups = "unit", enabled = false) - @Override - public void testDiscardReadBytes2() { - } - - @Test(groups = "unit", enabled = false) - @Override - public void testDuplicateCapacityChange() { - } - - @Test(groups = "unit", enabled = false) - @Override - public void testRetainedDuplicateCapacityChange() { - } - - @Test(groups = "unit") - public void testReaderIndexAndMarks() { - ByteBuf wrapped = _safeAlloc.buffer(16); - try { - wrapped.writerIndex(14); - wrapped.readerIndex(2); - wrapped.markWriterIndex(); - wrapped.markReaderIndex(); - ByteBuf slice = wrapped.slice(4, 4); - assertEquals(0, slice.readerIndex()); - assertEquals(4, slice.writerIndex()); - - slice.readerIndex(slice.readerIndex() + 1); - slice.resetReaderIndex(); - assertEquals(0, slice.readerIndex()); - - slice.writerIndex(slice.writerIndex() - 1); - slice.resetWriterIndex(); - assertEquals(0, slice.writerIndex()); - } finally { - wrapped.release(); - } - } - - @Test(groups = "unit") - public void sliceEmptyNotLeak() { - ByteBuf buffer = _safeAlloc.buffer(8).retain(); - assertEquals(2, buffer.refCnt()); - - ByteBuf slice1 = buffer.slice(); - assertEquals(2, slice1.refCnt()); - - ByteBuf slice2 = slice1.slice(); - assertEquals(2, slice2.refCnt()); - - assertFalse(slice2.release()); - assertEquals(1, buffer.refCnt()); - assertEquals(1, slice1.refCnt()); - assertEquals(1, slice2.refCnt()); - - assertTrue(slice2.release()); - - assertEquals(0, buffer.refCnt()); - assertEquals(0, slice1.refCnt()); - assertEquals(0, slice2.refCnt()); - } - - @Override - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void testGetBytesByteBuffer() { - byte[] bytes = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' }; - // Ensure destination buffer is bigger then what is wrapped in the ByteBuf. - ByteBuffer nioBuffer = ByteBuffer.allocate(bytes.length + 1); - ByteBuf wrappedBuffer = Unpooled.wrappedBuffer(bytes).slice(0, bytes.length - 1); - try { - wrappedBuffer.getBytes(wrappedBuffer.readerIndex(), nioBuffer); - } finally { - wrappedBuffer.release(); - } - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - @Override - public void testWriteUsAsciiCharSequenceExpand() { - super.testWriteUsAsciiCharSequenceExpand(); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - @Override - public void testWriteUtf8CharSequenceExpand() { - super.testWriteUtf8CharSequenceExpand(); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - @Override - public void testWriteIso88591CharSequenceExpand() { - super.testWriteIso88591CharSequenceExpand(); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - @Override - public void testWriteUtf16CharSequenceExpand() { - super.testWriteUtf16CharSequenceExpand(); - } - - @Test(groups = "unit") - public void ensureWritableWithEnoughSpaceShouldNotThrow() { - ByteBuf slice = newBuffer(10); - ByteBuf unwrapped = slice.unwrap(); - unwrapped.writerIndex(unwrapped.writerIndex() + 5); - slice.writerIndex(slice.readerIndex()); - - // Run ensureWritable and verify this doesn't change any indexes. - int originalWriterIndex = slice.writerIndex(); - int originalReadableBytes = slice.readableBytes(); - slice.ensureWritable(originalWriterIndex - slice.writerIndex()); - assertEquals(originalWriterIndex, slice.writerIndex()); - assertEquals(originalReadableBytes, slice.readableBytes()); - slice.release(); - } - - @Test(groups = "unit", expectedExceptions = IndexOutOfBoundsException.class) - public void ensureWritableWithNotEnoughSpaceShouldThrow() { - ByteBuf slice = newBuffer(10); - ByteBuf unwrapped = slice.unwrap(); - unwrapped.writerIndex(unwrapped.writerIndex() + 5); - try { - slice.ensureWritable(1); - fail(); - } finally { - slice.release(); - } - } - -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/safealloc/TestSafeAlloc.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/safealloc/TestSafeAlloc.java deleted file mode 100644 index 8090cf29f40..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/base/safealloc/TestSafeAlloc.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.linkedin.alpini.base.safealloc; - -import com.linkedin.alpini.base.misc.Time; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufUtil; -import io.netty.buffer.PooledByteBufAllocator; -import io.netty.util.internal.PlatformDependent; -import org.testng.Assert; -import org.testng.annotations.Test; - - -public class TestSafeAlloc { - public void testAlloc(SafeAllocator allocator, String text, int active, long leaked, boolean release) { - ByteBuf buf = ByteBufUtil.writeAscii(allocator, text); - - if (PlatformDependent.directBufferPreferred()) { - Assert.assertEquals(allocator.metric().usedDirectMemory(), 16777216); - Assert.assertEquals(allocator.metric().usedHeapMemory(), 0); - } else { - Assert.assertEquals(allocator.metric().usedDirectMemory(), 0); - Assert.assertEquals(allocator.metric().usedHeapMemory(), 16777216); - } - Assert.assertEquals(allocator.metric().activeAllocations(), active); - Assert.assertEquals(allocator.metric().leakedAllocations(), leaked); - - if (release) { - buf.release(); - } else { - buf.retain(100); - Assert.assertEquals(buf.refCnt(), 101); - } - } - - @Test(groups = "unit") - public void testBasic() throws InterruptedException { - - PooledByteBufAllocator store = new PooledByteBufAllocator(false); - SafeAllocator allocator = new SafeAllocator(store); - - testAlloc(allocator, "Hello world", 1, 0, false); - Assert.assertEquals(allocator.metric().totalReferences(), 1); - - System.gc(); - Time.sleep(1000L); - System.gc(); - - testAlloc(allocator, "Goodbye world", 1, 1, true); - Assert.assertEquals(allocator.metric().totalReferences(), 2); - - System.gc(); - Time.sleep(1000L); - System.gc(); - - Assert.assertEquals(allocator.metric().activeAllocations(), 0); - Assert.assertEquals(allocator.metric().leakedAllocations(), 1); - Assert.assertEquals(allocator.metric().totalReferences(), 2); - Assert.assertEquals(allocator.metric().totalQueues(), 1); - } - -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/compression/TestCompressionUtils.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/compression/TestCompressionUtils.java deleted file mode 100644 index ba332f89305..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/compression/TestCompressionUtils.java +++ /dev/null @@ -1,134 +0,0 @@ -package com.linkedin.alpini.netty4.compression; - -import org.testng.Assert; -import org.testng.annotations.Test; - - -/** - * Test CompressionUtils Class - * - * @author Eun-Gyu Kim - */ -public class TestCompressionUtils { - @Test(groups = { "unit" }) - public void testIsSupportedEncoding() { - Assert.assertFalse(CompressionUtils.isSupportedEncoding(null)); - - final String f1 = "snappy"; - Assert.assertTrue(CompressionUtils.isSupportedEncoding(f1)); - - final String f2 = "deflate"; - Assert.assertTrue(CompressionUtils.isSupportedEncoding(f2)); - - final String f3 = "identity"; - Assert.assertTrue(CompressionUtils.isSupportedEncoding(f3)); - - final String f4 = "gzip"; - Assert.assertTrue(CompressionUtils.isSupportedEncoding(f4)); - - final String f5 = "something"; - Assert.assertFalse(CompressionUtils.isSupportedEncoding(f5)); - } - - @Test(groups = { "unit" }) - public void testIsSupportedEncodingWithQuality() { - Assert.assertFalse(CompressionUtils.isSupportedEncoding(null)); - - final String f1 = "snappy;q=1.0"; - Assert.assertTrue(CompressionUtils.isSupportedEncoding(f1)); - - final String f1a = "snappy ; q = 1.0"; - Assert.assertTrue(CompressionUtils.isSupportedEncoding(f1a)); - - final String f1b = "snappy ; q = 1.0 , foobar"; - Assert.assertTrue(CompressionUtils.isSupportedEncoding(f1b)); - - final String f2 = "deflate;q=1.0"; - Assert.assertTrue(CompressionUtils.isSupportedEncoding(f2)); - - final String f3 = "identity;q=1.0"; - Assert.assertTrue(CompressionUtils.isSupportedEncoding(f3)); - - final String f4 = "gzip;q=1.0"; - Assert.assertTrue(CompressionUtils.isSupportedEncoding(f4)); - - final String f5 = "something;q=1.0"; - Assert.assertFalse(CompressionUtils.isSupportedEncoding(f5)); - } - - @Test(groups = { "unit" }) - public void testIsSupportedEncodingWithQualityZero() { - Assert.assertFalse(CompressionUtils.isSupportedEncoding(null)); - - final String f1 = "snappy;q=0.0"; - Assert.assertFalse(CompressionUtils.isSupportedEncoding(f1)); - - final String f1a = "snappy ; q = 0.0"; - Assert.assertFalse(CompressionUtils.isSupportedEncoding(f1a)); - - final String f1b = "snappy ; q = 0.0 , foobar"; - Assert.assertFalse(CompressionUtils.isSupportedEncoding(f1b)); - - final String f2 = "deflate;q=0.0"; - Assert.assertFalse(CompressionUtils.isSupportedEncoding(f2)); - - final String f3 = "identity;q=0.0"; - Assert.assertFalse(CompressionUtils.isSupportedEncoding(f3)); - - final String f4 = "gzip;q=0.0"; - Assert.assertFalse(CompressionUtils.isSupportedEncoding(f4)); - - final String f5 = "something"; - Assert.assertFalse(CompressionUtils.isSupportedEncoding(f5)); - - final String f6 = "snappy;q=0.0,deflate;q=0.0,identity;q=0.0,gzip;q=0.0"; - Assert.assertFalse(CompressionUtils.isSupportedEncoding(f6)); - } - - @Test(groups = { "unit" }) - public void testIsSupportedEncodingWithQualityMixed() { - Assert.assertFalse(CompressionUtils.isSupportedEncoding(null)); - - final String f1 = "deflate;q=0.0,snappy;q=1.0"; - Assert.assertTrue(CompressionUtils.isSupportedEncoding(f1)); - - final String f2 = "identity;q=0.0,deflate;q=1.0"; - Assert.assertTrue(CompressionUtils.isSupportedEncoding(f2)); - - final String f3 = "gzip;q=0.0,identity;q=1.0"; - Assert.assertTrue(CompressionUtils.isSupportedEncoding(f3)); - - final String f4 = "deflate;q=0.0,gzip;q=1.0"; - Assert.assertTrue(CompressionUtils.isSupportedEncoding(f4)); - - final String f5 = "deflate;q=0.0,gzip;q=yellow"; - Assert.assertFalse(CompressionUtils.isSupportedEncoding(f5)); - - final String f6 = "something;q=1.0"; - Assert.assertFalse(CompressionUtils.isSupportedEncoding(f6)); - } - - @Test(groups = { "unit" }) - public void testIsCompatibleEncodings() { - Assert.assertTrue(CompressionUtils.isCompatibleEncoding(null, "anything;at;all")); - Assert.assertFalse(CompressionUtils.isCompatibleEncoding("gzip", null)); - Assert.assertTrue(CompressionUtils.isCompatibleEncoding("identity", null)); - Assert.assertFalse( - CompressionUtils.isCompatibleEncoding("gzip", "snappy;q=0.0,deflate;q=0.0,identity;q=0.0,gzip;q=0.0")); - Assert.assertFalse( - CompressionUtils.isCompatibleEncoding("gzip", "snappy;q=1.0,deflate;q=0.0,identity;q=0.0,gzip;q=0.0")); - Assert.assertTrue( - CompressionUtils.isCompatibleEncoding("gzip", "snappy;q=0.0,deflate;q=0.0,identity;q=0.0,gzip;q=1.0")); - Assert.assertTrue(CompressionUtils.isCompatibleEncoding("gzip", "snappy;q=0.0,deflate;q=0.0,identity;q=0.0,gzip")); - Assert.assertFalse( - CompressionUtils.isCompatibleEncoding("gzip", "snappy;q=0.0,deflate;q=0.0,identity;q=0.0,gzip;q=yellow")); - Assert.assertFalse( - CompressionUtils.isCompatibleEncoding("foobar", "snappy;q=0.0,deflate;q=0.0,identity;q=0.0,gzip;q=0.0")); - Assert.assertFalse( - CompressionUtils.isCompatibleEncoding("foobar", "snappy;q=1.0,deflate;q=0.0,identity;q=0.0,gzip;q=0.0")); - Assert.assertTrue( - CompressionUtils - .isCompatibleEncoding("foobar", "snappy;q=0.0,deflate;q=0.0,foobar;q=0.1,identity;q=0.0,gzip;q=1.0")); - - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestElideDuplicateHeadersHandler.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestElideDuplicateHeadersHandler.java deleted file mode 100644 index 05166005fab..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestElideDuplicateHeadersHandler.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import io.netty.channel.embedded.EmbeddedChannel; -import io.netty.handler.codec.http.DefaultHttpHeaders; -import io.netty.handler.codec.http.DefaultHttpRequest; -import io.netty.handler.codec.http.DefaultHttpResponse; -import io.netty.handler.codec.http.HttpHeaders; -import io.netty.handler.codec.http.HttpMethod; -import io.netty.handler.codec.http.HttpRequest; -import io.netty.handler.codec.http.HttpResponse; -import io.netty.handler.codec.http.HttpResponseStatus; -import io.netty.handler.codec.http.HttpVersion; -import java.util.Iterator; -import java.util.Map; -import org.testng.Assert; -import org.testng.annotations.Test; - - -public class TestElideDuplicateHeadersHandler { - @Test(groups = "unit") - public void testBasicFunction() { - HttpHeaders requestHeaders = new DefaultHttpHeaders(); - String key = "Hello-World"; - String value = "This is a test"; - requestHeaders.add(key, value); - - EmbeddedChannel ch = new EmbeddedChannel(ElideDuplicateHeadersHandler.INSTANCE); - - HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/", requestHeaders); - ch.writeOneInbound(request); - Assert.assertSame(ch.readInbound(), request); - - HttpHeaders responseHeaders = new DefaultHttpHeaders(); - responseHeaders.add(key, value); - HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, responseHeaders); - ch.writeOneOutbound(response); - ch.flushOutbound(); - Assert.assertSame(ch.readOutbound(), response); - - Iterator> requestIterator = request.headers().iteratorCharSequence(); - Iterator> responseIterator = response.headers().iteratorCharSequence(); - - Map.Entry requestEntry = requestIterator.next(); - Map.Entry responseEntry = responseIterator.next(); - - Assert.assertSame(requestEntry.getKey(), responseEntry.getKey()); - Assert.assertSame(requestEntry.getValue(), responseEntry.getValue()); - - Assert.assertNotSame(requestEntry.getKey(), key); - Assert.assertNotSame(requestEntry.getValue(), value); - - Assert.assertFalse(requestIterator.hasNext()); - Assert.assertFalse(responseIterator.hasNext()); - - ch.finishAndReleaseAll(); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestHeaderStamp.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestHeaderStamp.java deleted file mode 100644 index 183bff32661..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestHeaderStamp.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelPromise; -import io.netty.handler.codec.http.HttpHeaders; -import io.netty.handler.codec.http.HttpResponse; -import org.mockito.Mockito; -import org.testng.annotations.Test; - - -/** - * @author Antony T Curtis {@literal } - */ -public class TestHeaderStamp { - @Test(groups = "unit") - public void testStampHeader() throws Exception { - HeaderStamp stamp = new HeaderStamp("TestHeader", "TestValue"); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - - HttpResponse msg = Mockito.mock(HttpResponse.class); - HttpHeaders headers = Mockito.mock(HttpHeaders.class); - ChannelPromise promise = Mockito.mock(ChannelPromise.class); - - Mockito.when(msg.headers()).thenReturn(headers); - - stamp.write(ctx, msg, promise); - - Mockito.verify(msg).headers(); - Mockito.verify(headers).add(Mockito.eq("TestHeader"), Mockito.eq("TestValue")); - Mockito.verify(ctx).write(Mockito.eq(msg), Mockito.eq(promise)); - Mockito.verifyNoMoreInteractions(ctx, msg, promise, headers); - - } - - @Test(groups = "unit") - public void testNoStampHeader() throws Exception { - - HeaderStamp stamp = new HeaderStamp("TestHeader", "TestValue"); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Object msg = Mockito.mock(Object.class); - ChannelPromise promise = Mockito.mock(ChannelPromise.class); - stamp.write(ctx, msg, promise); - - Mockito.verify(ctx).write(Mockito.eq(msg), Mockito.eq(promise)); - Mockito.verifyNoMoreInteractions(ctx, msg, promise); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestHttp2PingResponseHandler.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestHttp2PingResponseHandler.java deleted file mode 100644 index d443bf1235c..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestHttp2PingResponseHandler.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import com.linkedin.alpini.base.misc.Time; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.EventLoop; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.embedded.EmbeddedChannel; -import io.netty.handler.codec.http2.DefaultHttp2PingFrame; -import io.netty.handler.codec.http2.Http2PingFrame; -import org.mockito.Mockito; -import org.testng.Assert; -import org.testng.annotations.Test; - - -/* -* This class is designed to test Http2PingResponseHandler. -* -* @author Binbing Hou -* */ -public class TestHttp2PingResponseHandler { - @Test - public void basicTest() throws Exception { - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Channel channel = Mockito.mock(Channel.class); - EventLoop eventLoop = Mockito.mock(EventLoop.class); - EventLoopGroup eventLoopGroup = Mockito.mock(EventLoopGroup.class); - - Mockito.doReturn(channel).when(ctx).channel(); - Mockito.doReturn(eventLoop).when(channel).eventLoop(); - Mockito.doReturn(eventLoopGroup).when(eventLoop).parent(); - Mockito.doNothing().when(eventLoopGroup).forEach(Mockito.any()); - - Http2PingResponseHandler handler = new Http2PingResponseHandler(); - - long pingId = Time.currentTimeMillis(); - handler.channelRead0(ctx, new DefaultHttp2PingFrame(pingId, false)); - Http2PingFrame pingAckFrame = handler.getLastPingAckFrame(); - Assert.assertNotNull(pingAckFrame); - Assert.assertTrue(pingAckFrame.ack()); - Assert.assertEquals(pingAckFrame.content(), pingId); - Mockito.verify(ctx).writeAndFlush(pingAckFrame); - - // reset - Mockito.reset(ctx, channel, eventLoop, eventLoopGroup); - } - - @Test - public void nonHttp2PingFrameTest() { - Http2PingResponseHandler handler = new Http2PingResponseHandler(); - EmbeddedChannel channel = new EmbeddedChannel(handler); - channel.writeInbound("hello world"); - Assert.assertNull(handler.getLastPingAckFrame()); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestHttp2PingSendHandler.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestHttp2PingSendHandler.java deleted file mode 100644 index 690dda793eb..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestHttp2PingSendHandler.java +++ /dev/null @@ -1,145 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import com.linkedin.alpini.base.misc.Time; -import com.linkedin.alpini.netty4.pool.Http2PingCallListener; -import com.linkedin.alpini.netty4.pool.Http2PingHelper; -import io.netty.channel.embedded.EmbeddedChannel; -import io.netty.handler.codec.http2.DefaultHttp2PingFrame; -import io.netty.handler.codec.http2.Http2PingFrame; -import org.mockito.Mockito; -import org.testng.Assert; -import org.testng.annotations.Test; - -/* -* This class is implemented to test Http2PingSendHandler. -* -* @author Binbing Hou -* */ - - -public class TestHttp2PingSendHandler { - @Test - public void basicTest() { - Http2PingCallListener listener = Mockito.spy(new Http2PingHelper()); - Http2PingSendHandler handler = Mockito.spy(new Http2PingSendHandler(listener)); - - EmbeddedChannel channel = new EmbeddedChannel(handler); - - // write http2 ping - long pingId = Time.currentTimeMillis(); - long currentTimeNanosForPing = 123456L; - Mockito.doReturn(currentTimeNanosForPing).when(handler).getCurrentTimeNanos(); - Http2PingFrame http2PingFrame = new DefaultHttp2PingFrame(pingId, false); - channel.writeOutbound(http2PingFrame); - - Assert.assertEquals(handler.getLastPingSendTime(), currentTimeNanosForPing); - Assert.assertEquals(handler.getLastPingAckTime(), 0L); - Assert.assertEquals(handler.getLastPingId(), pingId); - Assert.assertEquals(handler.getLastPingChannel(), channel); - Mockito.verify(listener).callStart(pingId, currentTimeNanosForPing); - - // write http2 ping ack - Http2PingFrame http2PingAckFrame = new DefaultHttp2PingFrame(pingId, true); - long currentTimeNanosForPingAck = 123457L; - Mockito.doReturn(currentTimeNanosForPingAck).when(handler).getCurrentTimeNanos(); - channel.writeInbound(http2PingAckFrame); - - Assert.assertEquals(handler.getLastPingSendTime(), currentTimeNanosForPing); - Assert.assertEquals(handler.getLastPingAckTime(), currentTimeNanosForPingAck); - Assert.assertEquals(handler.getLastPingId(), pingId); - Assert.assertEquals(handler.getLastPingChannel(), channel); - Mockito.verify(listener).callClose(pingId, currentTimeNanosForPingAck); - - // reset - Mockito.reset(listener, handler); - } - - @Test - public void pingAckTimeOutTest() { - Http2PingCallListener listener = Mockito.spy(new Http2PingHelper()); - Http2PingSendHandler handler = Mockito.spy(new Http2PingSendHandler(listener)); - - EmbeddedChannel channel = new EmbeddedChannel(handler); - - // write first http2 ping - long pingId1 = Time.currentTimeMillis(); - long currentTimeNanosForPing1 = 123456L; - Mockito.doReturn(currentTimeNanosForPing1).when(handler).getCurrentTimeNanos(); - Http2PingFrame http2PingFrame1 = new DefaultHttp2PingFrame(pingId1, false); - channel.writeOutbound(http2PingFrame1); - - // write the second http2 ping - long pingId2 = Time.currentTimeMillis(); - long currentTimeNanosForPing2 = 123457L; - Mockito.doReturn(currentTimeNanosForPing2).when(handler).getCurrentTimeNanos(); - Http2PingFrame http2PingFrame2 = new DefaultHttp2PingFrame(pingId2, false); - channel.writeOutbound(http2PingFrame2); - - // the ack fo the first ping was not received, we consider it as a timeout error - Mockito.verify(listener).callCloseWithError(Mockito.eq(pingId1), Mockito.eq(currentTimeNanosForPing2)); - - Mockito.verify(listener).callStart(Mockito.eq(pingId2), Mockito.eq(currentTimeNanosForPing2)); - Assert.assertEquals(handler.getLastPingSendTime(), currentTimeNanosForPing2); - Assert.assertEquals(handler.getLastPingAckTime(), 0L); - Assert.assertEquals(handler.getLastPingId(), pingId2); - Assert.assertEquals(handler.getLastPingChannel(), channel); - - // reset - Mockito.reset(listener, handler); - } - - @Test - public void ignoredPingAckTest() { - Http2PingCallListener listener = Mockito.spy(new Http2PingHelper()); - Http2PingSendHandler handler = Mockito.spy(new Http2PingSendHandler(listener)); - - EmbeddedChannel channel = new EmbeddedChannel(handler); - - // write the http2 ping - long pingId1 = Time.currentTimeMillis(); - long currentTimeNanosForPing1 = 123456L; - Mockito.doReturn(currentTimeNanosForPing1).when(handler).getCurrentTimeNanos(); - Http2PingFrame http2PingFrame1 = new DefaultHttp2PingFrame(pingId1, false); - channel.writeOutbound(http2PingFrame1); - - // write http2 ping ack with different ping id, which will be ignored - long pingId2 = pingId1 + 1; - Http2PingFrame http2PingAckFrame = new DefaultHttp2PingFrame(pingId2, true); - channel.writeInbound(http2PingAckFrame); - - Assert.assertEquals(handler.getLastPingSendTime(), currentTimeNanosForPing1); - Assert.assertEquals(handler.getLastPingAckTime(), 0L); - Assert.assertEquals(handler.getLastPingId(), pingId1); - Assert.assertEquals(handler.getLastPingChannel(), channel); - Mockito.verify(listener, Mockito.never()).callClose(Mockito.eq(pingId2), Mockito.anyLong()); - - // reset - Mockito.reset(listener, handler); - } - - @Test - public void nonHttp2FrameTest() { - Http2PingCallListener listener = Mockito.spy(new Http2PingHelper()); - Http2PingSendHandler handler = Mockito.spy(new Http2PingSendHandler(listener)); - - EmbeddedChannel channel = new EmbeddedChannel(handler); - channel.writeOutbound("hello world"); - - Assert.assertEquals(handler.getLastPingSendTime(), 0L); - Assert.assertEquals(handler.getLastPingAckTime(), 0L); - Assert.assertEquals(handler.getLastPingId(), 0L); - Assert.assertNull(handler.getLastPingChannel()); - Mockito.verify(listener, Mockito.never()).callStart(Mockito.anyLong(), Mockito.anyLong()); - Mockito.verify(listener, Mockito.never()).callCloseWithError(Mockito.anyLong(), Mockito.anyLong()); - - channel.writeInbound("hello world"); - Assert.assertEquals(handler.getLastPingSendTime(), 0L); - Assert.assertEquals(handler.getLastPingAckTime(), 0L); - Assert.assertEquals(handler.getLastPingId(), 0L); - Assert.assertNull(handler.getLastPingChannel()); - Mockito.verify(listener, Mockito.never()).callStart(Mockito.anyLong(), Mockito.anyLong()); - - // reset - Mockito.reset(listener, handler); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestHttpMultiPartContentCodec.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestHttpMultiPartContentCodec.java deleted file mode 100644 index 2225bd0937d..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestHttpMultiPartContentCodec.java +++ /dev/null @@ -1,588 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import com.linkedin.alpini.netty4.misc.BasicFullHttpMultiPart; -import com.linkedin.alpini.netty4.misc.FullHttpMultiPart; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufOutputStream; -import io.netty.buffer.ByteBufUtil; -import io.netty.buffer.Unpooled; -import io.netty.channel.embedded.EmbeddedChannel; -import io.netty.handler.codec.ByteToMessageDecoder; -import io.netty.handler.codec.http.DefaultHttpResponse; -import io.netty.handler.codec.http.FullHttpRequest; -import io.netty.handler.codec.http.HttpContent; -import io.netty.handler.codec.http.HttpHeaderNames; -import io.netty.handler.codec.http.HttpObject; -import io.netty.handler.codec.http.HttpObjectAggregator; -import io.netty.handler.codec.http.HttpRequest; -import io.netty.handler.codec.http.HttpResponse; -import io.netty.handler.codec.http.HttpResponseStatus; -import io.netty.handler.codec.http.HttpUtil; -import io.netty.handler.codec.http.HttpVersion; -import io.netty.handler.codec.http.LastHttpContent; -import io.netty.handler.logging.LogLevel; -import io.netty.handler.logging.LoggingHandler; -import io.netty.util.AsciiString; -import io.netty.util.ReferenceCountUtil; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.CharBuffer; -import java.nio.charset.StandardCharsets; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import javax.mail.MessagingException; -import javax.mail.internet.InternetHeaders; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMultipart; -import org.apache.logging.log4j.LogManager; -import org.testng.Assert; -import org.testng.annotations.Test; - - -/** - * Created by acurtis on 3/23/17. - */ -@Test(groups = { "unit", "unit-leak", "leak" }, singleThreaded = true) -public final class TestHttpMultiPartContentCodec extends AbstractLeakDetect { - private EmbeddedChannel makeTestChannel() { - int maxInitialLineLength = 1024; - int maxHeaderSize = 8192; - int maxChunkSize = 16384; - int chunkSize = 8000; - int maxPartContentLength = 10240; - boolean validateHeaders = false; - - return new EmbeddedChannel( - new LoggingHandler("Egress", LogLevel.INFO), - new BasicHttpServerCodec(maxInitialLineLength, maxHeaderSize, maxChunkSize, validateHeaders), - new HttpByteBufContentChunker(maxChunkSize, chunkSize), - new HttpMultiPartContentCodec(maxPartContentLength), - new LoggingHandler(TestHttpMultiPartContentCodec.class, LogLevel.INFO)); - } - - private EmbeddedChannel makeTestAggregatedChannel() { - int maxInitialLineLength = 1024; - int maxHeaderSize = 8192; - int maxChunkSize = 16384; - int chunkSize = 8000; - int maxPartContentLength = 10240; - boolean validateHeaders = false; - - return new EmbeddedChannel( - new LoggingHandler("Egress", LogLevel.INFO), - new BasicHttpServerCodec(maxInitialLineLength, maxHeaderSize, maxChunkSize, validateHeaders), - new HttpByteBufContentChunker(maxChunkSize, chunkSize), - new HttpMultiPartContentCodec(maxPartContentLength), - new BasicHttpNonMultiPartAggregator(maxPartContentLength), - new LoggingHandler(TestHttpMultiPartContentCodec.class, LogLevel.INFO)); - } - - private EmbeddedChannel makeTestHttpAggregatedChannel() { - int maxInitialLineLength = 1024; - int maxHeaderSize = 8192; - int maxChunkSize = 16384; - int chunkSize = 8000; - int maxPartContentLength = 10240; - boolean validateHeaders = false; - - return new EmbeddedChannel( - new Log4J2LoggingHandler("Egress", LogLevel.INFO), - new BasicHttpServerCodec(maxInitialLineLength, maxHeaderSize, maxChunkSize, validateHeaders), - new HttpObjectAggregator(maxPartContentLength), - new HttpByteBufContentChunker(maxChunkSize, chunkSize), - new HttpMultiPartContentCodec(maxPartContentLength), - new Log4J2LoggingHandler(HttpMultiPartContentCodec.class, LogLevel.INFO), - new BasicHttpNonMultiPartAggregator(maxPartContentLength), - new Log4J2LoggingHandler(TestHttpMultiPartContentCodec.class, LogLevel.INFO)); - } - - static void assertRelease(Object o) { - Assert.assertTrue(ReferenceCountUtil.release(o)); - } - - @Test - public void basicTestMultiPart() { - EmbeddedChannel channel = makeTestChannel(); - - Assert.assertTrue( - channel.writeInbound( - encodeString( - "GET /Foo/bar/12345 HTTP/1.1\r\n" + "Host: foo-host.example.org\r\n" - + "Content-type: multipart/mixed; boundary=Part_123456\r\n" + "Content-length: " - + (0xf5 - 0x85 + 33) + "\r\n" + "\r\n" + "Ignore this fuzz\r\n" + "--Part_123456\r\n" - + "Content-type: text/plain\r\n" + "\r\n" + "Hello world\r\n" + "--Part_123456\r\n" - + "Content-type: text/plain\r\n" + "\r\n" + "Part two!\r\n" + "--Part_123456--\r\n" + "\r\n", - StandardCharsets.US_ASCII))); - - HttpObject object = channel.readInbound(); - Assert.assertTrue(object instanceof HttpRequest); - Assert.assertFalse(object instanceof FullHttpRequest); - - object = channel.readInbound(); - Assert.assertTrue(object instanceof FullHttpMultiPart); - Assert.assertEquals(((FullHttpMultiPart) object).content().toString(StandardCharsets.US_ASCII), "Hello world\r\n"); - assertRelease(object); - - object = channel.readInbound(); - Assert.assertTrue(object instanceof FullHttpMultiPart); - Assert.assertEquals(((FullHttpMultiPart) object).content().toString(StandardCharsets.US_ASCII), "Part two!\r\n"); - assertRelease(object); - - object = channel.readInbound(); - Assert.assertTrue(object instanceof LastHttpContent); - ReferenceCountUtil.release(object); - - HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, false); - response.headers() - .set( - HttpHeaderNames.CONTENT_TYPE, - "multipart/mixed; boundary=\"--=Part_8928ea38-13cb-5d79-66ac-553475448f79\""); - - FullHttpMultiPart part1 = new BasicFullHttpMultiPart( - ByteBufUtil.encodeString(POOLED_ALLOCATOR, CharBuffer.wrap("Test Part 1"), StandardCharsets.US_ASCII)); - FullHttpMultiPart part2 = new BasicFullHttpMultiPart( - ByteBufUtil.encodeString(POOLED_ALLOCATOR, CharBuffer.wrap("Test Part 2"), StandardCharsets.US_ASCII)); - FullHttpMultiPart part3 = new BasicFullHttpMultiPart( - ByteBufUtil.encodeString(POOLED_ALLOCATOR, CharBuffer.wrap("Test Part 3"), StandardCharsets.US_ASCII)); - - part1.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain"); - part1.headers().set(HttpHeaderNames.LOCATION, "/Foo/bar/12345/1"); - part2.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain"); - part2.headers().set(HttpHeaderNames.LOCATION, "/Foo/bar/12345/2"); - part3.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain"); - part3.headers().set(HttpHeaderNames.LOCATION, "/Foo/bar/12345/3"); - - HttpUtil.setContentLength(part2, part2.content().readableBytes()); - - Assert.assertTrue(channel.writeOutbound(response, part1, part2, part3, LastHttpContent.EMPTY_LAST_CONTENT)); - - ByteBuf out = Unpooled.EMPTY_BUFFER; - ByteBuf buf; - while ((buf = channel.readOutbound()) != null) { - out = ByteToMessageDecoder.COMPOSITE_CUMULATOR.cumulate(POOLED_ALLOCATOR, out, buf); - } - - LogManager.getLogger(getClass()).info("Output = {}", ByteBufUtil.prettyHexDump(out)); - Assert.assertEquals( - out.toString(StandardCharsets.US_ASCII), - "HTTP/1.1 200 OK\r\n" - + "content-type: multipart/mixed; boundary=\"--=Part_8928ea38-13cb-5d79-66ac-553475448f79\"\r\n" - + "transfer-encoding: chunked\r\n" + "\r\n" + "75\r\n" + "\r\n" - + "----=Part_8928ea38-13cb-5d79-66ac-553475448f79\r\n" + "content-type: text/plain\r\n" - + "location: /Foo/bar/12345/1\r\n" + "\r\n" + "Test Part 1\r\n" + "89\r\n" + "\r\n" - + "----=Part_8928ea38-13cb-5d79-66ac-553475448f79\r\n" + "content-type: text/plain\r\n" - + "location: /Foo/bar/12345/2\r\n" + "content-length: 11\r\n" + "\r\n" + "Test Part 2\r\n" + "75\r\n" - + "\r\n" + "----=Part_8928ea38-13cb-5d79-66ac-553475448f79\r\n" + "content-type: text/plain\r\n" - + "location: /Foo/bar/12345/3\r\n" + "\r\n" + "Test Part 3\r\n" + "34\r\n" + "\r\n" - + "----=Part_8928ea38-13cb-5d79-66ac-553475448f79--\r\n" + "\r\n" + "0\r\n" + "\r\n"); - assertRelease(out); - channel.finishAndReleaseAll(); - } - - @Test - public void basicTestNonMultiPart() { - EmbeddedChannel channel = makeTestChannel(); - - Assert.assertTrue( - channel.writeInbound( - encodeString( - "GET /Foo/bar/12345 HTTP/1.1\r\n" + "Host: foo-host.example.org\r\n" + "Content-type: text/plain\r\n" - + "Content-length: " + (0xf5 - 0x85 + 33) + "\r\n" + "\r\n" + "Ignore this fuzz\r\n" - + "--Part_123456\r\n" + "Content-type: text/plain\r\n" + "\r\n" + "Hello world\r\n" - + "--Part_123456\r\n" + "Content-type: text/plain\r\n" + "\r\n" + "Part two!\r\n" - + "--Part_123456--\r\n" + "\r\n", - StandardCharsets.US_ASCII))); - - HttpObject object = channel.readInbound(); - Assert.assertTrue(object instanceof HttpRequest); - Assert.assertFalse(object instanceof FullHttpRequest); - - object = channel.readInbound(); - Assert.assertTrue(object instanceof LastHttpContent); - - Assert.assertEquals( - ((LastHttpContent) object).content().toString(StandardCharsets.US_ASCII), - "Ignore this fuzz\r\n" + "--Part_123456\r\n" + "Content-type: text/plain\r\n" + "\r\n" + "Hello world\r\n" - + "--Part_123456\r\n" + "Content-type: text/plain\r\n" + "\r\n" + "Part two!\r\n" + "--Part_123456--\r\n"); - assertRelease(object); - - HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, false); - response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain"); - - ByteBuf content = encodeString("This is a simple test response\r\n", StandardCharsets.US_ASCII); - - HttpUtil.setContentLength(response, content.readableBytes()); - - Assert.assertTrue(channel.writeOutbound(response, content, LastHttpContent.EMPTY_LAST_CONTENT)); - - ByteBuf out = Unpooled.EMPTY_BUFFER; - ByteBuf buf; - while ((buf = channel.readOutbound()) != null) { - out = ByteToMessageDecoder.COMPOSITE_CUMULATOR.cumulate(POOLED_ALLOCATOR, out, buf); - } - - LogManager.getLogger(getClass()).info("Output = {}", ByteBufUtil.prettyHexDump(out)); - Assert.assertEquals( - out.toString(StandardCharsets.US_ASCII), - "HTTP/1.1 200 OK\r\n" + "content-type: text/plain\r\n" + "content-length: 32\r\n" + "\r\n" - + "This is a simple test response\r\n"); - assertRelease(out); - channel.finishAndReleaseAll(); - } - - @Test(invocationCount = 5) - public void basicTestMultiPartAggregated() { - testMultiPartAggregated(makeTestAggregatedChannel()); - } - - @Test(invocationCount = 5) - public void basicTestNonMultiPartAggregated() { - testNonMultiPartAggregated(makeTestAggregatedChannel()); - } - - @Test - public void basicTestMultiPartHttpAggregatedBoundary() { - testMultiPartBoundary(makeTestHttpAggregatedChannel()); - } - - @Test - public void basicTestMultiPartHttpAggregated() { - testMultiPartAggregated(makeTestHttpAggregatedChannel()); - } - - @Test - public void basicTestNonMultiPartHttpAggregated() { - testNonMultiPartAggregated(makeTestHttpAggregatedChannel()); - } - - @Test - public void fullTestMultiPartHttpAggregated() throws IOException, MessagingException { - testNestedMultiPartBoundary(makeTestHttpAggregatedChannel()); - } - - private void testMultiPartAggregated(EmbeddedChannel channel) { - - Assert.assertTrue( - channel.writeInbound( - encodeString( - "GET /Foo/bar/12345 HTTP/1.1\r\n" + "Host: foo-host.example.org\r\n" - + "Content-type: multipart/mixed; boundary=Part_123456\r\n" + "Content-length: " - + (0xf5 - 0x85 + 15) + "\r\n" + "\r\n" + "--Part_123456\r\n" + "Content-type: text/plain\r\n" - + "\r\n" + "Hello world\r\n" + "--Part_123456\r\n" + "Content-type: text/plain\r\n" + "\r\n" - + "Part two!\r\n" + "--Part_123456--\r\n" + "\r\n", - StandardCharsets.US_ASCII))); - - HttpObject object = channel.readInbound(); - Assert.assertTrue(object instanceof HttpRequest); - Assert.assertFalse(object instanceof FullHttpRequest); - - object = channel.readInbound(); - Assert.assertTrue(object instanceof FullHttpMultiPart); - Assert.assertEquals(((FullHttpMultiPart) object).content().toString(StandardCharsets.US_ASCII), "Hello world\r\n"); - assertRelease(object); - - object = channel.readInbound(); - Assert.assertTrue(object instanceof FullHttpMultiPart); - Assert.assertEquals(((FullHttpMultiPart) object).content().toString(StandardCharsets.US_ASCII), "Part two!\r\n"); - assertRelease(object); - - object = channel.readInbound(); - Assert.assertTrue(object instanceof LastHttpContent); - ReferenceCountUtil.release(object); - - HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, false); - response.headers() - .set( - HttpHeaderNames.CONTENT_TYPE, - "multipart/mixed; boundary=\"--=Part_8928ea38-13cb-5d79-66ac-553475448f79\""); - - FullHttpMultiPart part1 = new BasicFullHttpMultiPart(encodeString("Test Part 1", StandardCharsets.US_ASCII)); - FullHttpMultiPart part2 = new BasicFullHttpMultiPart(encodeString("Test Part 2", StandardCharsets.US_ASCII)); - FullHttpMultiPart part3 = new BasicFullHttpMultiPart(encodeString("Test Part 3", StandardCharsets.US_ASCII)); - - part1.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain"); - part1.headers().set(HttpHeaderNames.LOCATION, "/Foo/bar/12345/1"); - part2.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain"); - part2.headers().set(HttpHeaderNames.LOCATION, "/Foo/bar/12345/2"); - part3.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain"); - part3.headers().set(HttpHeaderNames.LOCATION, "/Foo/bar/12345/3"); - - HttpUtil.setContentLength(part2, part2.content().readableBytes()); - - Assert.assertTrue(channel.writeOutbound(response, part1, part2, part3, LastHttpContent.EMPTY_LAST_CONTENT)); - - ByteBuf out = Unpooled.EMPTY_BUFFER; - ByteBuf buf; - while ((buf = channel.readOutbound()) != null) { - out = ByteToMessageDecoder.COMPOSITE_CUMULATOR.cumulate(POOLED_ALLOCATOR, out, buf); - } - - LogManager.getLogger(getClass()).info("Output = {}", ByteBufUtil.prettyHexDump(out)); - Assert.assertEquals( - out.toString(StandardCharsets.US_ASCII), - "HTTP/1.1 200 OK\r\n" - + "content-type: multipart/mixed; boundary=\"--=Part_8928ea38-13cb-5d79-66ac-553475448f79\"\r\n" - + "transfer-encoding: chunked\r\n" + "\r\n" + "75\r\n" + "\r\n" - + "----=Part_8928ea38-13cb-5d79-66ac-553475448f79\r\n" + "content-type: text/plain\r\n" - + "location: /Foo/bar/12345/1\r\n" + "\r\n" + "Test Part 1\r\n" + "89\r\n" + "\r\n" - + "----=Part_8928ea38-13cb-5d79-66ac-553475448f79\r\n" + "content-type: text/plain\r\n" - + "location: /Foo/bar/12345/2\r\n" + "content-length: 11\r\n" + "\r\n" + "Test Part 2\r\n" + "75\r\n" - + "\r\n" + "----=Part_8928ea38-13cb-5d79-66ac-553475448f79\r\n" + "content-type: text/plain\r\n" - + "location: /Foo/bar/12345/3\r\n" + "\r\n" + "Test Part 3\r\n" + "34\r\n" + "\r\n" - + "----=Part_8928ea38-13cb-5d79-66ac-553475448f79--\r\n" + "\r\n" + "0\r\n" + "\r\n"); - assertRelease(out); - channel.finishAndReleaseAll(); - } - - private void testNonMultiPartAggregated(EmbeddedChannel channel) { - - Assert.assertTrue( - channel.writeInbound( - encodeString( - "GET /Foo/bar/12345 HTTP/1.1\r\n" + "Host: foo-host.example.org\r\n" + "Content-type: text/plain\r\n" - + "Content-length: " + (0xf5 - 0x85 + 15) + "\r\n" + "\r\n" + "--Part_123456\r\n" - + "Content-type: text/plain\r\n" + "\r\n" + "Hello world\r\n" + "--Part_123456\r\n" - + "Content-type: text/plain\r\n" + "\r\n" + "Part two!\r\n" + "--Part_123456--\r\n" + "\r\n", - StandardCharsets.US_ASCII))); - - HttpObject object = channel.readInbound(); - Assert.assertTrue(object instanceof FullHttpRequest); - Assert.assertEquals( - ((HttpContent) object).content().toString(StandardCharsets.US_ASCII), - "--Part_123456\r\n" + "Content-type: text/plain\r\n" + "\r\n" + "Hello world\r\n" + "--Part_123456\r\n" - + "Content-type: text/plain\r\n" + "\r\n" + "Part two!\r\n" + "--Part_123456--\r\n"); - assertRelease(object); - - HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, false); - response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain"); - - ByteBuf content = encodeString("This is a simple test response\r\n", StandardCharsets.US_ASCII); - - HttpUtil.setContentLength(response, content.readableBytes()); - - Assert.assertTrue(channel.writeOutbound(response, content.retainedDuplicate(), LastHttpContent.EMPTY_LAST_CONTENT)); - - ByteBuf out = Unpooled.EMPTY_BUFFER; - ByteBuf buf; - while ((buf = channel.readOutbound()) != null) { - out = ByteToMessageDecoder.COMPOSITE_CUMULATOR.cumulate(POOLED_ALLOCATOR, out, buf); - } - - LogManager.getLogger(getClass()).info("Output = {}", ByteBufUtil.prettyHexDump(out)); - Assert.assertEquals( - out.toString(StandardCharsets.US_ASCII), - "HTTP/1.1 200 OK\r\n" + "content-type: text/plain\r\n" + "content-length: 32\r\n" + "\r\n" - + "This is a simple test response\r\n"); - assertRelease(out); - assertRelease(content); - channel.finishAndReleaseAll(); - } - - private void testMultiPartBoundary(EmbeddedChannel channel) { - - Assert.assertTrue( - channel.writeInbound( - encodeString( - "GET /Foo/bar/12345 HTTP/1.1\r\n" + "Host: foo-host.example.org\r\n" - + "Content-type: multipart/mixed; boundary=Part_123456\r\n" + "Content-length: " - + (0xf5 - 0x85 + 15) + "\r\n" + "\r\n" + "--Part_123456\r\n" + "Content-type: text/plain\r\n" - + "\r\n" + "Hello world\r\n" + "--Part_123456\r\n" + "Content-type: text/plain\r\n" + "\r\n" - + "Part two!\r\n" + "--Part_123456--\r\n" + "\r\n", - StandardCharsets.US_ASCII))); - - HttpObject object = channel.readInbound(); - Assert.assertTrue(object instanceof HttpRequest); - Assert.assertFalse(object instanceof FullHttpRequest); - - object = channel.readInbound(); - Assert.assertTrue(object instanceof FullHttpMultiPart); - Assert.assertEquals(((FullHttpMultiPart) object).content().toString(StandardCharsets.US_ASCII), "Hello world\r\n"); - assertRelease(object); - - object = channel.readInbound(); - Assert.assertTrue(object instanceof FullHttpMultiPart); - Assert.assertEquals(((FullHttpMultiPart) object).content().toString(StandardCharsets.US_ASCII), "Part two!\r\n"); - assertRelease(object); - - object = channel.readInbound(); - Assert.assertTrue(object instanceof LastHttpContent); - ReferenceCountUtil.release(object); - - HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, false); - response.headers().set(HttpHeaderNames.CONTENT_TYPE, "multipart/mixed"); - - FullHttpMultiPart part1 = new BasicFullHttpMultiPart(encodeString("Test Part 1", StandardCharsets.US_ASCII)); - FullHttpMultiPart part2 = new BasicFullHttpMultiPart(encodeString("Test Part 2", StandardCharsets.US_ASCII)); - FullHttpMultiPart part3 = new BasicFullHttpMultiPart(encodeString("Test Part 3", StandardCharsets.US_ASCII)); - - part1.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain"); - part1.headers().set(HttpHeaderNames.LOCATION, "/Foo/bar/12345/1"); - part2.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain"); - part2.headers().set(HttpHeaderNames.LOCATION, "/Foo/bar/12345/2"); - part3.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain"); - part3.headers().set(HttpHeaderNames.LOCATION, "/Foo/bar/12345/3"); - - HttpUtil.setContentLength(part2, part2.content().readableBytes()); - - Assert.assertTrue(channel.writeOutbound(response, part1, part2, part3, LastHttpContent.EMPTY_LAST_CONTENT)); - - ByteBuf out = Unpooled.EMPTY_BUFFER; - ByteBuf buf; - while ((buf = channel.readOutbound()) != null) { - out = ByteToMessageDecoder.COMPOSITE_CUMULATOR.cumulate(POOLED_ALLOCATOR, out, buf); - } - - LogManager.getLogger(getClass()).info("Output = {}", ByteBufUtil.prettyHexDump(out)); - String content = out.toString(StandardCharsets.US_ASCII); - - Matcher m = Pattern.compile("\"--=Part_(........-....-....-....-............)\"").matcher(content); - Assert.assertTrue(m.find()); - String boundary = m.group(1); - - Assert.assertEquals( - content, - "HTTP/1.1 200 OK\r\n" + "content-type: multipart/mixed; boundary=\"--=Part_" + boundary + "\"\r\n" - + "transfer-encoding: chunked\r\n" + "\r\n" + "75\r\n" + "\r\n" + "----=Part_" + boundary + "\r\n" - + "content-type: text/plain\r\n" + "location: /Foo/bar/12345/1\r\n" + "\r\n" + "Test Part 1\r\n" + "89\r\n" - + "\r\n" + "----=Part_" + boundary + "\r\n" + "content-type: text/plain\r\n" - + "location: /Foo/bar/12345/2\r\n" + "content-length: 11\r\n" + "\r\n" + "Test Part 2\r\n" + "75\r\n" - + "\r\n" + "----=Part_" + boundary + "\r\n" + "content-type: text/plain\r\n" - + "location: /Foo/bar/12345/3\r\n" + "\r\n" + "Test Part 3\r\n" + "34\r\n" + "\r\n" + "----=Part_" - + boundary + "--\r\n" + "\r\n" + "0\r\n" + "\r\n"); - assertRelease(out); - channel.finishAndReleaseAll(); - } - - private MimeBodyPart makePart(String type, byte[] bytes) throws MessagingException { - InternetHeaders headers = new InternetHeaders(); - headers.setHeader("Content-Type", type); - headers.setHeader("Content-Length", Integer.toString(bytes.length)); - return new MimeBodyPart(headers, bytes); - } - - private void testNestedMultiPartBoundary(EmbeddedChannel channel) throws MessagingException, IOException { - ByteBuf requestBytes = POOLED_ALLOCATOR.buffer(); - AsciiString innerContent; - { - MimeMultipart mp = new MimeMultipart(); - mp.addBodyPart(makePart("text/plain", "Hello World".getBytes())); - mp.addBodyPart(new MimeBodyPart(new InternetHeaders(), "Hello World2".getBytes())); - mp.addBodyPart(makePart("text/plain", new byte[0])); - - ByteArrayOutputStream innerBytes = new ByteArrayOutputStream(); - mp.writeTo(innerBytes); - innerContent = new AsciiString(innerBytes.toByteArray()); - - mp.addBodyPart(makePart(mp.getContentType(), innerBytes.toByteArray())); - - mp.addBodyPart(makePart("text/plain", "Goodbyte world\r\n".getBytes())); - - ByteBuf content = POOLED_ALLOCATOR.buffer(); - mp.writeTo(new ByteBufOutputStream(content)); - - ByteBufUtil.writeAscii( - requestBytes, - "GET /foo/bar/54321 HTTP/1.1\r\n" + "Host: foo-host.example.org\r\n" + "Content-Type: "); - ByteBufUtil.writeAscii(requestBytes, mp.getContentType()); - ByteBufUtil.writeAscii(requestBytes, "\r\n" + "Content-length: "); - ByteBufUtil.writeAscii(requestBytes, Integer.toString(content.readableBytes())); - ByteBufUtil.writeAscii(requestBytes, "\r\n\r\n"); - requestBytes.writeBytes(content); - - content.release(); - } - - Assert.assertTrue(channel.writeInbound(requestBytes)); - - HttpObject object = channel.readInbound(); - Assert.assertTrue(object instanceof HttpRequest); - Assert.assertFalse(object instanceof FullHttpRequest); - - object = channel.readInbound(); - Assert.assertTrue(object instanceof FullHttpMultiPart); - Assert.assertEquals(((FullHttpMultiPart) object).content().toString(StandardCharsets.US_ASCII), "Hello World"); - assertRelease(object); - - object = channel.readInbound(); - Assert.assertTrue(object instanceof FullHttpMultiPart); - Assert.assertEquals(((FullHttpMultiPart) object).content().toString(StandardCharsets.US_ASCII), "Hello World2\r\n"); - assertRelease(object); - - object = channel.readInbound(); - Assert.assertTrue(object instanceof FullHttpMultiPart); - Assert.assertEquals(((FullHttpMultiPart) object).content().toString(StandardCharsets.US_ASCII), ""); - assertRelease(object); - - object = channel.readInbound(); - Assert.assertTrue(object instanceof FullHttpMultiPart); - Assert.assertEquals( - ((FullHttpMultiPart) object).content().toString(StandardCharsets.US_ASCII), - innerContent.toString()); - assertRelease(object); - - object = channel.readInbound(); - Assert.assertTrue(object instanceof FullHttpMultiPart); - Assert - .assertEquals(((FullHttpMultiPart) object).content().toString(StandardCharsets.US_ASCII), "Goodbyte world\r\n"); - assertRelease(object); - - object = channel.readInbound(); - Assert.assertTrue(object instanceof LastHttpContent); - ReferenceCountUtil.release(object); - - HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, false); - response.headers().set(HttpHeaderNames.CONTENT_TYPE, "multipart/mixed"); - - FullHttpMultiPart part1 = new BasicFullHttpMultiPart(encodeString("Test Part 1", StandardCharsets.US_ASCII)); - FullHttpMultiPart part2 = new BasicFullHttpMultiPart(encodeString("Test Part 2", StandardCharsets.US_ASCII)); - FullHttpMultiPart part3 = new BasicFullHttpMultiPart(encodeString("Test Part 3", StandardCharsets.US_ASCII)); - - part1.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain"); - part1.headers().set(HttpHeaderNames.LOCATION, "/Foo/bar/12345/1"); - part2.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain"); - part2.headers().set(HttpHeaderNames.LOCATION, "/Foo/bar/12345/2"); - part3.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain"); - part3.headers().set(HttpHeaderNames.LOCATION, "/Foo/bar/12345/3"); - - HttpUtil.setContentLength(part2, part2.content().readableBytes()); - - Assert.assertTrue(channel.writeOutbound(response, part1, part2, part3, LastHttpContent.EMPTY_LAST_CONTENT)); - - ByteBuf out = Unpooled.EMPTY_BUFFER; - ByteBuf buf; - while ((buf = channel.readOutbound()) != null) { - out = ByteToMessageDecoder.COMPOSITE_CUMULATOR.cumulate(POOLED_ALLOCATOR, out, buf); - } - - LogManager.getLogger(getClass()).info("Output = {}", ByteBufUtil.prettyHexDump(out)); - String content = out.toString(StandardCharsets.US_ASCII); - - Matcher m = Pattern.compile("\"--=Part_(........-....-....-....-............)\"").matcher(content); - Assert.assertTrue(m.find()); - String boundary = m.group(1); - - Assert.assertEquals( - content, - "HTTP/1.1 200 OK\r\n" + "content-type: multipart/mixed; boundary=\"--=Part_" + boundary + "\"\r\n" - + "transfer-encoding: chunked\r\n" + "\r\n" + "75\r\n" + "\r\n" + "----=Part_" + boundary + "\r\n" - + "content-type: text/plain\r\n" + "location: /Foo/bar/12345/1\r\n" + "\r\n" + "Test Part 1\r\n" + "89\r\n" - + "\r\n" + "----=Part_" + boundary + "\r\n" + "content-type: text/plain\r\n" - + "location: /Foo/bar/12345/2\r\n" + "content-length: 11\r\n" + "\r\n" + "Test Part 2\r\n" + "75\r\n" - + "\r\n" + "----=Part_" + boundary + "\r\n" + "content-type: text/plain\r\n" - + "location: /Foo/bar/12345/3\r\n" + "\r\n" + "Test Part 3\r\n" + "34\r\n" + "\r\n" + "----=Part_" - + boundary + "--\r\n" + "\r\n" + "0\r\n" + "\r\n"); - assertRelease(out); - channel.finishAndReleaseAll(); - } - - /** - * since TestNG tends to sort by method name, this tries to be the last test - * in the class. We do this because the AfterClass annotated methods may - * execute after other tests classes have run and doesn't execute immediately - * after the methods in this test class. - */ - @Test(alwaysRun = true) - public final void zz9PluralZAlpha() throws InterruptedException { - finallyLeakDetect(); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestHttpServerConcurrencyObserver.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestHttpServerConcurrencyObserver.java deleted file mode 100644 index 14a62519014..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestHttpServerConcurrencyObserver.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import com.linkedin.alpini.base.monitoring.CallTracker; -import com.linkedin.alpini.base.monitoring.CallTrackerImpl; -import io.netty.buffer.Unpooled; -import io.netty.channel.embedded.EmbeddedChannel; -import io.netty.handler.codec.http.DefaultHttpContent; -import io.netty.handler.codec.http.DefaultHttpRequest; -import io.netty.handler.codec.http.DefaultHttpResponse; -import io.netty.handler.codec.http.HttpMethod; -import io.netty.handler.codec.http.HttpObject; -import io.netty.handler.codec.http.HttpResponseStatus; -import io.netty.handler.codec.http.HttpVersion; -import io.netty.handler.codec.http.LastHttpContent; -import java.nio.charset.StandardCharsets; -import org.testng.Assert; -import org.testng.annotations.Test; - - -/** - * Created by acurtis on 12/12/17. - */ -public class TestHttpServerConcurrencyObserver { - @Test(groups = "unit") - public void testBasic() throws InterruptedException { - CallTracker callTracker = new CallTrackerImpl(); - EmbeddedChannel channel = new EmbeddedChannel(new HttpServerConcurrencyObserver(callTracker)); - - HttpObject object = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/"); - channel.writeOneInbound(object).sync(); - Assert.assertSame(channel.readInbound(), object); - Assert.assertEquals(callTracker.getCurrentConcurrency(), 1); - channel.writeOneInbound(LastHttpContent.EMPTY_LAST_CONTENT).sync(); - Assert.assertSame(channel.readInbound(), LastHttpContent.EMPTY_LAST_CONTENT); - Assert.assertEquals(callTracker.getCurrentConcurrency(), 1); - - channel.writeOneInbound(object).sync(); - Assert.assertSame(channel.readInbound(), object); - Assert.assertEquals(callTracker.getCurrentConcurrency(), 2); - object = new DefaultHttpContent(Unpooled.copiedBuffer("Hello world", StandardCharsets.UTF_8)); - channel.writeOneInbound(object).sync(); - Assert.assertSame(channel.readInbound(), object); - Assert.assertEquals(callTracker.getCurrentConcurrency(), 2); - channel.writeOneInbound(LastHttpContent.EMPTY_LAST_CONTENT).sync(); - Assert.assertSame(channel.readInbound(), LastHttpContent.EMPTY_LAST_CONTENT); - Assert.assertEquals(callTracker.getCurrentConcurrency(), 2); - - object = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/"); - channel.writeOneInbound(object).sync(); - Assert.assertSame(channel.readInbound(), object); - Assert.assertEquals(callTracker.getCurrentConcurrency(), 3); - channel.writeOneInbound(LastHttpContent.EMPTY_LAST_CONTENT).sync(); - Assert.assertSame(channel.readInbound(), LastHttpContent.EMPTY_LAST_CONTENT); - Assert.assertEquals(callTracker.getCurrentConcurrency(), 3); - - object = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); - channel.writeOneOutbound(object); - channel.flushOutbound(); - Assert.assertSame(channel.readOutbound(), object); - Assert.assertEquals(callTracker.getCurrentConcurrency(), 3); - channel.writeOneOutbound(LastHttpContent.EMPTY_LAST_CONTENT); - channel.flushOutbound(); - Assert.assertSame(channel.readOutbound(), LastHttpContent.EMPTY_LAST_CONTENT); - Assert.assertEquals(callTracker.getCurrentConcurrency(), 2); - - object = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.INTERNAL_SERVER_ERROR); - channel.writeOneOutbound(object); - channel.flushOutbound(); - Assert.assertSame(channel.readOutbound(), object); - Assert.assertEquals(callTracker.getCurrentConcurrency(), 2); - Assert.assertEquals(callTracker.getCurrentErrorCountTotal(), 0); - channel.writeOneOutbound(LastHttpContent.EMPTY_LAST_CONTENT); - channel.flushOutbound(); - Assert.assertSame(channel.readOutbound(), LastHttpContent.EMPTY_LAST_CONTENT); - Assert.assertEquals(callTracker.getCurrentConcurrency(), 1); - Assert.assertEquals(callTracker.getCurrentErrorCountTotal(), 1); - - channel.writeOneOutbound(object); - channel.flushOutbound(); - Assert.assertSame(channel.readOutbound(), object); - Assert.assertEquals(callTracker.getCurrentConcurrency(), 1); - object = new DefaultHttpContent(Unpooled.copiedBuffer("Goodbye world", StandardCharsets.UTF_8)); - channel.writeOneOutbound(object); - channel.flushOutbound(); - Assert.assertSame(channel.readOutbound(), object); - Assert.assertEquals(callTracker.getCurrentConcurrency(), 1); - channel.writeOneOutbound(LastHttpContent.EMPTY_LAST_CONTENT); - channel.flushOutbound(); - Assert.assertSame(channel.readOutbound(), LastHttpContent.EMPTY_LAST_CONTENT); - Assert.assertEquals(callTracker.getCurrentConcurrency(), 0); - - channel.close().sync(); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestLog4J2FrameLogger.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestLog4J2FrameLogger.java deleted file mode 100644 index 73a67093c67..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestLog4J2FrameLogger.java +++ /dev/null @@ -1,596 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.http2.Http2Flags; -import io.netty.handler.codec.http2.Http2FrameLogger; -import io.netty.handler.codec.http2.Http2Headers; -import io.netty.handler.codec.http2.Http2Settings; -import java.nio.charset.StandardCharsets; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.Logger; -import org.mockito.ArgumentCaptor; -import org.mockito.Mockito; -import org.testng.Assert; -import org.testng.annotations.Test; - - -/** - * Created by acurtis on 4/23/18. - */ -public class TestLog4J2FrameLogger { - private final Logger _mockLogger = Mockito.mock(Logger.class); - - @Test(groups = "unit") - public void testConstruct() throws Exception { - Assert.assertNotNull(new Log4J2FrameLogger(Level.DEBUG)); - } - - @Test(groups = "unit") - public void testLogData() { - Mockito.reset(_mockLogger); - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - class Harness extends Log4J2FrameLogger { - private Harness() { - super(Level.DEBUG); - } - - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Log4J2FrameLogger handler = new Harness(); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Channel ch = Mockito.mock(Channel.class); - Mockito.when(ctx.channel()).thenReturn(ch); - ByteBuf data = Unpooled.copiedBuffer("Hello world", StandardCharsets.US_ASCII); - - handler.logData(Http2FrameLogger.Direction.INBOUND, ctx, 1, data, 42, true); - - ArgumentCaptor message = ArgumentCaptor.forClass(Object.class); - Mockito.verify(_mockLogger).isEnabled(Mockito.eq(Level.DEBUG)); - Mockito.verify(_mockLogger) - .log( - Mockito.eq(Level.DEBUG), - Mockito.eq("{} {} DATA: streamId={} padding={} endStream={} length={} bytes={}"), - Mockito.same(ch), - Mockito.eq("INBOUND"), - Mockito.eq(1), - Mockito.eq(42), - Mockito.eq(true), - Mockito.eq(11), - message.capture()); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Assert.assertEquals(String.valueOf(message.getValue()), "48656c6c6f20776f726c64"); - Mockito.verify(ctx).channel(); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testLogHeaders1() { - Mockito.reset(_mockLogger); - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - class Harness extends Log4J2FrameLogger { - private Harness() { - super(Level.DEBUG); - } - - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Log4J2FrameLogger handler = new Harness(); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Channel ch = Mockito.mock(Channel.class); - Mockito.when(ctx.channel()).thenReturn(ch); - Http2Headers data = Mockito.mock(Http2Headers.class, "headers"); - - handler.logHeaders(Http2FrameLogger.Direction.INBOUND, ctx, 1, data, 42, true); - - Mockito.verify(_mockLogger) - .log( - Mockito.eq(Level.DEBUG), - Mockito.eq("{} {} HEADERS: streamId={} headers={} padding={} endStream={}"), - Mockito.same(ch), - Mockito.eq("INBOUND"), - Mockito.eq(1), - Mockito.same(data), - Mockito.eq(42), - Mockito.eq(true)); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Mockito.verify(ctx).channel(); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testLogHeaders2() { - Mockito.reset(_mockLogger); - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - class Harness extends Log4J2FrameLogger { - private Harness() { - super(Level.DEBUG); - } - - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Log4J2FrameLogger handler = new Harness(); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Channel ch = Mockito.mock(Channel.class); - Mockito.when(ctx.channel()).thenReturn(ch); - Http2Headers data = Mockito.mock(Http2Headers.class, "headers"); - - handler.logHeaders(Http2FrameLogger.Direction.INBOUND, ctx, 5, data, 1, (short) 100, false, 42, true); - - Mockito.verify(_mockLogger) - .log( - Mockito.eq(Level.DEBUG), - Mockito.eq( - "{} {} HEADERS: streamId={} headers={} streamDependency={} weight={} exclusive={} padding={} endStream={}"), - Mockito.same(ch), - Mockito.eq("INBOUND"), - Mockito.eq(5), - Mockito.same(data), - Mockito.eq(1), - Mockito.eq((short) 100), - Mockito.eq(false), - Mockito.eq(42), - Mockito.eq(true)); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Mockito.verify(ctx).channel(); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testLogPriority() { - Mockito.reset(_mockLogger); - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - class Harness extends Log4J2FrameLogger { - private Harness() { - super(Level.DEBUG); - } - - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Log4J2FrameLogger handler = new Harness(); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Channel ch = Mockito.mock(Channel.class); - Mockito.when(ctx.channel()).thenReturn(ch); - - handler.logPriority(Http2FrameLogger.Direction.INBOUND, ctx, 5, 0, (short) 100, false); - - Mockito.verify(_mockLogger) - .log( - Mockito.eq(Level.DEBUG), - Mockito.eq("{} {} PRIORITY: streamId={} streamDependency={} weight={} exclusive={}"), - Mockito.same(ch), - Mockito.eq("INBOUND"), - Mockito.eq(5), - Mockito.eq(0), - Mockito.eq((short) 100), - Mockito.eq(false)); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Mockito.verify(ctx).channel(); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testLogRstStream() { - Mockito.reset(_mockLogger); - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - class Harness extends Log4J2FrameLogger { - private Harness() { - super(Level.DEBUG); - } - - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Log4J2FrameLogger handler = new Harness(); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Channel ch = Mockito.mock(Channel.class); - Mockito.when(ctx.channel()).thenReturn(ch); - - handler.logRstStream(Http2FrameLogger.Direction.INBOUND, ctx, 5, 0); - - Mockito.verify(_mockLogger) - .log( - Mockito.eq(Level.DEBUG), - Mockito.eq("{} {} RST_STREAM: streamId={} errorCode={}"), - Mockito.same(ch), - Mockito.eq("INBOUND"), - Mockito.eq(5), - Mockito.eq(0L)); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Mockito.verify(ctx).channel(); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testLogSettingsAck() { - Mockito.reset(_mockLogger); - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - class Harness extends Log4J2FrameLogger { - private Harness() { - super(Level.DEBUG); - } - - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Log4J2FrameLogger handler = new Harness(); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Channel ch = Mockito.mock(Channel.class); - Mockito.when(ctx.channel()).thenReturn(ch); - - handler.logSettingsAck(Http2FrameLogger.Direction.INBOUND, ctx); - - Mockito.verify(_mockLogger) - .log(Mockito.eq(Level.DEBUG), Mockito.eq("{} {} SETTINGS: ack=true"), Mockito.same(ch), Mockito.eq("INBOUND")); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Mockito.verify(ctx).channel(); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testLogSettings() { - Mockito.reset(_mockLogger); - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - class Harness extends Log4J2FrameLogger { - private Harness() { - super(Level.DEBUG); - } - - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Log4J2FrameLogger handler = new Harness(); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Channel ch = Mockito.mock(Channel.class); - Mockito.when(ctx.channel()).thenReturn(ch); - Http2Settings settings = new Http2Settings(); - - handler.logSettings(Http2FrameLogger.Direction.INBOUND, ctx, settings); - - Mockito.verify(_mockLogger) - .log( - Mockito.eq(Level.DEBUG), - Mockito.eq("{} {} SETTINGS: ack=false settings={}"), - Mockito.same(ch), - Mockito.eq("INBOUND"), - Mockito.same(settings)); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Mockito.verify(ctx).channel(); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testLogPing() { - Mockito.reset(_mockLogger); - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - class Harness extends Log4J2FrameLogger { - private Harness() { - super(Level.DEBUG); - } - - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Log4J2FrameLogger handler = new Harness(); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Channel ch = Mockito.mock(Channel.class); - Mockito.when(ctx.channel()).thenReturn(ch); - long data = 0xdeadbeefL; - - handler.logPing(Http2FrameLogger.Direction.INBOUND, ctx, data); - - Mockito.verify(_mockLogger) - .log( - Mockito.eq(Level.DEBUG), - Mockito.eq("{} {} PING: ack=false bytes={}"), - Mockito.same(ch), - Mockito.eq("INBOUND"), - Mockito.eq(data)); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Mockito.verify(ctx).channel(); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testLogPingAck() { - Mockito.reset(_mockLogger); - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - class Harness extends Log4J2FrameLogger { - private Harness() { - super(Level.DEBUG); - } - - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Log4J2FrameLogger handler = new Harness(); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Channel ch = Mockito.mock(Channel.class); - Mockito.when(ctx.channel()).thenReturn(ch); - long data = 0xdeadbeefL; - - handler.logPingAck(Http2FrameLogger.Direction.INBOUND, ctx, data); - - Mockito.verify(_mockLogger) - .log( - Mockito.eq(Level.DEBUG), - Mockito.eq("{} {} PING: ack=true bytes={}"), - Mockito.same(ch), - Mockito.eq("INBOUND"), - Mockito.eq(data)); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Mockito.verify(ctx).channel(); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testLogPushPromise() { - Mockito.reset(_mockLogger); - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - class Harness extends Log4J2FrameLogger { - private Harness() { - super(Level.DEBUG); - } - - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Log4J2FrameLogger handler = new Harness(); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Channel ch = Mockito.mock(Channel.class); - Mockito.when(ctx.channel()).thenReturn(ch); - Http2Headers headers = Mockito.mock(Http2Headers.class, "headers"); - - handler.logPushPromise(Http2FrameLogger.Direction.INBOUND, ctx, 5, 8, headers, 42); - - Mockito.verify(_mockLogger) - .log( - Mockito.eq(Level.DEBUG), - Mockito.eq("{} {} PUSH_PROMISE: streamId={} promisedStreamId={} headers={} padding={}"), - Mockito.same(ch), - Mockito.eq("INBOUND"), - Mockito.eq(5), - Mockito.eq(8), - Mockito.same(headers), - Mockito.eq(42)); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Mockito.verify(ctx).channel(); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testLogGoAway() { - Mockito.reset(_mockLogger); - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - class Harness extends Log4J2FrameLogger { - private Harness() { - super(Level.DEBUG); - } - - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Log4J2FrameLogger handler = new Harness(); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Channel ch = Mockito.mock(Channel.class); - Mockito.when(ctx.channel()).thenReturn(ch); - ByteBuf debug = Unpooled.copiedBuffer("Hello world", StandardCharsets.US_ASCII); - - handler.logGoAway(Http2FrameLogger.Direction.INBOUND, ctx, 5, 0, debug); - ArgumentCaptor captor = ArgumentCaptor.forClass(Object.class); - - Mockito.verify(_mockLogger).isEnabled(Mockito.eq(Level.DEBUG)); - Mockito.verify(_mockLogger) - .log( - Mockito.eq(Level.DEBUG), - Mockito.eq("{} {} GO_AWAY: lastStreamId={} errorCode={} length={} bytes={}"), - Mockito.same(ch), - Mockito.eq("INBOUND"), - Mockito.eq(5), - Mockito.eq(0L), - Mockito.eq(11), - captor.capture()); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Assert.assertEquals(captor.getValue().toString(), "48656c6c6f20776f726c64"); - - Mockito.verify(ctx).channel(); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testLogWindowUpdate() { - Mockito.reset(_mockLogger); - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - class Harness extends Log4J2FrameLogger { - private Harness() { - super(Level.DEBUG); - } - - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Log4J2FrameLogger handler = new Harness(); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Channel ch = Mockito.mock(Channel.class); - Mockito.when(ctx.channel()).thenReturn(ch); - Http2Headers headers = Mockito.mock(Http2Headers.class, "headers"); - - handler.logWindowsUpdate(Http2FrameLogger.Direction.INBOUND, ctx, 5, 10000); - - Mockito.verify(_mockLogger) - .log( - Mockito.eq(Level.DEBUG), - Mockito.eq("{} {} WINDOW_UPDATE: streamId={} windowSizeIncrement={}"), - Mockito.same(ch), - Mockito.eq("INBOUND"), - Mockito.eq(5), - Mockito.eq(10000)); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Mockito.verify(ctx).channel(); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testLogUnknownFrame() { - Mockito.reset(_mockLogger); - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - class Harness extends Log4J2FrameLogger { - private Harness() { - super(Level.DEBUG, "foo"); - } - - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Log4J2FrameLogger handler = new Harness(); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Channel ch = Mockito.mock(Channel.class); - Mockito.when(ctx.channel()).thenReturn(ch); - ByteBuf debug = Unpooled.copiedBuffer( - "Hello world! " + "This is a longer string which will exceed 64 bytes so it will be truncated", - StandardCharsets.US_ASCII); - Http2Flags flags = new Http2Flags((short) 1234); - - handler.logUnknownFrame(Http2FrameLogger.Direction.INBOUND, ctx, (byte) 100, 5, flags, debug); - ArgumentCaptor captor = ArgumentCaptor.forClass(Object.class); - - Mockito.verify(_mockLogger).isEnabled(Mockito.eq(Level.DEBUG)); - Mockito.verify(_mockLogger) - .log( - Mockito.eq(Level.DEBUG), - Mockito.eq("{} {} UNKNOWN: frameType={} streamId={} flags={} length={} bytes={}"), - Mockito.same(ch), - Mockito.eq("INBOUND"), - Mockito.eq(100), - Mockito.eq(5), - Mockito.eq((short) 1234), - Mockito.eq(87), - captor.capture()); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Assert.assertEquals( - captor.getValue().toString(), - "48656c6c6f20776f726c642120546869732069732061206c6f6e67657220737472696e672077686963682077696c6c2065786365656420363420627974657320..."); - - Mockito.verify(ctx).channel(); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testLogUnknownFrameNoDebug() { - Mockito.reset(_mockLogger); - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(false); - - class Harness extends Log4J2FrameLogger { - private Harness() { - super(Level.DEBUG, "foo"); - } - - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Log4J2FrameLogger handler = new Harness(); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Channel ch = Mockito.mock(Channel.class); - Mockito.when(ctx.channel()).thenReturn(ch); - ByteBuf debug = Unpooled.copiedBuffer( - "Hello world! " + "This is a longer string which will exceed 64 bytes so it will be truncated", - StandardCharsets.US_ASCII); - Http2Flags flags = new Http2Flags((short) 1234); - - handler.logUnknownFrame(Http2FrameLogger.Direction.INBOUND, ctx, (byte) 100, 5, flags, debug); - ArgumentCaptor captor = ArgumentCaptor.forClass(Object.class); - - Mockito.verify(_mockLogger).isEnabled(Mockito.eq(Level.DEBUG)); - Mockito.verify(_mockLogger) - .log( - Mockito.eq(Level.DEBUG), - Mockito.eq("{} {} UNKNOWN: frameType={} streamId={} flags={} length={} bytes={}"), - Mockito.same(ch), - Mockito.eq("INBOUND"), - Mockito.eq(100), - Mockito.eq(5), - Mockito.eq((short) 1234), - Mockito.eq(87), - captor.capture()); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Assert.assertEquals(captor.getValue().toString(), ""); - - Mockito.verify(ctx).channel(); - Mockito.verifyNoMoreInteractions(ctx); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestLog4J2LoggingHandler.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestLog4J2LoggingHandler.java deleted file mode 100644 index f1af11afe07..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestLog4J2LoggingHandler.java +++ /dev/null @@ -1,766 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufHolder; -import io.netty.buffer.Unpooled; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelPromise; -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.Logger; -import org.mockito.ArgumentCaptor; -import org.mockito.Mockito; -import org.testng.Assert; -import org.testng.annotations.Test; - - -/** - * Created by acurtis on 4/23/18. - */ -public class TestLog4J2LoggingHandler { - private final Logger _mockLogger = Mockito.mock(Logger.class); - - @Test(groups = "unit") - public void testConstruct() throws Exception { - Assert.assertNotNull(new Log4J2LoggingHandler()); - } - - @Test(groups = "unit") - public void testChannelRegistered() throws Exception { - Mockito.reset(_mockLogger); - - class Harness extends Log4J2LoggingHandler { - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - Log4J2LoggingHandler handler = new Harness(); - - Channel ch = Mockito.mock(Channel.class, "mockChannel"); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Mockito.when(ctx.channel()).thenReturn(ch); - - handler.channelRegistered(ctx); - - Mockito.verify(_mockLogger).isEnabled(Mockito.eq(Level.DEBUG)); - ArgumentCaptor message = ArgumentCaptor.forClass(Object.class); - Mockito.verify(_mockLogger).log(Mockito.eq(Level.DEBUG), message.capture()); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Assert.assertEquals(String.valueOf(message.getValue()), "mockChannel REGISTERED"); - Mockito.verify(ctx).channel(); - Mockito.verify(ctx).fireChannelRegistered(); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testChannelUnregistered() throws Exception { - Mockito.reset(_mockLogger); - - class Harness extends Log4J2LoggingHandler { - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - Log4J2LoggingHandler handler = new Harness(); - - Channel ch = Mockito.mock(Channel.class, "mockChannel"); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Mockito.when(ctx.channel()).thenReturn(ch); - - handler.channelUnregistered(ctx); - - Mockito.verify(_mockLogger).isEnabled(Mockito.eq(Level.DEBUG)); - ArgumentCaptor message = ArgumentCaptor.forClass(Object.class); - Mockito.verify(_mockLogger).log(Mockito.eq(Level.DEBUG), message.capture()); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Assert.assertEquals(String.valueOf(message.getValue()), "mockChannel UNREGISTERED"); - Mockito.verify(ctx).channel(); - Mockito.verify(ctx).fireChannelUnregistered(); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testChannelActive() throws Exception { - Mockito.reset(_mockLogger); - - class Harness extends Log4J2LoggingHandler { - private Harness() { - super(TestLog4J2LoggingHandler.class); - } - - @Override - Logger setupLogger(Logger logger) { - Assert.assertEquals(logger.getName(), TestLog4J2LoggingHandler.class.getName()); - return _mockLogger; - } - } - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - Log4J2LoggingHandler handler = new Harness(); - - Channel ch = Mockito.mock(Channel.class, "mockChannel"); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Mockito.when(ctx.channel()).thenReturn(ch); - - handler.channelActive(ctx); - - Mockito.verify(_mockLogger).isEnabled(Mockito.eq(Level.DEBUG)); - ArgumentCaptor message = ArgumentCaptor.forClass(Object.class); - Mockito.verify(_mockLogger).log(Mockito.eq(Level.DEBUG), message.capture()); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Assert.assertEquals(String.valueOf(message.getValue()), "mockChannel ACTIVE"); - Mockito.verify(ctx).channel(); - Mockito.verify(ctx).fireChannelActive(); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testChannelInactive() throws Exception { - Mockito.reset(_mockLogger); - - class Harness extends Log4J2LoggingHandler { - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - Log4J2LoggingHandler handler = new Harness(); - - Channel ch = Mockito.mock(Channel.class, "mockChannel"); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Mockito.when(ctx.channel()).thenReturn(ch); - - handler.channelInactive(ctx); - - Mockito.verify(_mockLogger).isEnabled(Mockito.eq(Level.DEBUG)); - ArgumentCaptor message = ArgumentCaptor.forClass(Object.class); - Mockito.verify(_mockLogger).log(Mockito.eq(Level.DEBUG), message.capture()); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Assert.assertEquals(String.valueOf(message.getValue()), "mockChannel INACTIVE"); - Mockito.verify(ctx).channel(); - Mockito.verify(ctx).fireChannelInactive(); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testExceptionCaught() throws Exception { - Mockito.reset(_mockLogger); - - class Harness extends Log4J2LoggingHandler { - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - class TestEx extends Error { - } - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - Log4J2LoggingHandler handler = new Harness(); - - Channel ch = Mockito.mock(Channel.class, "mockChannel"); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Mockito.when(ctx.channel()).thenReturn(ch); - - handler.exceptionCaught(ctx, new TestEx()); - - Mockito.verify(_mockLogger).isEnabled(Mockito.eq(Level.DEBUG)); - ArgumentCaptor message = ArgumentCaptor.forClass(Object.class); - Mockito.verify(_mockLogger).log(Mockito.eq(Level.DEBUG), message.capture(), Mockito.notNull(TestEx.class)); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Assert.assertEquals( - String.valueOf(message.getValue()), - "mockChannel EXCEPTION: com.linkedin.alpini.netty4.handlers.TestLog4J2LoggingHandler$1TestEx"); - Mockito.verify(ctx).channel(); - Mockito.verify(ctx).fireExceptionCaught(Mockito.notNull(TestEx.class)); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testUserEvent() throws Exception { - Mockito.reset(_mockLogger); - - class Harness extends Log4J2LoggingHandler { - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - class TestEvent { - @Override - public String toString() { - return "TestEvent{}"; - } - } - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - Log4J2LoggingHandler handler = new Harness(); - - Channel ch = Mockito.mock(Channel.class, "mockChannel"); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Mockito.when(ctx.channel()).thenReturn(ch); - - handler.userEventTriggered(ctx, new TestEvent()); - - Mockito.verify(_mockLogger).isEnabled(Mockito.eq(Level.DEBUG)); - ArgumentCaptor message = ArgumentCaptor.forClass(Object.class); - Mockito.verify(_mockLogger).log(Mockito.eq(Level.DEBUG), message.capture()); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Assert.assertEquals(String.valueOf(message.getValue()), "mockChannel USER_EVENT: TestEvent{}"); - Mockito.verify(ctx).channel(); - Mockito.verify(ctx).fireUserEventTriggered(Mockito.notNull(TestEvent.class)); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testBind() throws Exception { - Mockito.reset(_mockLogger); - - class Harness extends Log4J2LoggingHandler { - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - Log4J2LoggingHandler handler = new Harness(); - - Channel ch = Mockito.mock(Channel.class, "mockChannel"); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Mockito.when(ctx.channel()).thenReturn(ch); - - SocketAddress localAddress = Mockito.mock(SocketAddress.class, "localAddress"); - ChannelPromise promise = Mockito.mock(ChannelPromise.class); - - handler.bind(ctx, localAddress, promise); - - Mockito.verify(_mockLogger).isEnabled(Mockito.eq(Level.DEBUG)); - ArgumentCaptor message = ArgumentCaptor.forClass(Object.class); - Mockito.verify(_mockLogger).log(Mockito.eq(Level.DEBUG), message.capture()); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Assert.assertEquals(String.valueOf(message.getValue()), "mockChannel BIND: localAddress"); - Mockito.verify(ctx).channel(); - Mockito.verify(ctx).bind(Mockito.eq(localAddress), Mockito.eq(promise)); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testConnect2() throws Exception { - Mockito.reset(_mockLogger); - - class Harness extends Log4J2LoggingHandler { - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - Log4J2LoggingHandler handler = new Harness(); - - Channel ch = Mockito.mock(Channel.class, "mockChannel"); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Mockito.when(ctx.channel()).thenReturn(ch); - - SocketAddress localAddress = Mockito.mock(SocketAddress.class, "localAddress"); - SocketAddress remoteAddress = Mockito.mock(SocketAddress.class, "remoteAddress"); - ChannelPromise promise = Mockito.mock(ChannelPromise.class); - - handler.connect(ctx, remoteAddress, localAddress, promise); - - Mockito.verify(_mockLogger).isEnabled(Mockito.eq(Level.DEBUG)); - ArgumentCaptor message = ArgumentCaptor.forClass(Object.class); - Mockito.verify(_mockLogger).log(Mockito.eq(Level.DEBUG), message.capture()); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Assert.assertEquals(String.valueOf(message.getValue()), "mockChannel CONNECT: remoteAddress, localAddress"); - Mockito.verify(ctx).channel(); - Mockito.verify(ctx).connect(Mockito.eq(remoteAddress), Mockito.eq(localAddress), Mockito.eq(promise)); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testConnect1() throws Exception { - Mockito.reset(_mockLogger); - - class Harness extends Log4J2LoggingHandler { - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - Log4J2LoggingHandler handler = new Harness(); - - Channel ch = Mockito.mock(Channel.class, "mockChannel"); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Mockito.when(ctx.channel()).thenReturn(ch); - - SocketAddress remoteAddress = Mockito.mock(SocketAddress.class, "remoteAddress"); - ChannelPromise promise = Mockito.mock(ChannelPromise.class); - - handler.connect(ctx, remoteAddress, null, promise); - - Mockito.verify(_mockLogger).isEnabled(Mockito.eq(Level.DEBUG)); - ArgumentCaptor message = ArgumentCaptor.forClass(Object.class); - Mockito.verify(_mockLogger).log(Mockito.eq(Level.DEBUG), message.capture()); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Assert.assertEquals(String.valueOf(message.getValue()), "mockChannel CONNECT: remoteAddress"); - Mockito.verify(ctx).channel(); - Mockito.verify(ctx).connect(Mockito.eq(remoteAddress), Mockito.isNull(SocketAddress.class), Mockito.eq(promise)); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testDisconnect() throws Exception { - Mockito.reset(_mockLogger); - - class Harness extends Log4J2LoggingHandler { - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - Log4J2LoggingHandler handler = new Harness(); - - Channel ch = Mockito.mock(Channel.class, "mockChannel"); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Mockito.when(ctx.channel()).thenReturn(ch); - ChannelPromise promise = Mockito.mock(ChannelPromise.class); - - handler.disconnect(ctx, promise); - - Mockito.verify(_mockLogger).isEnabled(Mockito.eq(Level.DEBUG)); - ArgumentCaptor message = ArgumentCaptor.forClass(Object.class); - Mockito.verify(_mockLogger).log(Mockito.eq(Level.DEBUG), message.capture()); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Assert.assertEquals(String.valueOf(message.getValue()), "mockChannel DISCONNECT"); - Mockito.verify(ctx).channel(); - Mockito.verify(ctx).disconnect(Mockito.eq(promise)); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testClose() throws Exception { - Mockito.reset(_mockLogger); - - class Harness extends Log4J2LoggingHandler { - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - Log4J2LoggingHandler handler = new Harness(); - - Channel ch = Mockito.mock(Channel.class, "mockChannel"); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Mockito.when(ctx.channel()).thenReturn(ch); - ChannelPromise promise = Mockito.mock(ChannelPromise.class); - - handler.close(ctx, promise); - - Mockito.verify(_mockLogger).isEnabled(Mockito.eq(Level.DEBUG)); - ArgumentCaptor message = ArgumentCaptor.forClass(Object.class); - Mockito.verify(_mockLogger).log(Mockito.eq(Level.DEBUG), message.capture()); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Assert.assertEquals(String.valueOf(message.getValue()), "mockChannel CLOSE"); - Mockito.verify(ctx).channel(); - Mockito.verify(ctx).close(Mockito.eq(promise)); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testDeregister() throws Exception { - Mockito.reset(_mockLogger); - - class Harness extends Log4J2LoggingHandler { - private Harness() { - super("Foo"); - } - - @Override - Logger setupLogger(Logger logger) { - Assert.assertEquals(logger.getName(), "Foo"); - return _mockLogger; - } - } - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - Log4J2LoggingHandler handler = new Harness(); - - Channel ch = Mockito.mock(Channel.class, "mockChannel"); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Mockito.when(ctx.channel()).thenReturn(ch); - ChannelPromise promise = Mockito.mock(ChannelPromise.class); - - handler.deregister(ctx, promise); - - Mockito.verify(_mockLogger).isEnabled(Mockito.eq(Level.DEBUG)); - ArgumentCaptor message = ArgumentCaptor.forClass(Object.class); - Mockito.verify(_mockLogger).log(Mockito.eq(Level.DEBUG), message.capture()); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Assert.assertEquals(String.valueOf(message.getValue()), "mockChannel DEREGISTER"); - Mockito.verify(ctx).channel(); - Mockito.verify(ctx).deregister(Mockito.eq(promise)); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testChannelReadComplete() throws Exception { - Mockito.reset(_mockLogger); - - class Harness extends Log4J2LoggingHandler { - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - Log4J2LoggingHandler handler = new Harness(); - - Channel ch = Mockito.mock(Channel.class, "mockChannel"); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Mockito.when(ctx.channel()).thenReturn(ch); - - handler.channelReadComplete(ctx); - - Mockito.verify(_mockLogger).isEnabled(Mockito.eq(Level.DEBUG)); - ArgumentCaptor message = ArgumentCaptor.forClass(Object.class); - Mockito.verify(_mockLogger).log(Mockito.eq(Level.DEBUG), message.capture()); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Assert.assertEquals(String.valueOf(message.getValue()), "mockChannel READ COMPLETE"); - Mockito.verify(ctx).channel(); - Mockito.verify(ctx).fireChannelReadComplete(); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testChannelRead() throws Exception { - Mockito.reset(_mockLogger); - - class Harness extends Log4J2LoggingHandler { - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - Log4J2LoggingHandler handler = new Harness(); - - Channel ch = Mockito.mock(Channel.class, "mockChannel"); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Mockito.when(ctx.channel()).thenReturn(ch); - Object msg = Mockito.mock(Object.class, "Msg"); - - handler.channelRead(ctx, msg); - - Mockito.verify(_mockLogger).isEnabled(Mockito.eq(Level.DEBUG)); - ArgumentCaptor message = ArgumentCaptor.forClass(Object.class); - Mockito.verify(_mockLogger).log(Mockito.eq(Level.DEBUG), message.capture()); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Assert.assertEquals(String.valueOf(message.getValue()), "mockChannel READ: Msg"); - Mockito.verify(ctx).channel(); - Mockito.verify(ctx).fireChannelRead(Mockito.eq(msg)); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testChannelReadByteBufHolder0() throws Exception { - Mockito.reset(_mockLogger); - - class Harness extends Log4J2LoggingHandler { - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - Log4J2LoggingHandler handler = new Harness(); - - Channel ch = Mockito.mock(Channel.class, "mockChannel"); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Mockito.when(ctx.channel()).thenReturn(ch); - ByteBuf byteBuf = Mockito.mock(ByteBuf.class, "Msg"); - ByteBufHolder msg = Mockito.mock(ByteBufHolder.class, "Holder0"); - Mockito.when(msg.content()).thenReturn(byteBuf); - - handler.channelRead(ctx, msg); - - Mockito.verify(_mockLogger).isEnabled(Mockito.eq(Level.DEBUG)); - ArgumentCaptor message = ArgumentCaptor.forClass(Object.class); - Mockito.verify(_mockLogger).log(Mockito.eq(Level.DEBUG), message.capture()); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Assert.assertEquals(String.valueOf(message.getValue()), "mockChannel READ, Holder0, 0B"); - Mockito.verify(ctx).channel(); - Mockito.verify(ctx).fireChannelRead(Mockito.eq(msg)); - Mockito.verifyNoMoreInteractions(ctx); - - Mockito.verify(msg).content(); - Mockito.verify(byteBuf).readableBytes(); - } - - @Test(groups = "unit") - public void testChannelReadByteBufHolderHello() throws Exception { - Mockito.reset(_mockLogger); - - class Harness extends Log4J2LoggingHandler { - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - Log4J2LoggingHandler handler = new Harness(); - - Channel ch = Mockito.mock(Channel.class, "mockChannel"); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Mockito.when(ctx.channel()).thenReturn(ch); - ByteBuf byteBuf = Unpooled.copiedBuffer("Hello world", StandardCharsets.US_ASCII); - ByteBufHolder msg = Mockito.mock(ByteBufHolder.class, "Holder1"); - Mockito.when(msg.content()).thenReturn(byteBuf); - - handler.channelRead(ctx, msg); - - Mockito.verify(_mockLogger).isEnabled(Mockito.eq(Level.DEBUG)); - ArgumentCaptor message = ArgumentCaptor.forClass(Object.class); - Mockito.verify(_mockLogger).log(Mockito.eq(Level.DEBUG), message.capture()); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Assert.assertEquals( - String.valueOf(message.getValue()), - "mockChannel READ: Holder1, 11B\n" + " +-------------------------------------------------+\n" - + " | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n" - + "+--------+-------------------------------------------------+----------------+\n" - + "|00000000| 48 65 6c 6c 6f 20 77 6f 72 6c 64 |Hello world |\n" - + "+--------+-------------------------------------------------+----------------+"); - Mockito.verify(ctx).channel(); - Mockito.verify(ctx).fireChannelRead(Mockito.eq(msg)); - Mockito.verifyNoMoreInteractions(ctx); - - Mockito.verify(msg).content(); - } - - @Test(groups = "unit") - public void testWrite() throws Exception { - Mockito.reset(_mockLogger); - - class Harness extends Log4J2LoggingHandler { - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - Log4J2LoggingHandler handler = new Harness(); - - Channel ch = Mockito.mock(Channel.class, "mockChannel"); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Mockito.when(ctx.channel()).thenReturn(ch); - ChannelPromise promise = Mockito.mock(ChannelPromise.class); - Object msg = Mockito.mock(Object.class, "Msg"); - - handler.write(ctx, msg, promise); - - Mockito.verify(_mockLogger).isEnabled(Mockito.eq(Level.DEBUG)); - ArgumentCaptor message = ArgumentCaptor.forClass(Object.class); - Mockito.verify(_mockLogger).log(Mockito.eq(Level.DEBUG), message.capture()); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Assert.assertEquals(String.valueOf(message.getValue()), "mockChannel WRITE: Msg"); - Mockito.verify(ctx).channel(); - Mockito.verify(ctx).write(Mockito.eq(msg), Mockito.eq(promise)); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testWriteByteBuf0() throws Exception { - Mockito.reset(_mockLogger); - - class Harness extends Log4J2LoggingHandler { - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - Log4J2LoggingHandler handler = new Harness(); - - Channel ch = Mockito.mock(Channel.class, "mockChannel"); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Mockito.when(ctx.channel()).thenReturn(ch); - ChannelPromise promise = Mockito.mock(ChannelPromise.class); - ByteBuf msg = Mockito.mock(ByteBuf.class, "Msg"); - - handler.write(ctx, msg, promise); - - Mockito.verify(_mockLogger).isEnabled(Mockito.eq(Level.DEBUG)); - ArgumentCaptor message = ArgumentCaptor.forClass(Object.class); - Mockito.verify(_mockLogger).log(Mockito.eq(Level.DEBUG), message.capture()); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Assert.assertEquals(String.valueOf(message.getValue()), "mockChannel WRITE: 0B"); - Mockito.verify(ctx).channel(); - Mockito.verify(ctx).write(Mockito.eq(msg), Mockito.eq(promise)); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testWriteByteBufHello() throws Exception { - Mockito.reset(_mockLogger); - - class Harness extends Log4J2LoggingHandler { - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - Log4J2LoggingHandler handler = new Harness(); - - Channel ch = Mockito.mock(Channel.class, "mockChannel"); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Mockito.when(ctx.channel()).thenReturn(ch); - ChannelPromise promise = Mockito.mock(ChannelPromise.class); - ByteBuf msg = Unpooled.copiedBuffer("Hello World", StandardCharsets.US_ASCII); - - handler.write(ctx, msg, promise); - - Mockito.verify(_mockLogger).isEnabled(Mockito.eq(Level.DEBUG)); - ArgumentCaptor message = ArgumentCaptor.forClass(Object.class); - Mockito.verify(_mockLogger).log(Mockito.eq(Level.DEBUG), message.capture()); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Assert.assertEquals( - String.valueOf(message.getValue()), - "mockChannel WRITE: 11B\n" + " +-------------------------------------------------+\n" - + " | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n" - + "+--------+-------------------------------------------------+----------------+\n" - + "|00000000| 48 65 6c 6c 6f 20 57 6f 72 6c 64 |Hello World |\n" - + "+--------+-------------------------------------------------+----------------+"); - Mockito.verify(ctx).channel(); - Mockito.verify(ctx).write(Mockito.eq(msg), Mockito.eq(promise)); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testChannelWritabilityChanged() throws Exception { - Mockito.reset(_mockLogger); - - class Harness extends Log4J2LoggingHandler { - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - Log4J2LoggingHandler handler = new Harness(); - - Channel ch = Mockito.mock(Channel.class, "mockChannel"); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Mockito.when(ctx.channel()).thenReturn(ch); - - handler.channelWritabilityChanged(ctx); - - Mockito.verify(_mockLogger).isEnabled(Mockito.eq(Level.DEBUG)); - ArgumentCaptor message = ArgumentCaptor.forClass(Object.class); - Mockito.verify(_mockLogger).log(Mockito.eq(Level.DEBUG), message.capture()); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Assert.assertEquals(String.valueOf(message.getValue()), "mockChannel WRITABILITY CHANGED"); - Mockito.verify(ctx).channel(); - Mockito.verify(ctx).fireChannelWritabilityChanged(); - Mockito.verifyNoMoreInteractions(ctx); - } - - @Test(groups = "unit") - public void testFlush() throws Exception { - Mockito.reset(_mockLogger); - - class Harness extends Log4J2LoggingHandler { - @Override - Logger setupLogger(Logger logger) { - return _mockLogger; - } - } - - Mockito.when(_mockLogger.isEnabled(Mockito.eq(Level.DEBUG))).thenReturn(true); - - Log4J2LoggingHandler handler = new Harness(); - - Channel ch = Mockito.mock(Channel.class, "mockChannel"); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - Mockito.when(ctx.channel()).thenReturn(ch); - - handler.flush(ctx); - - Mockito.verify(_mockLogger).isEnabled(Mockito.eq(Level.DEBUG)); - ArgumentCaptor message = ArgumentCaptor.forClass(Object.class); - Mockito.verify(_mockLogger).log(Mockito.eq(Level.DEBUG), message.capture()); - Mockito.verifyNoMoreInteractions(_mockLogger); - - Assert.assertEquals(String.valueOf(message.getValue()), "mockChannel FLUSH"); - Mockito.verify(ctx).channel(); - Mockito.verify(ctx).flush(); - Mockito.verifyNoMoreInteractions(ctx); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestOutboundByteBufAggregator.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestOutboundByteBufAggregator.java deleted file mode 100644 index 0f150186283..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestOutboundByteBufAggregator.java +++ /dev/null @@ -1,284 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.CompositeByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.ChannelFuture; -import io.netty.channel.embedded.EmbeddedChannel; -import java.nio.charset.StandardCharsets; -import java.util.Iterator; -import org.testng.Assert; -import org.testng.annotations.Test; - - -@Test(groups = { "unit", "unit-leak", "leak" }, singleThreaded = true) -public final class TestOutboundByteBufAggregator extends AbstractLeakDetect { - @Test - public void testBasic() { - EmbeddedChannel ch = new EmbeddedChannel(new OutboundByteBufAggregator()); - ch.config().setAllocator(POOLED_ALLOCATOR); - basic(ch); - ch.finishAndReleaseAll(); - } - - private void basic(EmbeddedChannel ch) { - ByteBuf test = encodeString("Hello world", StandardCharsets.ISO_8859_1); - Assert.assertTrue(test.hasMemoryAddress()); - - ChannelFuture future = ch.writeOneOutbound(test); - - Assert.assertFalse(future.isDone()); - Assert.assertNull(ch.readOutbound()); - - ch.flushOutbound(); - - Assert.assertTrue(future.isSuccess()); - ByteBuf outbound = ch.readOutbound(); - - Assert.assertSame(outbound, test); - - test.release(); - } - - @Test - public void testBasicPassthrough() { - EmbeddedChannel ch = new EmbeddedChannel(new OutboundByteBufAggregator()); - ch.config().setAllocator(POOLED_ALLOCATOR); - basicPassthrough(ch); - ch.finishAndReleaseAll(); - } - - private void basicPassthrough(EmbeddedChannel ch) { - ByteBuf test = Unpooled.wrappedBuffer(new byte[16384]); - - ChannelFuture future = ch.writeOneOutbound(test); - - Assert.assertFalse(future.isDone()); - Assert.assertNull(ch.readOutbound()); - - ch.flushOutbound(); - - Assert.assertTrue(future.isSuccess()); - ByteBuf outbound = ch.readOutbound(); - - Assert.assertSame(outbound, test); - - test.release(); - } - - @Test - public void testBasicComposite() { - EmbeddedChannel ch = new EmbeddedChannel(new OutboundByteBufAggregator()); - ch.config().setAllocator(POOLED_ALLOCATOR); - basicComposite(ch); - ch.finishAndReleaseAll(); - } - - private void basicComposite(EmbeddedChannel ch) { - - ByteBuf testBuf = encodeString("xxxxxxxxxxHello World! This is a test.", StandardCharsets.ISO_8859_1); - ByteBuf testBuf2 = encodeString( - ";UG'IUG;IG;IG;/G;O/UG;OUG;IGUGUGIGGIGIIGIGGGUGUGGUGGUGUGGIGGUOUGOUGGUOGUOOGUOUG! This is a test.42t24t24t24tg24t24t", - StandardCharsets.ISO_8859_1); - - ChannelFuture future = ch.writeOneOutbound( - POOLED_ALLOCATOR.compositeBuffer() - .addComponents(true, testBuf.readRetainedSlice(22), testBuf2.retainedSlice(118 - 38, 16)) - .slice(10, 102 - 74)); - testBuf.release(); - testBuf2.release(); - - Assert.assertFalse(future.isDone()); - Assert.assertNull(ch.readOutbound()); - - ch.flushOutbound(); - - Assert.assertTrue(future.isSuccess()); - ByteBuf outbound = ch.readOutbound(); - Assert.assertNull(ch.readOutbound()); - - Assert.assertEquals(outbound.toString(StandardCharsets.ISO_8859_1), "Hello World! This is a test."); - Assert.assertFalse(outbound instanceof CompositeByteBuf); - Assert.assertTrue(outbound.hasMemoryAddress()); - - outbound.release(); - } - - @Test - public void testSimpleComposite() { - EmbeddedChannel ch = new EmbeddedChannel(new OutboundByteBufAggregator()); - ch.config().setAllocator(POOLED_ALLOCATOR); - simpleComposite(ch); - ch.finishAndReleaseAll(); - } - - private void simpleComposite(EmbeddedChannel ch) { - ChannelFuture future = ch.writeOneOutbound(Unpooled.wrappedBuffer(new byte[8192], new byte[8192])); - - Assert.assertFalse(future.isDone()); - Assert.assertNull(ch.readOutbound()); - - ch.flushOutbound(); - - Assert.assertTrue(future.isSuccess()); - ByteBuf outbound = ch.readOutbound(); - Assert.assertNull(ch.readOutbound()); - - Assert.assertEquals(outbound.readableBytes(), 16384); - Assert.assertFalse(outbound instanceof CompositeByteBuf); - - outbound.release(); - } - - @Test - public void testOverflowComposite() { - EmbeddedChannel ch = new EmbeddedChannel(new OutboundByteBufAggregator()); - ch.config().setAllocator(POOLED_ALLOCATOR); - overflowComposite(ch); - ch.finishAndReleaseAll(); - } - - private void overflowComposite(EmbeddedChannel ch) { - ChannelFuture future = ch.writeOneOutbound(Unpooled.wrappedBuffer(new byte[8192], new byte[16384])); - - Assert.assertFalse(future.isDone()); - Assert.assertNull(ch.readOutbound()); - - ch.flushOutbound(); - - Assert.assertTrue(future.isSuccess()); - ByteBuf outbound = ch.readOutbound(); - Assert.assertNull(ch.readOutbound()); - - Assert.assertEquals(outbound.readableBytes(), 24576); - Assert.assertTrue(outbound instanceof CompositeByteBuf); - - Iterator it = ((CompositeByteBuf) outbound).iterator(); - Assert.assertEquals(it.next().readableBytes(), 16384); - Assert.assertEquals(it.next().readableBytes(), 8192); - Assert.assertFalse(it.hasNext()); - - outbound.release(); - } - - @Test - public void testOverflowComposite2() { - EmbeddedChannel ch = new EmbeddedChannel(new OutboundByteBufAggregator()); - ch.config().setAllocator(POOLED_ALLOCATOR); - overflowComposite2(ch); - ch.finishAndReleaseAll(); - } - - private void overflowComposite2(EmbeddedChannel ch) { - ChannelFuture future = ch.writeOneOutbound(Unpooled.wrappedBuffer(new byte[8192], new byte[24576])); - - Assert.assertFalse(future.isDone()); - Assert.assertNull(ch.readOutbound()); - - ch.flushOutbound(); - - Assert.assertTrue(future.isSuccess()); - ByteBuf outbound = ch.readOutbound(); - Assert.assertNull(ch.readOutbound()); - - Assert.assertEquals(outbound.readableBytes(), 32768); - Assert.assertTrue(outbound instanceof CompositeByteBuf); - - Iterator it = ((CompositeByteBuf) outbound).iterator(); - ByteBuf buf = it.next(); - Assert.assertEquals(buf.readableBytes(), 16384); - Assert.assertFalse(buf.isReadOnly()); - buf = it.next(); - Assert.assertEquals(buf.readableBytes(), 16384); - Assert.assertTrue(buf.isReadOnly()); // passed-through bytebuf is readonly. - - Assert.assertFalse(it.hasNext()); - - outbound.release(); - } - - @Test - public void testSimple1() { - EmbeddedChannel ch = new EmbeddedChannel(new OutboundByteBufAggregator()); - ch.config().setAllocator(POOLED_ALLOCATOR); - simple1(ch); - ch.finishAndReleaseAll(); - } - - private void simple1(EmbeddedChannel ch) { - ChannelFuture future1 = ch.writeOneOutbound(Unpooled.wrappedBuffer(new byte[8192])); - ChannelFuture future2 = ch.writeOneOutbound(Unpooled.wrappedBuffer(new byte[8192])); - - Assert.assertFalse(future1.isDone()); - Assert.assertFalse(future2.isDone()); - Assert.assertNull(ch.readOutbound()); - - ch.flushOutbound(); - - Assert.assertTrue(future1.isSuccess()); - Assert.assertTrue(future2.isSuccess()); - ByteBuf outbound = ch.readOutbound(); - Assert.assertNull(ch.readOutbound()); - - Assert.assertEquals(outbound.readableBytes(), 16384); - - outbound.release(); - } - - @Test - public void testSimple0() { - EmbeddedChannel ch = new EmbeddedChannel(new OutboundByteBufAggregator()); - ch.config().setAllocator(POOLED_ALLOCATOR); - simple0(ch); - ch.finishAndReleaseAll(); - } - - private void simple0(EmbeddedChannel ch) { - ChannelFuture future1 = ch.writeOneOutbound(encodeString("Hello world!", StandardCharsets.ISO_8859_1)); - ChannelFuture future2 = ch.writeOneOutbound(encodeString(" This is a test.", StandardCharsets.ISO_8859_1)); - - Assert.assertFalse(future1.isDone()); - Assert.assertFalse(future2.isDone()); - Assert.assertNull(ch.readOutbound()); - - ch.flushOutbound(); - - Assert.assertTrue(future1.isSuccess()); - Assert.assertTrue(future2.isSuccess()); - ByteBuf outbound = ch.readOutbound(); - - Assert.assertNotNull(outbound); - Assert.assertNull(ch.readOutbound()); - - Assert.assertEquals(outbound.toString(StandardCharsets.ISO_8859_1), "Hello world! This is a test."); - - outbound.release(); - } - - @Test - public void testGauntlet() { - EmbeddedChannel ch = new EmbeddedChannel(new OutboundByteBufAggregator()); - ch.config().setAllocator(POOLED_ALLOCATOR); - simple0(ch); - simple1(ch); - overflowComposite2(ch); - overflowComposite(ch); - simpleComposite(ch); - basicComposite(ch); - simpleComposite(ch); - basicPassthrough(ch); - basic(ch); - ch.finishAndReleaseAll(); - } - - /** - * since TestNG tends to sort by method name, this tries to be the last test - * in the class. We do this because the AfterClass annotated methods may - * execute after other tests classes have run and doesn't execute immediately - * after the methods in this test class. - */ - @Test(alwaysRun = true) - public final void zz9PluralZAlpha() throws InterruptedException { - finallyLeakDetect(); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestRateLimitConnectHandler.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestRateLimitConnectHandler.java deleted file mode 100644 index d3271050f50..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/handlers/TestRateLimitConnectHandler.java +++ /dev/null @@ -1,132 +0,0 @@ -package com.linkedin.alpini.netty4.handlers; - -import com.linkedin.alpini.base.concurrency.Executors; -import com.linkedin.alpini.base.concurrency.ScheduledExecutorService; -import com.linkedin.alpini.base.misc.Time; -import com.linkedin.alpini.io.IOUtils; -import io.netty.bootstrap.Bootstrap; -import io.netty.channel.Channel; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.pool.ChannelPoolHandler; -import io.netty.channel.pool.FixedChannelPool; -import io.netty.channel.socket.nio.NioSocketChannel; -import io.netty.handler.logging.LogLevel; -import io.netty.handler.logging.LoggingHandler; -import io.netty.util.concurrent.Future; -import java.io.IOException; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.ArrayList; -import java.util.IntSummaryStatistics; -import java.util.List; -import org.testng.Assert; -import org.testng.IRetryAnalyzer; -import org.testng.ITestResult; -import org.testng.Reporter; -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - - -/** - * Created by acurtis on 3/19/18. - */ -public class TestRateLimitConnectHandler { - NioEventLoopGroup eventLoopGroup; - - ScheduledExecutorService scheduler; - - @BeforeTest(groups = "unit") - public void beforeTest() { - eventLoopGroup = new NioEventLoopGroup(); - - scheduler = Executors.newSingleThreadScheduledExecutor(); - } - - @AfterTest(groups = "unit") - public void afterTest() { - eventLoopGroup.shutdownGracefully(); - scheduler.shutdown(); - } - - @DataProvider - public Object[][] provideTimeBetweenAccepts() { - return new Object[][] { { 10, 500 }, { 50, 100 }, }; - } - - /** Timing related test needs retries */ - public static class RetryTimeBetweenAccepts implements IRetryAnalyzer { - int remaining = 5; - - @Override - public boolean retry(ITestResult result) { - if (!result.isSuccess() && remaining-- > 0) { - result.setStatus(ITestResult.SUCCESS_PERCENTAGE_FAILURE); - Reporter.log("Retries remaining: " + remaining); - return true; - } - return false; - } - } - - @Test(groups = "unit", dataProvider = "provideTimeBetweenAccepts", retryAnalyzer = RetryTimeBetweenAccepts.class, successPercentage = 10) - public void testTimeBetweenAccepts(final int limit, final int delay) throws IOException { - List accepted = new ArrayList<>(limit); - List> acquires = new ArrayList<>(limit); - try (final ServerSocket serverSocket = new ServerSocket(0)) { - int port = serverSocket.getLocalPort(); - Assert.assertNotEquals(port, 0); - - List interval = new ArrayList<>(limit); - - RateLimitConnectHandler handler = new RateLimitConnectHandler(scheduler, delay, delay * 10); - - FixedChannelPool pool = new FixedChannelPool( - new Bootstrap().group(eventLoopGroup).channel(NioSocketChannel.class).remoteAddress("localhost", port), - new ChannelPoolHandler() { - @Override - public void channelReleased(Channel ch) throws Exception { - - } - - @Override - public void channelAcquired(Channel ch) throws Exception { - - } - - @Override - public void channelCreated(Channel ch) throws Exception { - ch.pipeline().addLast(handler).addLast(new LoggingHandler(LogLevel.INFO)); - } - }, - limit, - Integer.MAX_VALUE); - - for (int i = 0; i < limit; i++) { - acquires.add(pool.acquire()); - } - - accepted.add(serverSocket.accept()); - long time = Time.currentTimeMillis(); - - for (int i = 1; i < limit; i++) { - accepted.add(serverSocket.accept()); - long prev = time; - time = Time.currentTimeMillis(); - interval.add(time - prev); - } - - IntSummaryStatistics stats = interval.stream().mapToInt(Long::intValue).summaryStatistics(); - - // Check that the time between receiving connections is at least the delay-1 ms - // and that the average time is no more than the delay + 10 ms. - Assert.assertTrue(stats.getMin() >= delay - 1, "stats=" + stats); - Assert.assertTrue(stats.getAverage() < delay + 10, "stats=" + stats); - - } finally { - accepted.forEach(IOUtils::closeQuietly); - acquires.stream().map(Future::getNow).forEach(Channel::close); - } - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/misc/TestAsciiStringURLCodec.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/misc/TestAsciiStringURLCodec.java deleted file mode 100644 index dbaf410614e..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/misc/TestAsciiStringURLCodec.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.linkedin.alpini.netty4.misc; - -import io.netty.util.AsciiString; -import java.nio.charset.StandardCharsets; -import org.testng.Assert; -import org.testng.annotations.Test; - - -/** - * @author Antony T Curtis {@literal } - */ -public class TestAsciiStringURLCodec { - static final int SWISS_GERMAN_STUFF_UNICODE[] = { 0x47, 0x72, 0xFC, 0x65, 0x7A, 0x69, 0x5F, 0x7A, 0xE4, 0x6D, 0xE4 }; - - static final int RUSSIAN_STUFF_UNICODE[] = - { 0x412, 0x441, 0x435, 0x43C, 0x5F, 0x43F, 0x440, 0x438, 0x432, 0x435, 0x442 }; - - private static String constructString(int[] unicodeChars) { - StringBuilder buffer = new StringBuilder(); - if (unicodeChars != null) { - for (int unicodeChar: unicodeChars) { - buffer.append((char) unicodeChar); - } - } - return buffer.toString(); - } - - @Test(groups = "unit") - public void testUTF8RoundTrip() throws Exception { - String ru_msg = constructString(RUSSIAN_STUFF_UNICODE); - String ch_msg = constructString(SWISS_GERMAN_STUFF_UNICODE); - - Assert.assertEquals( - AsciiStringURLCodec.encode(ru_msg, StandardCharsets.UTF_8), - new AsciiString("%D0%92%D1%81%D0%B5%D0%BC_%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82")); - - Assert.assertEquals( - AsciiStringURLCodec.encode(ch_msg, StandardCharsets.UTF_8), - new AsciiString("Gr%C3%BCezi_z%C3%A4m%C3%A4")); - - Assert.assertEquals( - AsciiStringURLCodec.decode(AsciiStringURLCodec.encode(ru_msg, StandardCharsets.UTF_8), StandardCharsets.UTF_8) - .toString(), - ru_msg); - - Assert.assertEquals( - AsciiStringURLCodec.decode(AsciiStringURLCodec.encode(ch_msg, StandardCharsets.UTF_8), StandardCharsets.UTF_8) - .toString(), - ch_msg); - } - - @Test(groups = "unit") - public void testBasicEncodeDecode() throws Exception { - String plain = "Hello there!"; - AsciiString encoded = AsciiStringURLCodec.encode(plain, StandardCharsets.US_ASCII); - Assert.assertTrue(AsciiString.contentEquals(encoded, "Hello+there%21")); - CharSequence decoded = AsciiStringURLCodec.decode(encoded, StandardCharsets.US_ASCII); - Assert.assertTrue(AsciiString.contentEquals(decoded, plain)); - } - - @Test(groups = "unit") - public void testSafeCharEncodeDecode() throws Exception { - String plain = "abc123_-.*"; - AsciiString encoded = AsciiStringURLCodec.encode(plain, StandardCharsets.US_ASCII); - Assert.assertTrue(encoded.contentEquals(plain)); - CharSequence decoded = AsciiStringURLCodec.decode(encoded, StandardCharsets.US_ASCII); - Assert.assertTrue(AsciiString.contentEquals(decoded, plain)); - } - - @Test(groups = "unit") - public void testUnsafeEncodeDecode() throws Exception { - String plain = "~!@#$%^&()+{}\"\\;:`,/[]"; - AsciiString encoded = AsciiStringURLCodec.encode(plain, StandardCharsets.US_ASCII); - Assert.assertTrue(encoded.contentEquals("%7E%21%40%23%24%25%5E%26%28%29%2B%7B%7D%22%5C%3B%3A%60%2C%2F%5B%5D")); - CharSequence decoded = AsciiStringURLCodec.decode(encoded, StandardCharsets.US_ASCII); - Assert.assertTrue(AsciiString.contentEquals(decoded, plain)); - } - - @Test(groups = "unit", expectedExceptions = IllegalArgumentException.class) - public void testDecodeInvalid1() { - AsciiStringURLCodec.decode(new AsciiString("%"), StandardCharsets.US_ASCII); - } - - @Test(groups = "unit", expectedExceptions = IllegalArgumentException.class) - public void testDecodeInvalid2() { - AsciiStringURLCodec.decode(new AsciiString("%A"), StandardCharsets.US_ASCII); - } - - @Test(groups = "unit", expectedExceptions = IllegalArgumentException.class) - public void testDecodeInvalid3() { - AsciiStringURLCodec.decode(new AsciiString("%WW"), StandardCharsets.US_ASCII); - } - - @Test(groups = "unit", expectedExceptions = IllegalArgumentException.class) - public void testDecodeInvalid4() { - AsciiStringURLCodec.decode(new AsciiString("%0W"), StandardCharsets.US_ASCII); - } - -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestChannelPoolManagerImplHttp2Ping.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestChannelPoolManagerImplHttp2Ping.java deleted file mode 100644 index 785690784f8..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestChannelPoolManagerImplHttp2Ping.java +++ /dev/null @@ -1,195 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import static org.mockito.Mockito.CALLS_REAL_METHODS; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.mockito.Mockito.withSettings; - -import com.linkedin.alpini.consts.QOS; -import com.linkedin.alpini.netty4.misc.NettyUtils; -import com.linkedin.venice.utils.TestUtils; -import io.netty.bootstrap.ServerBootstrap; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.MultithreadEventLoopGroup; -import io.netty.channel.embedded.EmbeddedChannel; -import io.netty.channel.group.DefaultChannelGroup; -import io.netty.channel.pool.ChannelPoolHandler; -import io.netty.channel.socket.SocketChannel; -import io.netty.handler.codec.http2.Http2FrameCodecBuilder; -import io.netty.handler.codec.http2.Http2MultiplexHandler; -import io.netty.util.concurrent.CompleteFuture; -import io.netty.util.concurrent.EventExecutor; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.ImmediateEventExecutor; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.function.Consumer; -import org.mockito.Mockito; -import org.testng.Assert; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - - -/* -* This class is designed to test the Http2 ping mechanism implemented in ChannelPoolManagerImpl. -* -* @author Binbing Hou -* */ -public class TestChannelPoolManagerImplHttp2Ping { - @DataProvider - public static Object[][] http2PingModes() { - return new Object[][] { // {useHttp2Ping, useGlobalPool, isPoolClosing} - { true, true, false }, { false, true, false }, { true, false, false }, { false, false, false }, - { true, true, true }, { false, true, true }, { true, false, true }, { false, false, true }, }; - } - - @Test(groups = "unit", dataProvider = "http2PingModes", invocationTimeOut = 10000L) - public void http2PingTest(boolean enableHttp2Ping, boolean useGlobalPool, boolean isPoolClosing) - throws InterruptedException { - - final int numOfExecutors = 4; - - EventLoopGroup eventLoopGroup = NettyUtils.newEventLoopGroup(numOfExecutors, Executors.defaultThreadFactory()); - try { - http2PingTest(enableHttp2Ping, useGlobalPool, isPoolClosing, numOfExecutors, eventLoopGroup); - eventLoopGroup.shutdownGracefully().sync(); - } finally { - // Must shutdown threads even in the event an exception occurs or else gradle test will not complete - eventLoopGroup.shutdownNow(); - } - } - - private void http2PingTest( - boolean enableHttp2Ping, - boolean useGlobalPool, - boolean isPoolClosing, - final int numOfExecutors, - final EventLoopGroup eventLoopGroup) throws InterruptedException { - ChannelPoolResolver channelPoolResolver = new BasicDnsResolver(); - EventExecutor eventExecutor = ImmediateEventExecutor.INSTANCE; - - ChannelPoolFactory channelPoolFactory = Mockito.mock(ChannelPoolFactory.class); - ManagedChannelPool parentPool = prepareParentPool(true, eventExecutor, isPoolClosing); - Http2AwareChannelPool pool = mock( - Http2AwareChannelPool.class, - withSettings().useConstructor(parentPool, (Consumer) ch -> {}, (Consumer) ch -> {}) - .defaultAnswer(CALLS_REAL_METHODS)); - Mockito.doAnswer(invocation -> pool) - .when(channelPoolFactory) - .construct(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); - - ChannelPoolManagerImpl manager = mock( - ChannelPoolManagerImpl.class, - withSettings() - .useConstructor( - eventLoopGroup, - channelPoolFactory, - channelPoolResolver, - 100, - useGlobalPool, - false, - false, - enableHttp2Ping ? 1 : 0) - .defaultAnswer(CALLS_REAL_METHODS)); - - Channel serverChannel = dummyServer(eventLoopGroup); - InetSocketAddress serverAddress = (InetSocketAddress) serverChannel.localAddress(); - Future channelFuture = manager.acquire("localhost:" + serverAddress.getPort(), "queueName", QOS.NORMAL); - Assert.assertTrue(channelFuture.await().isSuccess()); - Assert.assertNotNull(channelFuture.await().getNow()); - - manager.startPeriodicPing(); - - if (enableHttp2Ping) { - TestUtils.waitForNonDeterministicAssertion(1, TimeUnit.SECONDS, () -> { - Assert.assertTrue(manager.enablePeriodicPing()); - Assert.assertNotNull(manager.getPeriodicPingScheduledFuture()); - Assert.assertEquals(manager.getPools().size(), 1); - Mockito.verify(channelPoolFactory, useGlobalPool ? Mockito.times(1) : Mockito.times(numOfExecutors)) - .construct(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); - }); - } else { - TestUtils.waitForNonDeterministicAssertion(1, TimeUnit.SECONDS, () -> { - Assert.assertFalse(manager.enablePeriodicPing()); - Assert.assertNull(manager.getPeriodicPingScheduledFuture()); - Assert.assertEquals(manager.getPools().size(), 1); - Mockito.verify(channelPoolFactory, useGlobalPool ? Mockito.times(1) : Mockito.times(numOfExecutors)) - .construct(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); - }); - } - - // If the http2 ping is not enabled or the pool is in the closing state, we do not acquire connections - // to send http2 ping. In particular, for the local pool impl, it calls pool.acquire() 4 times - // for pool initialization. - if (!enableHttp2Ping || isPoolClosing) { - TestUtils.waitForNonDeterministicAssertion( - 1, - TimeUnit.SECONDS, - () -> Mockito.verify(pool, useGlobalPool ? Mockito.never() : Mockito.times(numOfExecutors)).acquire()); - } - - // reset - manager.stopPeriodicPing(); - - Mockito.reset(manager, channelPoolFactory, pool); - } - - private Channel dummyServer(EventLoopGroup eventLoopGroup) { - ServerBootstrap bootstrap = new ServerBootstrap().channel(NettyUtils.serverSocketChannel()) - .group(eventLoopGroup) - .localAddress(InetAddress.getLoopbackAddress(), 0) - .childHandler(new ChannelInitializer() { - @Override - protected void initChannel(SocketChannel ch) throws Exception { - } - }); - - return bootstrap.bind().syncUninterruptibly().channel(); - } - - private Future makeFuture(boolean successfulAcquire, EventExecutor eventExecutor) { - - return new CompleteFuture(eventExecutor) { - @Override - public boolean isSuccess() { - return successfulAcquire; - } - - @Override - public Throwable cause() { - return null; - } - - @Override - public Channel getNow() { - EmbeddedChannel channel = new EmbeddedChannel(); - // Since the test generates a channel synthetically, this needs to be set up. - channel.attr(Http2AwareChannelPool.STREAM_GROUP).set(new DefaultChannelGroup(channel.eventLoop(), true)); - channel.pipeline().addLast(Http2FrameCodecBuilder.forClient().build()); - ChannelHandler multiplexHandler = new Http2MultiplexHandler(mock(ChannelHandler.class)); - channel.pipeline().addLast(multiplexHandler); - return channel; - } - }; - } - - private ManagedChannelPool prepareParentPool( - boolean successfulAcquire, - EventExecutor eventExecutor, - boolean isPoolClosing) { - Future future = makeFuture(successfulAcquire, eventExecutor); - ManagedChannelPool parentPool = mock(ManagedChannelPool.class); - ChannelPoolHandler channelPoolHandler = mock(ChannelPoolHandler.class); - when(parentPool.isHealthy()).thenReturn(true); - when(parentPool.isClosing()).thenReturn(isPoolClosing); - when(parentPool.acquire()).thenReturn(future); - when(parentPool.handler()).thenReturn(channelPoolHandler); - when(parentPool.name()).thenReturn("pool"); - return parentPool; - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestChannelPoolResolver.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestChannelPoolResolver.java deleted file mode 100644 index 30492e15a7e..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestChannelPoolResolver.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.ImmediateEventExecutor; -import java.net.InetSocketAddress; -import org.testng.Assert; -import org.testng.annotations.Test; - - -/** - * Created by acurtis on 3/30/17. - */ -public class TestChannelPoolResolver { - @Test(groups = "unit") - public void testBasicDnsResolver() throws InterruptedException { - BasicDnsResolver resolver = new BasicDnsResolver(); - - Future result = resolver - .resolve(InetSocketAddress.createUnresolved("localhost", 80), ImmediateEventExecutor.INSTANCE.newPromise()); - - Assert.assertTrue(result.await().isSuccess()); - Assert.assertFalse(result.getNow().isUnresolved()); - Assert.assertEquals(result.getNow().getHostName(), "localhost"); - Assert.assertEquals(result.getNow().getPort(), 80); - Assert.assertEquals(result.getNow().getAddress().getHostAddress(), "127.0.0.1"); - - result = resolver - .resolve(InetSocketAddress.createUnresolved("google.com", 80), ImmediateEventExecutor.INSTANCE.newPromise()); - - Assert.assertTrue(result.await().isSuccess()); - Assert.assertFalse(result.getNow().isUnresolved()); - Assert.assertEquals(result.getNow().getHostName(), "google.com"); - Assert.assertEquals(result.getNow().getPort(), 80); - - result = resolver.resolve( - InetSocketAddress.createUnresolved("unresolved.linkedin.com", 80), - ImmediateEventExecutor.INSTANCE.newPromise()); - - Assert.assertTrue(result.await().isSuccess()); - Assert.assertTrue(result.getNow().isUnresolved()); - Assert.assertEquals(result.getNow().getHostName(), "unresolved.linkedin.com"); - Assert.assertEquals(result.getNow().getPort(), 80); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestEspressoFixedChannelPool.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestEspressoFixedChannelPool.java deleted file mode 100644 index 3d07a62b019..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestEspressoFixedChannelPool.java +++ /dev/null @@ -1,416 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertNotSame; -import static org.testng.Assert.assertSame; -import static org.testng.Assert.assertTrue; -import static org.testng.Assert.fail; - -import io.netty.bootstrap.Bootstrap; -import io.netty.bootstrap.ServerBootstrap; -import io.netty.channel.Channel; -import io.netty.channel.ChannelInboundHandlerAdapter; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.ChannelPromise; -import io.netty.channel.DefaultEventLoopGroup; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.local.LocalAddress; -import io.netty.channel.local.LocalChannel; -import io.netty.channel.local.LocalServerChannel; -import io.netty.channel.pool.AbstractChannelPoolHandler; -import io.netty.channel.pool.ChannelHealthChecker; -import io.netty.channel.pool.ChannelPool; -import io.netty.channel.pool.ChannelPoolHandler; -import io.netty.channel.pool.FixedChannelPool.AcquireTimeoutAction; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.GenericFutureListener; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicInteger; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - - -/** - * - * Forked from Netty's FixedChannelPoolTest - * - */ -public class TestEspressoFixedChannelPool { - private static final String LOCAL_ADDR_ID = "test.id"; - - private static EventLoopGroup group; - - @BeforeClass(groups = "unit") - public static void createEventLoop() { - group = new DefaultEventLoopGroup(); - } - - @AfterClass(groups = "unit") - public static void destroyEventLoop() { - if (group != null) { - group.shutdownGracefully(); - } - } - - static class CountingChannelPoolHandler implements ChannelPoolHandler { - private final AtomicInteger channelCount = new AtomicInteger(0); - private final AtomicInteger acquiredCount = new AtomicInteger(0); - private final AtomicInteger releasedCount = new AtomicInteger(0); - - @Override - public void channelCreated(Channel ch) { - channelCount.incrementAndGet(); - } - - @Override - public void channelReleased(Channel ch) { - releasedCount.incrementAndGet(); - } - - @Override - public void channelAcquired(Channel ch) { - acquiredCount.incrementAndGet(); - } - - public int channelCount() { - return channelCount.get(); - } - - public int acquiredCount() { - return acquiredCount.get(); - } - - public int releasedCount() { - return releasedCount.get(); - } - } - - @Test(groups = "unit") - public void testAcquire() throws Exception { - LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID); - Bootstrap cb = new Bootstrap(); - cb.remoteAddress(addr); - cb.group(group).channel(LocalChannel.class); - - ServerBootstrap sb = new ServerBootstrap(); - sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(LocalChannel ch) throws Exception { - ch.pipeline().addLast(new ChannelInboundHandlerAdapter()); - } - }); - - // Start server - Channel sc = sb.bind(addr).syncUninterruptibly().channel(); - CountingChannelPoolHandler handler = new CountingChannelPoolHandler(); - - ChannelPool pool = new EspressoFixedChannelPool(cb, handler, 1, Integer.MAX_VALUE); - - Channel channel = pool.acquire().syncUninterruptibly().getNow(); - Future future = pool.acquire(); - Assert.assertFalse(future.isDone()); - - pool.release(channel).syncUninterruptibly(); - assertTrue(future.await(1, TimeUnit.SECONDS)); - - Channel channel2 = future.getNow(); - assertSame(channel, channel2); - assertEquals(1, handler.channelCount()); - - assertEquals(2, handler.acquiredCount()); - assertEquals(1, handler.releasedCount()); - - sc.close().syncUninterruptibly(); - channel2.close().syncUninterruptibly(); - } - - @Test(groups = "unit", expectedExceptions = TimeoutException.class) - public void testAcquireTimeout() throws Exception { - testAcquireTimeout(500); - } - - @Test(groups = "unit", expectedExceptions = TimeoutException.class) - public void testAcquireWithZeroTimeout() throws Exception { - testAcquireTimeout(0); - } - - private static void testAcquireTimeout(long timeoutMillis) throws Exception { - LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID); - Bootstrap cb = new Bootstrap(); - cb.remoteAddress(addr); - cb.group(group).channel(LocalChannel.class); - - ServerBootstrap sb = new ServerBootstrap(); - sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(LocalChannel ch) throws Exception { - ch.pipeline().addLast(new ChannelInboundHandlerAdapter()); - } - }); - - // Start server - Channel sc = sb.bind(addr).syncUninterruptibly().channel(); - ChannelPoolHandler handler = new TestChannelPoolHandler(); - ChannelPool pool = new EspressoFixedChannelPool( - cb, - handler, - ChannelHealthChecker.ACTIVE, - AcquireTimeoutAction.FAIL, - timeoutMillis, - 1, - Integer.MAX_VALUE); - - Channel channel = pool.acquire().syncUninterruptibly().getNow(); - Future future = pool.acquire(); - try { - future.syncUninterruptibly(); - } finally { - sc.close().syncUninterruptibly(); - channel.close().syncUninterruptibly(); - } - } - - @Test(groups = "unit") - public void testAcquireNewConnection() throws Exception { - LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID); - Bootstrap cb = new Bootstrap(); - cb.remoteAddress(addr); - cb.group(group).channel(LocalChannel.class); - - ServerBootstrap sb = new ServerBootstrap(); - sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(LocalChannel ch) throws Exception { - ch.pipeline().addLast(new ChannelInboundHandlerAdapter()); - } - }); - - // Start server - Channel sc = sb.bind(addr).syncUninterruptibly().channel(); - ChannelPoolHandler handler = new TestChannelPoolHandler(); - ChannelPool pool = new EspressoFixedChannelPool( - cb, - handler, - ChannelHealthChecker.ACTIVE, - AcquireTimeoutAction.NEW, - 500, - 1, - Integer.MAX_VALUE); - - Channel channel = pool.acquire().syncUninterruptibly().getNow(); - Channel channel2 = pool.acquire().syncUninterruptibly().getNow(); - assertNotSame(channel, channel2); - sc.close().syncUninterruptibly(); - channel.close().syncUninterruptibly(); - channel2.close().syncUninterruptibly(); - } - - /** - * Tests that the acquiredChannelCount is not added up several times for the same channel acquire request. - * @throws Exception - */ - @Test(groups = "unit") - public void testAcquireNewConnectionWhen() throws Exception { - LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID); - Bootstrap cb = new Bootstrap(); - cb.remoteAddress(addr); - cb.group(group).channel(LocalChannel.class); - - ServerBootstrap sb = new ServerBootstrap(); - sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(LocalChannel ch) throws Exception { - ch.pipeline().addLast(new ChannelInboundHandlerAdapter()); - } - }); - - // Start server - Channel sc = sb.bind(addr).syncUninterruptibly().channel(); - ChannelPoolHandler handler = new TestChannelPoolHandler(); - ChannelPool pool = new EspressoFixedChannelPool(cb, handler, 1); - Channel channel1 = pool.acquire().syncUninterruptibly().getNow(); - channel1.close().syncUninterruptibly(); - pool.release(channel1); - - Channel channel2 = pool.acquire().syncUninterruptibly().getNow(); - - assertNotSame(channel1, channel2); - sc.close().syncUninterruptibly(); - channel2.close().syncUninterruptibly(); - } - - @Test(groups = "unit", expectedExceptions = IllegalStateException.class) - public void testAcquireBoundQueue() throws Exception { - LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID); - Bootstrap cb = new Bootstrap(); - cb.remoteAddress(addr); - cb.group(group).channel(LocalChannel.class); - - ServerBootstrap sb = new ServerBootstrap(); - sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(LocalChannel ch) throws Exception { - ch.pipeline().addLast(new ChannelInboundHandlerAdapter()); - } - }); - - // Start server - Channel sc = sb.bind(addr).syncUninterruptibly().channel(); - ChannelPoolHandler handler = new TestChannelPoolHandler(); - ChannelPool pool = new EspressoFixedChannelPool(cb, handler, 1, 1); - - Channel channel = pool.acquire().syncUninterruptibly().getNow(); - Future future = pool.acquire(); - assertFalse(future.isDone()); - - try { - pool.acquire().syncUninterruptibly(); - } finally { - sc.close().syncUninterruptibly(); - channel.close().syncUninterruptibly(); - } - } - - @Test(groups = "unit", expectedExceptions = IllegalArgumentException.class) - public void testReleaseDifferentPool() throws Exception { - LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID); - Bootstrap cb = new Bootstrap(); - cb.remoteAddress(addr); - cb.group(group).channel(LocalChannel.class); - - ServerBootstrap sb = new ServerBootstrap(); - sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(LocalChannel ch) throws Exception { - ch.pipeline().addLast(new ChannelInboundHandlerAdapter()); - } - }); - - // Start server - Channel sc = sb.bind(addr).syncUninterruptibly().channel(); - ChannelPoolHandler handler = new TestChannelPoolHandler(); - ChannelPool pool = new EspressoFixedChannelPool(cb, handler, 1, 1); - ChannelPool pool2 = new EspressoFixedChannelPool(cb, handler, 1, 1); - - Channel channel = pool.acquire().syncUninterruptibly().getNow(); - - try { - pool2.release(channel).syncUninterruptibly(); - } finally { - sc.close().syncUninterruptibly(); - channel.close().syncUninterruptibly(); - } - } - - @Test(groups = "unit") - public void testReleaseAfterClosePool() throws Exception { - LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID); - Bootstrap cb = new Bootstrap(); - cb.remoteAddress(addr); - cb.group(group).channel(LocalChannel.class); - - ServerBootstrap sb = new ServerBootstrap(); - sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(LocalChannel ch) throws Exception { - ch.pipeline().addLast(new ChannelInboundHandlerAdapter()); - } - }); - - // Start server - Channel sc = sb.bind(addr).syncUninterruptibly().channel(); - - EspressoFixedChannelPool pool = new EspressoFixedChannelPool(cb, new TestChannelPoolHandler(), 2); - final Future acquire = pool.acquire(); - final Channel channel = acquire.get(); - pool.close(); - group.submit(new Runnable() { - @Override - public void run() { - // NOOP - } - }).syncUninterruptibly(); - try { - pool.release(channel).syncUninterruptibly(); - fail(); - } catch (IllegalStateException e) { - // expected - } - // Since the pool is closed, the Channel should have been closed as well. - channel.closeFuture().syncUninterruptibly(); - assertFalse(channel.isOpen()); - sc.close().syncUninterruptibly(); - } - - @Test(groups = "unit") - public void testReleaseClosed() { - LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID); - Bootstrap cb = new Bootstrap(); - cb.remoteAddress(addr); - cb.group(group).channel(LocalChannel.class); - - ServerBootstrap sb = new ServerBootstrap(); - sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(LocalChannel ch) throws Exception { - ch.pipeline().addLast(new ChannelInboundHandlerAdapter()); - } - }); - - // Start server - Channel sc = sb.bind(addr).syncUninterruptibly().channel(); - - EspressoFixedChannelPool pool = new EspressoFixedChannelPool(cb, new TestChannelPoolHandler(), 2); - Channel channel = pool.acquire().syncUninterruptibly().getNow(); - channel.close().syncUninterruptibly(); - pool.release(channel).syncUninterruptibly(); - - sc.close().syncUninterruptibly(); - } - - @Test(groups = "unit") - public void testCloseAsync() throws ExecutionException, InterruptedException { - LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID); - Bootstrap cb = new Bootstrap(); - cb.remoteAddress(addr); - cb.group(group).channel(LocalChannel.class); - - ServerBootstrap sb = new ServerBootstrap(); - sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(LocalChannel ch) throws Exception { - ch.pipeline().addLast(new ChannelInboundHandlerAdapter()); - } - }); - - // Start server - final Channel sc = sb.bind(addr).syncUninterruptibly().channel(); - - final EspressoFixedChannelPool pool = new EspressoFixedChannelPool(cb, new TestChannelPoolHandler(), 2); - - pool.acquire().get(); - pool.acquire().get(); - - final ChannelPromise closePromise = sc.newPromise(); - pool.closeAsync().addListener(new GenericFutureListener>() { - @Override - public void operationComplete(Future future) throws Exception { - Assert.assertEquals(0, pool.acquiredChannelCount()); - sc.close(closePromise).syncUninterruptibly(); - } - }).awaitUninterruptibly(); - closePromise.awaitUninterruptibly(); - } - - private static final class TestChannelPoolHandler extends AbstractChannelPoolHandler { - @Override - public void channelCreated(Channel ch) throws Exception { - // NOOP - } - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestEspressoSimpleChannelPool.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestEspressoSimpleChannelPool.java deleted file mode 100644 index dafc751f931..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestEspressoSimpleChannelPool.java +++ /dev/null @@ -1,321 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import static org.testng.AssertJUnit.assertEquals; -import static org.testng.AssertJUnit.assertFalse; -import static org.testng.AssertJUnit.assertNotNull; -import static org.testng.AssertJUnit.assertNotSame; -import static org.testng.AssertJUnit.assertSame; -import static org.testng.AssertJUnit.assertTrue; -import static org.testng.AssertJUnit.fail; - -import io.netty.bootstrap.Bootstrap; -import io.netty.bootstrap.ServerBootstrap; -import io.netty.channel.Channel; -import io.netty.channel.ChannelInboundHandlerAdapter; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.DefaultEventLoopGroup; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.local.LocalAddress; -import io.netty.channel.local.LocalChannel; -import io.netty.channel.local.LocalServerChannel; -import io.netty.channel.pool.ChannelHealthChecker; -import io.netty.channel.pool.ChannelPool; -import io.netty.channel.pool.ChannelPoolHandler; -import io.netty.util.concurrent.Future; -import java.util.Queue; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.atomic.AtomicInteger; -import org.testng.Assert; -import org.testng.annotations.Test; - - -/** - * - * Forked from Netty's SimplehannelPoolTest - * - */ -public class TestEspressoSimpleChannelPool { - private static final String LOCAL_ADDR_ID = "test.id"; - - static class CountingChannelPoolHandler implements ChannelPoolHandler { - private final AtomicInteger channelCount = new AtomicInteger(0); - private final AtomicInteger acquiredCount = new AtomicInteger(0); - private final AtomicInteger releasedCount = new AtomicInteger(0); - - @Override - public void channelCreated(Channel ch) { - channelCount.incrementAndGet(); - } - - @Override - public void channelReleased(Channel ch) { - releasedCount.incrementAndGet(); - } - - @Override - public void channelAcquired(Channel ch) { - acquiredCount.incrementAndGet(); - } - - public int channelCount() { - return channelCount.get(); - } - - public int acquiredCount() { - return acquiredCount.get(); - } - - public int releasedCount() { - return releasedCount.get(); - } - } - - @Test(groups = "unit") - public void testAcquire() throws Exception { - EventLoopGroup group = new DefaultEventLoopGroup(); - LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID); - Bootstrap cb = new Bootstrap(); - cb.remoteAddress(addr); - cb.group(group).channel(LocalChannel.class); - - ServerBootstrap sb = new ServerBootstrap(); - sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(LocalChannel ch) throws Exception { - ch.pipeline().addLast(new ChannelInboundHandlerAdapter()); - } - }); - - // Start server - Channel sc = sb.bind(addr).sync().channel(); - CountingChannelPoolHandler handler = new CountingChannelPoolHandler(); - - ChannelPool pool = new EspressoSimpleChannelPool(cb, handler); - - Channel channel = pool.acquire().sync().getNow(); - - pool.release(channel).syncUninterruptibly(); - - Channel channel2 = pool.acquire().sync().getNow(); - Assert.assertSame(channel, channel2); - Assert.assertEquals(1, handler.channelCount()); - pool.release(channel2).syncUninterruptibly(); - - // Should fail on multiple release calls. - try { - pool.release(channel2).syncUninterruptibly(); - fail(); - } catch (IllegalArgumentException e) { - // expected - assertFalse(channel.isActive()); - } - - assertEquals(2, handler.acquiredCount()); - assertEquals(2, handler.releasedCount()); - - sc.close().sync(); - group.shutdownGracefully(); - } - - @Test(groups = "unit") - public void testBoundedChannelPoolSegment() throws Exception { - EventLoopGroup group = new DefaultEventLoopGroup(); - LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID); - Bootstrap cb = new Bootstrap(); - cb.remoteAddress(addr); - cb.group(group).channel(LocalChannel.class); - - ServerBootstrap sb = new ServerBootstrap(); - sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(LocalChannel ch) throws Exception { - ch.pipeline().addLast(new ChannelInboundHandlerAdapter()); - } - }); - - // Start server - Channel sc = sb.bind(addr).sync().channel(); - CountingChannelPoolHandler handler = new CountingChannelPoolHandler(); - - ChannelPool pool = new EspressoSimpleChannelPool(cb, handler, ChannelHealthChecker.ACTIVE) { - private final Queue queue = new LinkedBlockingQueue(1); - - @Override - protected Channel pollChannel() { - return queue.poll(); - } - - @Override - protected boolean offerChannel(Channel ch) { - return queue.offer(ch); - } - }; - - Channel channel = pool.acquire().sync().getNow(); - Channel channel2 = pool.acquire().sync().getNow(); - - pool.release(channel).syncUninterruptibly().getNow(); - try { - pool.release(channel2).syncUninterruptibly(); - fail(); - } catch (IllegalStateException e) { - // expected - } - channel2.close().sync(); - - assertEquals(2, handler.channelCount()); - assertEquals(2, handler.acquiredCount()); - assertEquals(1, handler.releasedCount()); - sc.close().sync(); - channel.close().sync(); - channel2.close().sync(); - group.shutdownGracefully(); - } - - /** - * Tests that if channel was unhealthy it is not offered back to the pool. - * - * @throws Exception - */ - @Test(groups = "unit") - public void testUnhealthyChannelIsNotOffered() throws Exception { - EventLoopGroup group = new DefaultEventLoopGroup(); - LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID); - Bootstrap cb = new Bootstrap(); - cb.remoteAddress(addr); - cb.group(group).channel(LocalChannel.class); - - ServerBootstrap sb = new ServerBootstrap(); - sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(LocalChannel ch) throws Exception { - ch.pipeline().addLast(new ChannelInboundHandlerAdapter()); - } - }); - - // Start server - Channel sc = sb.bind(addr).syncUninterruptibly().channel(); - ChannelPoolHandler handler = new CountingChannelPoolHandler(); - ChannelPool pool = new EspressoSimpleChannelPool(cb, handler); - Channel channel1 = pool.acquire().syncUninterruptibly().getNow(); - pool.release(channel1).syncUninterruptibly(); - Channel channel2 = pool.acquire().syncUninterruptibly().getNow(); - // first check that when returned healthy then it actually offered back to the pool. - assertSame(channel1, channel2); - - channel1.close().syncUninterruptibly(); - - pool.release(channel1).syncUninterruptibly(); - Channel channel3 = pool.acquire().syncUninterruptibly().getNow(); - // channel1 was not healthy anymore so it should not get acquired anymore. - assertNotSame(channel1, channel3); - sc.close().syncUninterruptibly(); - channel3.close().syncUninterruptibly(); - group.shutdownGracefully(); - } - - /** - * Tests that if channel was unhealthy it is was offered back to the pool because - * it was requested not to validate channel health on release. - * - * @throws Exception - */ - @Test(groups = "unit") - public void testUnhealthyChannelIsOfferedWhenNoHealthCheckRequested() throws Exception { - EventLoopGroup group = new DefaultEventLoopGroup(); - LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID); - Bootstrap cb = new Bootstrap(); - cb.remoteAddress(addr); - cb.group(group).channel(LocalChannel.class); - - ServerBootstrap sb = new ServerBootstrap(); - sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(LocalChannel ch) throws Exception { - ch.pipeline().addLast(new ChannelInboundHandlerAdapter()); - } - }); - - // Start server - Channel sc = sb.bind(addr).syncUninterruptibly().channel(); - ChannelPoolHandler handler = new CountingChannelPoolHandler(); - ChannelPool pool = new EspressoSimpleChannelPool(cb, handler, ChannelHealthChecker.ACTIVE, false); - Channel channel1 = pool.acquire().syncUninterruptibly().getNow(); - channel1.close().syncUninterruptibly(); - Future releaseFuture = pool.release(channel1, channel1.eventLoop().newPromise()).syncUninterruptibly(); - Assert.assertTrue(releaseFuture.isSuccess()); - - Channel channel2 = pool.acquire().syncUninterruptibly().getNow(); - // verifying that in fact the channel2 is different that means is not pulled from the pool - assertNotSame(channel1, channel2); - sc.close().syncUninterruptibly(); - channel2.close().syncUninterruptibly(); - group.shutdownGracefully(); - } - - @Test(groups = "unit") - public void testBootstrap() { - final EspressoSimpleChannelPool pool = - new EspressoSimpleChannelPool(new Bootstrap(), new CountingChannelPoolHandler()); - - try { - // Checking for the actual bootstrap object doesn't make sense here, since the pool uses a copy with a - // modified channel handler. - assertNotNull(pool.bootstrap()); - } finally { - pool.close(); - } - } - - @Test(groups = "unit") - public void testHandler() { - final ChannelPoolHandler handler = new CountingChannelPoolHandler(); - final EspressoSimpleChannelPool pool = new EspressoSimpleChannelPool(new Bootstrap(), handler); - - try { - assertSame(handler, pool.handler()); - } finally { - pool.close(); - } - } - - @Test(groups = "unit") - public void testHealthChecker() { - final ChannelHealthChecker healthChecker = ChannelHealthChecker.ACTIVE; - final EspressoSimpleChannelPool pool = - new EspressoSimpleChannelPool(new Bootstrap(), new CountingChannelPoolHandler(), healthChecker); - - try { - assertSame(healthChecker, pool.healthChecker()); - } finally { - pool.close(); - } - } - - @Test(groups = "unit") - public void testReleaseHealthCheck() { - final EspressoSimpleChannelPool healthCheckOnReleasePool = new EspressoSimpleChannelPool( - new Bootstrap(), - new CountingChannelPoolHandler(), - ChannelHealthChecker.ACTIVE, - true); - - try { - assertTrue(healthCheckOnReleasePool.releaseHealthCheck()); - } finally { - healthCheckOnReleasePool.close(); - } - - final EspressoSimpleChannelPool noHealthCheckOnReleasePool = new EspressoSimpleChannelPool( - new Bootstrap(), - new CountingChannelPoolHandler(), - ChannelHealthChecker.ACTIVE, - false); - - try { - assertFalse(noHealthCheckOnReleasePool.releaseHealthCheck()); - } finally { - noHealthCheckOnReleasePool.close(); - } - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestFastFixedChannelPool.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestFastFixedChannelPool.java deleted file mode 100644 index 35db4ac89e8..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestFastFixedChannelPool.java +++ /dev/null @@ -1,416 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertNotSame; -import static org.testng.Assert.assertSame; -import static org.testng.Assert.assertTrue; -import static org.testng.Assert.fail; - -import io.netty.bootstrap.Bootstrap; -import io.netty.bootstrap.ServerBootstrap; -import io.netty.channel.Channel; -import io.netty.channel.ChannelInboundHandlerAdapter; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.ChannelPromise; -import io.netty.channel.DefaultEventLoopGroup; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.local.LocalAddress; -import io.netty.channel.local.LocalChannel; -import io.netty.channel.local.LocalServerChannel; -import io.netty.channel.pool.AbstractChannelPoolHandler; -import io.netty.channel.pool.ChannelHealthChecker; -import io.netty.channel.pool.ChannelPool; -import io.netty.channel.pool.ChannelPoolHandler; -import io.netty.channel.pool.FixedChannelPool.AcquireTimeoutAction; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.GenericFutureListener; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicInteger; -import org.testng.Assert; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - - -/** - * - * Forked from Netty's FixedChannelPoolTest - * - */ -public class TestFastFixedChannelPool { - private static final String LOCAL_ADDR_ID = "test.id"; - - private EventLoopGroup group; - - @BeforeMethod(groups = "unit") - public void createEventLoop() { - group = new DefaultEventLoopGroup(); - } - - @AfterMethod(groups = "unit") - public void destroyEventLoop() throws InterruptedException { - if (group != null) { - group.shutdownGracefully().sync(); - } - } - - static class CountingChannelPoolHandler implements ChannelPoolHandler { - private final AtomicInteger channelCount = new AtomicInteger(0); - private final AtomicInteger acquiredCount = new AtomicInteger(0); - private final AtomicInteger releasedCount = new AtomicInteger(0); - - @Override - public void channelCreated(Channel ch) { - channelCount.incrementAndGet(); - } - - @Override - public void channelReleased(Channel ch) { - releasedCount.incrementAndGet(); - } - - @Override - public void channelAcquired(Channel ch) { - acquiredCount.incrementAndGet(); - } - - public int channelCount() { - return channelCount.get(); - } - - public int acquiredCount() { - return acquiredCount.get(); - } - - public int releasedCount() { - return releasedCount.get(); - } - } - - @Test(groups = "unit") - public void testAcquire() throws Exception { - LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID); - Bootstrap cb = new Bootstrap(); - cb.remoteAddress(addr); - cb.group(group).channel(LocalChannel.class); - - ServerBootstrap sb = new ServerBootstrap(); - sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(LocalChannel ch) throws Exception { - ch.pipeline().addLast(new ChannelInboundHandlerAdapter()); - } - }); - - // Start server - Channel sc = sb.bind(addr).syncUninterruptibly().channel(); - CountingChannelPoolHandler handler = new CountingChannelPoolHandler(); - - ChannelPool pool = new FastFixedChannelPool(cb, handler, 1, Integer.MAX_VALUE); - - Channel channel = pool.acquire().syncUninterruptibly().getNow(); - Future future = pool.acquire(); - Assert.assertFalse(future.isDone()); - - pool.release(channel).syncUninterruptibly(); - assertTrue(future.await(1, TimeUnit.SECONDS)); - - Channel channel2 = future.getNow(); - assertSame(channel, channel2); - assertEquals(1, handler.channelCount()); - - assertEquals(2, handler.acquiredCount()); - assertEquals(1, handler.releasedCount()); - - sc.close().syncUninterruptibly(); - channel2.close().syncUninterruptibly(); - } - - @Test(groups = "unit", expectedExceptions = TimeoutException.class) - public void testAcquireTimeout() throws Exception { - testAcquireTimeout(500); - } - - @Test(groups = "unit", expectedExceptions = TimeoutException.class) - public void testAcquireWithZeroTimeout() throws Exception { - testAcquireTimeout(0); - } - - private void testAcquireTimeout(long timeoutMillis) throws Exception { - LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID); - Bootstrap cb = new Bootstrap(); - cb.remoteAddress(addr); - cb.group(group).channel(LocalChannel.class); - - ServerBootstrap sb = new ServerBootstrap(); - sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(LocalChannel ch) throws Exception { - ch.pipeline().addLast(new ChannelInboundHandlerAdapter()); - } - }); - - // Start server - Channel sc = sb.bind(addr).syncUninterruptibly().channel(); - ChannelPoolHandler handler = new TestChannelPoolHandler(); - ChannelPool pool = new FastFixedChannelPool( - cb, - handler, - ChannelHealthChecker.ACTIVE, - AcquireTimeoutAction.FAIL, - timeoutMillis, - 1, - Integer.MAX_VALUE); - - Channel channel = pool.acquire().syncUninterruptibly().getNow(); - Future future = pool.acquire(); - try { - future.syncUninterruptibly(); - } finally { - sc.close().syncUninterruptibly(); - channel.close().syncUninterruptibly(); - } - } - - @Test(groups = "unit") - public void testAcquireNewConnection() throws Exception { - LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID); - Bootstrap cb = new Bootstrap(); - cb.remoteAddress(addr); - cb.group(group).channel(LocalChannel.class); - - ServerBootstrap sb = new ServerBootstrap(); - sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(LocalChannel ch) throws Exception { - ch.pipeline().addLast(new ChannelInboundHandlerAdapter()); - } - }); - - // Start server - Channel sc = sb.bind(addr).syncUninterruptibly().channel(); - ChannelPoolHandler handler = new TestChannelPoolHandler(); - ChannelPool pool = new FastFixedChannelPool( - cb, - handler, - ChannelHealthChecker.ACTIVE, - AcquireTimeoutAction.NEW, - 500, - 1, - Integer.MAX_VALUE); - - Channel channel = pool.acquire().syncUninterruptibly().getNow(); - Channel channel2 = pool.acquire().syncUninterruptibly().getNow(); - assertNotSame(channel, channel2); - sc.close().syncUninterruptibly(); - channel.close().syncUninterruptibly(); - channel2.close().syncUninterruptibly(); - } - - /** - * Tests that the acquiredChannelCount is not added up several times for the same channel acquire request. - * @throws Exception - */ - @Test(groups = "unit") - public void testAcquireNewConnectionWhen() throws Exception { - LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID); - Bootstrap cb = new Bootstrap(); - cb.remoteAddress(addr); - cb.group(group).channel(LocalChannel.class); - - ServerBootstrap sb = new ServerBootstrap(); - sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(LocalChannel ch) throws Exception { - ch.pipeline().addLast(new ChannelInboundHandlerAdapter()); - } - }); - - // Start server - Channel sc = sb.bind(addr).syncUninterruptibly().channel(); - ChannelPoolHandler handler = new TestChannelPoolHandler(); - ChannelPool pool = new FastFixedChannelPool(cb, handler, 1); - Channel channel1 = pool.acquire().syncUninterruptibly().getNow(); - channel1.close().syncUninterruptibly(); - pool.release(channel1); - - Channel channel2 = pool.acquire().syncUninterruptibly().getNow(); - - assertNotSame(channel1, channel2); - sc.close().syncUninterruptibly(); - channel2.close().syncUninterruptibly(); - } - - @Test(groups = "unit", expectedExceptions = IllegalStateException.class) - public void testAcquireBoundQueue() throws Exception { - LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID); - Bootstrap cb = new Bootstrap(); - cb.remoteAddress(addr); - cb.group(group).channel(LocalChannel.class); - - ServerBootstrap sb = new ServerBootstrap(); - sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(LocalChannel ch) throws Exception { - ch.pipeline().addLast(new ChannelInboundHandlerAdapter()); - } - }); - - // Start server - Channel sc = sb.bind(addr).syncUninterruptibly().channel(); - ChannelPoolHandler handler = new TestChannelPoolHandler(); - ChannelPool pool = new FastFixedChannelPool(cb, handler, 1, 1); - - Channel channel = pool.acquire().syncUninterruptibly().getNow(); - Future future = pool.acquire(); - assertFalse(future.isDone()); - - try { - pool.acquire().syncUninterruptibly(); - } finally { - sc.close().syncUninterruptibly(); - channel.close().syncUninterruptibly(); - } - } - - @Test(groups = "unit", expectedExceptions = IllegalArgumentException.class) - public void testReleaseDifferentPool() throws Exception { - LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID); - Bootstrap cb = new Bootstrap(); - cb.remoteAddress(addr); - cb.group(group).channel(LocalChannel.class); - - ServerBootstrap sb = new ServerBootstrap(); - sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(LocalChannel ch) throws Exception { - ch.pipeline().addLast(new ChannelInboundHandlerAdapter()); - } - }); - - // Start server - Channel sc = sb.bind(addr).syncUninterruptibly().channel(); - ChannelPoolHandler handler = new TestChannelPoolHandler(); - ChannelPool pool = new FastFixedChannelPool(cb, handler, 1, 1); - ChannelPool pool2 = new FastFixedChannelPool(cb, handler, 1, 1); - - Channel channel = pool.acquire().syncUninterruptibly().getNow(); - - try { - pool2.release(channel).syncUninterruptibly(); - } finally { - sc.close().syncUninterruptibly(); - channel.close().syncUninterruptibly(); - } - } - - @Test(groups = "unit") - public void testReleaseAfterClosePool() throws Exception { - LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID); - Bootstrap cb = new Bootstrap(); - cb.remoteAddress(addr); - cb.group(group).channel(LocalChannel.class); - - ServerBootstrap sb = new ServerBootstrap(); - sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(LocalChannel ch) throws Exception { - ch.pipeline().addLast(new ChannelInboundHandlerAdapter()); - } - }); - - // Start server - Channel sc = sb.bind(addr).syncUninterruptibly().channel(); - - FastFixedChannelPool pool = new FastFixedChannelPool(cb, new TestChannelPoolHandler(), 2); - final Future acquire = pool.acquire(); - final Channel channel = acquire.get(); - pool.close(); - group.submit(new Runnable() { - @Override - public void run() { - // NOOP - } - }).syncUninterruptibly(); - try { - pool.release(channel).syncUninterruptibly(); - fail(); - } catch (IllegalStateException e) { - // expected - } - // Since the pool is closed, the Channel should have been closed as well. - channel.closeFuture().syncUninterruptibly(); - assertFalse(channel.isOpen()); - sc.close().syncUninterruptibly(); - } - - @Test(groups = "unit") - public void testReleaseClosed() { - LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID); - Bootstrap cb = new Bootstrap(); - cb.remoteAddress(addr); - cb.group(group).channel(LocalChannel.class); - - ServerBootstrap sb = new ServerBootstrap(); - sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(LocalChannel ch) throws Exception { - ch.pipeline().addLast(new ChannelInboundHandlerAdapter()); - } - }); - - // Start server - Channel sc = sb.bind(addr).syncUninterruptibly().channel(); - - FastFixedChannelPool pool = new FastFixedChannelPool(cb, new TestChannelPoolHandler(), 2); - Channel channel = pool.acquire().syncUninterruptibly().getNow(); - channel.close().syncUninterruptibly(); - pool.release(channel).syncUninterruptibly(); - - sc.close().syncUninterruptibly(); - } - - @Test(groups = "unit") - public void testCloseAsync() throws ExecutionException, InterruptedException { - LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID); - Bootstrap cb = new Bootstrap(); - cb.remoteAddress(addr); - cb.group(group).channel(LocalChannel.class); - - ServerBootstrap sb = new ServerBootstrap(); - sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(LocalChannel ch) throws Exception { - ch.pipeline().addLast(new ChannelInboundHandlerAdapter()); - } - }); - - // Start server - final Channel sc = sb.bind(addr).syncUninterruptibly().channel(); - - final FastFixedChannelPool pool = new FastFixedChannelPool(cb, new TestChannelPoolHandler(), 2); - - pool.acquire().get(); - pool.acquire().get(); - - final ChannelPromise closePromise = sc.newPromise(); - pool.closeAsync().addListener(new GenericFutureListener>() { - @Override - public void operationComplete(Future future) throws Exception { - Assert.assertEquals(0, pool.acquiredChannelCount()); - sc.close(closePromise).syncUninterruptibly(); - } - }).awaitUninterruptibly(); - closePromise.awaitUninterruptibly(); - } - - private static final class TestChannelPoolHandler extends AbstractChannelPoolHandler { - @Override - public void channelCreated(Channel ch) throws Exception { - // NOOP - } - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestFastSimpleChannelPool.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestFastSimpleChannelPool.java deleted file mode 100644 index f979567778a..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestFastSimpleChannelPool.java +++ /dev/null @@ -1,317 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import static org.testng.AssertJUnit.assertEquals; -import static org.testng.AssertJUnit.assertFalse; -import static org.testng.AssertJUnit.assertNotNull; -import static org.testng.AssertJUnit.assertNotSame; -import static org.testng.AssertJUnit.assertSame; -import static org.testng.AssertJUnit.assertTrue; -import static org.testng.AssertJUnit.fail; - -import io.netty.bootstrap.Bootstrap; -import io.netty.bootstrap.ServerBootstrap; -import io.netty.channel.Channel; -import io.netty.channel.ChannelInboundHandlerAdapter; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.DefaultEventLoopGroup; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.local.LocalAddress; -import io.netty.channel.local.LocalChannel; -import io.netty.channel.local.LocalServerChannel; -import io.netty.channel.pool.ChannelHealthChecker; -import io.netty.channel.pool.ChannelPool; -import io.netty.channel.pool.ChannelPoolHandler; -import io.netty.util.concurrent.Future; -import java.util.Queue; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.atomic.AtomicInteger; -import org.testng.Assert; -import org.testng.annotations.Test; - - -/** - * - * Forked from Netty's SimplehannelPoolTest - * - */ -public class TestFastSimpleChannelPool { - private static final String LOCAL_ADDR_ID = "test.id"; - - static class CountingChannelPoolHandler implements ChannelPoolHandler { - private final AtomicInteger channelCount = new AtomicInteger(0); - private final AtomicInteger acquiredCount = new AtomicInteger(0); - private final AtomicInteger releasedCount = new AtomicInteger(0); - - @Override - public void channelCreated(Channel ch) { - channelCount.incrementAndGet(); - } - - @Override - public void channelReleased(Channel ch) { - releasedCount.incrementAndGet(); - } - - @Override - public void channelAcquired(Channel ch) { - acquiredCount.incrementAndGet(); - } - - public int channelCount() { - return channelCount.get(); - } - - public int acquiredCount() { - return acquiredCount.get(); - } - - public int releasedCount() { - return releasedCount.get(); - } - } - - @Test(groups = "unit") - public void testAcquire() throws Exception { - EventLoopGroup group = new DefaultEventLoopGroup(); - LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID); - Bootstrap cb = new Bootstrap(); - cb.remoteAddress(addr); - cb.group(group).channel(LocalChannel.class); - - ServerBootstrap sb = new ServerBootstrap(); - sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(LocalChannel ch) throws Exception { - ch.pipeline().addLast(new ChannelInboundHandlerAdapter()); - } - }); - - // Start server - Channel sc = sb.bind(addr).sync().channel(); - CountingChannelPoolHandler handler = new CountingChannelPoolHandler(); - - ChannelPool pool = new FastSimpleChannelPool(cb, handler); - - Channel channel = pool.acquire().sync().getNow(); - - pool.release(channel).syncUninterruptibly(); - - Channel channel2 = pool.acquire().sync().getNow(); - Assert.assertSame(channel, channel2); - Assert.assertEquals(1, handler.channelCount()); - pool.release(channel2).syncUninterruptibly(); - - // Should fail on multiple release calls. - try { - pool.release(channel2).syncUninterruptibly(); - fail(); - } catch (IllegalArgumentException e) { - // expected - assertFalse(channel.isActive()); - } - - assertEquals(2, handler.acquiredCount()); - assertEquals(2, handler.releasedCount()); - - sc.close().sync(); - group.shutdownGracefully(); - } - - @Test(groups = "unit") - public void testBoundedChannelPoolSegment() throws Exception { - EventLoopGroup group = new DefaultEventLoopGroup(); - LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID); - Bootstrap cb = new Bootstrap(); - cb.remoteAddress(addr); - cb.group(group).channel(LocalChannel.class); - - ServerBootstrap sb = new ServerBootstrap(); - sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(LocalChannel ch) throws Exception { - ch.pipeline().addLast(new ChannelInboundHandlerAdapter()); - } - }); - - // Start server - Channel sc = sb.bind(addr).sync().channel(); - CountingChannelPoolHandler handler = new CountingChannelPoolHandler(); - - ChannelPool pool = new FastSimpleChannelPool(cb, handler, ChannelHealthChecker.ACTIVE) { - private final Queue queue = new LinkedBlockingQueue(1); - - @Override - protected Channel pollChannel() { - return queue.poll(); - } - - @Override - protected boolean offerChannel(Channel ch) { - return queue.offer(ch); - } - }; - - Channel channel = pool.acquire().sync().getNow(); - Channel channel2 = pool.acquire().sync().getNow(); - - pool.release(channel).syncUninterruptibly().getNow(); - try { - pool.release(channel2).syncUninterruptibly(); - fail(); - } catch (IllegalStateException e) { - // expected - } - channel2.close().sync(); - - assertEquals(2, handler.channelCount()); - assertEquals(2, handler.acquiredCount()); - assertEquals(2, handler.releasedCount()); // release is now called before offerChannel() - sc.close().sync(); - channel.close().sync(); - channel2.close().sync(); - group.shutdownGracefully(); - } - - /** - * Tests that if channel was unhealthy it is not offered back to the pool. - * - * @throws Exception - */ - @Test(groups = "unit") - public void testUnhealthyChannelIsNotOffered() throws Exception { - EventLoopGroup group = new DefaultEventLoopGroup(); - LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID); - Bootstrap cb = new Bootstrap(); - cb.remoteAddress(addr); - cb.group(group).channel(LocalChannel.class); - - ServerBootstrap sb = new ServerBootstrap(); - sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(LocalChannel ch) throws Exception { - ch.pipeline().addLast(new ChannelInboundHandlerAdapter()); - } - }); - - // Start server - Channel sc = sb.bind(addr).syncUninterruptibly().channel(); - ChannelPoolHandler handler = new CountingChannelPoolHandler(); - ChannelPool pool = new FastSimpleChannelPool(cb, handler); - Channel channel1 = pool.acquire().syncUninterruptibly().getNow(); - pool.release(channel1).syncUninterruptibly(); - Channel channel2 = pool.acquire().syncUninterruptibly().getNow(); - // first check that when returned healthy then it actually offered back to the pool. - assertSame(channel1, channel2); - - channel1.close().syncUninterruptibly(); - - pool.release(channel1).syncUninterruptibly(); - Channel channel3 = pool.acquire().syncUninterruptibly().getNow(); - // channel1 was not healthy anymore so it should not get acquired anymore. - assertNotSame(channel1, channel3); - sc.close().syncUninterruptibly(); - channel3.close().syncUninterruptibly(); - group.shutdownGracefully(); - } - - /** - * Tests that if channel was unhealthy it is was offered back to the pool because - * it was requested not to validate channel health on release. - * - * @throws Exception - */ - @Test(groups = "unit") - public void testUnhealthyChannelIsOfferedWhenNoHealthCheckRequested() throws Exception { - EventLoopGroup group = new DefaultEventLoopGroup(); - LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID); - Bootstrap cb = new Bootstrap(); - cb.remoteAddress(addr); - cb.group(group).channel(LocalChannel.class); - - ServerBootstrap sb = new ServerBootstrap(); - sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer() { - @Override - public void initChannel(LocalChannel ch) throws Exception { - ch.pipeline().addLast(new ChannelInboundHandlerAdapter()); - } - }); - - // Start server - Channel sc = sb.bind(addr).syncUninterruptibly().channel(); - ChannelPoolHandler handler = new CountingChannelPoolHandler(); - ChannelPool pool = new FastSimpleChannelPool(cb, handler, ChannelHealthChecker.ACTIVE, false); - Channel channel1 = pool.acquire().syncUninterruptibly().getNow(); - channel1.close().syncUninterruptibly(); - Future releaseFuture = pool.release(channel1, channel1.eventLoop().newPromise()).syncUninterruptibly(); - Assert.assertTrue(releaseFuture.isSuccess()); - - Channel channel2 = pool.acquire().syncUninterruptibly().getNow(); - // verifying that in fact the channel2 is different that means is not pulled from the pool - assertNotSame(channel1, channel2); - sc.close().syncUninterruptibly(); - channel2.close().syncUninterruptibly(); - group.shutdownGracefully(); - } - - @Test(groups = "unit") - public void testBootstrap() { - final FastSimpleChannelPool pool = new FastSimpleChannelPool(new Bootstrap(), new CountingChannelPoolHandler()); - - try { - // Checking for the actual bootstrap object doesn't make sense here, since the pool uses a copy with a - // modified channel handler. - assertNotNull(pool.bootstrap()); - } finally { - pool.close(); - } - } - - @Test(groups = "unit") - public void testHandler() { - final ChannelPoolHandler handler = new CountingChannelPoolHandler(); - final FastSimpleChannelPool pool = new FastSimpleChannelPool(new Bootstrap(), handler); - - try { - assertSame(handler, pool.handler()); - } finally { - pool.close(); - } - } - - @Test(groups = "unit") - public void testHealthChecker() { - final ChannelHealthChecker healthChecker = ChannelHealthChecker.ACTIVE; - final FastSimpleChannelPool pool = - new FastSimpleChannelPool(new Bootstrap(), new CountingChannelPoolHandler(), healthChecker); - - try { - assertSame(healthChecker, pool.healthChecker()); - } finally { - pool.close(); - } - } - - @Test(groups = "unit") - public void testReleaseHealthCheck() { - final FastSimpleChannelPool healthCheckOnReleasePool = - new FastSimpleChannelPool(new Bootstrap(), new CountingChannelPoolHandler(), ChannelHealthChecker.ACTIVE, true); - - try { - assertTrue(healthCheckOnReleasePool.releaseHealthCheck()); - } finally { - healthCheckOnReleasePool.close(); - } - - final FastSimpleChannelPool noHealthCheckOnReleasePool = new FastSimpleChannelPool( - new Bootstrap(), - new CountingChannelPoolHandler(), - ChannelHealthChecker.ACTIVE, - false); - - try { - assertFalse(noHealthCheckOnReleasePool.releaseHealthCheck()); - } finally { - noHealthCheckOnReleasePool.close(); - } - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestFixedChannelPoolImpl.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestFixedChannelPoolImpl.java deleted file mode 100644 index c2a6c27522d..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestFixedChannelPoolImpl.java +++ /dev/null @@ -1,298 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import com.linkedin.alpini.base.misc.Time; -import com.linkedin.alpini.netty4.handlers.Log4J2LoggingHandler; -import io.netty.bootstrap.Bootstrap; -import io.netty.bootstrap.ServerBootstrap; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.local.LocalAddress; -import io.netty.channel.local.LocalChannel; -import io.netty.channel.local.LocalServerChannel; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.pool.ChannelHealthChecker; -import io.netty.channel.pool.ChannelPoolHandler; -import io.netty.channel.pool.FixedChannelPool; -import io.netty.handler.logging.LogLevel; -import io.netty.handler.logging.LoggingHandler; -import io.netty.util.concurrent.Future; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.LongAdder; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - - -/** - * Created by acurtis on 5/8/18. - */ -public class TestFixedChannelPoolImpl { - private static final Logger LOG = LogManager.getLogger(TestFixedChannelPoolImpl.class); - - private EventLoopGroup _eventLoopGroup; - - @BeforeClass(groups = "unit") - public void beforeClass() { - _eventLoopGroup = new NioEventLoopGroup(1); - } - - @AfterClass(groups = "unit") - public void afterClass() { - Optional.ofNullable(_eventLoopGroup).ifPresent(EventLoopGroup::shutdownGracefully); - } - - @DataProvider - public Object[][] useQueueSizeForAcquiredChannelCount() { - return new Object[][] { new Object[] { true }, new Object[] { false } }; - } - - @Test(groups = "unit", dataProvider = "useQueueSizeForAcquiredChannelCount") - public void testMinPoolSize(boolean useQueueSizeForAcquiredChannelCount) throws InterruptedException { - - LocalAddress localAddress = new LocalAddress("testMinPoolSize"); - - LoggingHandler listenLog = new Log4J2LoggingHandler("listen", LogLevel.DEBUG); - LoggingHandler serverLog = new Log4J2LoggingHandler("server", LogLevel.DEBUG); - - ServerBootstrap serverBootstrap = new ServerBootstrap().group(_eventLoopGroup) - .channel(LocalServerChannel.class) - .handler(listenLog) - .childHandler(new ChannelInitializer() { - @Override - protected void initChannel(Channel ch) throws Exception { - ch.pipeline().addLast(serverLog); - } - }); - - Bootstrap bootstrap = - new Bootstrap().group(_eventLoopGroup).channel(LocalChannel.class).remoteAddress(localAddress); - - ChannelFuture server = serverBootstrap.bind(localAddress).sync(); - try { - - int minConnections = 10; - int maxConnections = 100; - int maxPendingAcquires = 100; - - LongAdder createAdder = new LongAdder(); - LongAdder closeAdder = new LongAdder(); - - FixedChannelPoolImpl pool = createNewFixedChannelPool( - useQueueSizeForAcquiredChannelCount, - bootstrap, - minConnections, - maxConnections, - maxPendingAcquires, - createAdder, - closeAdder); - - Thread.sleep(100L); - - Assert.assertEquals(pool.getConnectedChannels(), 0); - Assert.assertEquals(pool.getAcquiredChannelCount(), 0); - CountDownLatch released = new CountDownLatch(1); - - { - Future channelFuture = CompletableFuture.supplyAsync(pool::acquire, _eventLoopGroup.next()).join(); - channelFuture.sync(); - Assert.assertTrue(channelFuture.isSuccess()); - Assert.assertEquals(pool.getAcquiredChannelCount(), 1); - _eventLoopGroup.execute(() -> pool.release(channelFuture.getNow()).addListener(f -> released.countDown())); - } - - { - Future channelFuture = CompletableFuture.supplyAsync(pool::acquire, _eventLoopGroup.next()).join(); - channelFuture.sync(); - Assert.assertTrue(channelFuture.isSuccess()); - _eventLoopGroup.execute(() -> pool.release(channelFuture.getNow()).addListener(f -> released.countDown())); - } - - long timeout = Time.currentTimeMillis() + 1000L; - do { - Thread.sleep(100L); - LOG.info("created={}, closed={}", createAdder, closeAdder); - } while (pool.getConnectedChannels() != minConnections && timeout > Time.currentTimeMillis()); - - Assert.assertEquals(pool.getConnectedChannels(), minConnections); - Assert.assertEquals(createAdder.intValue(), minConnections); - Assert.assertEquals(closeAdder.intValue(), 0); - - released.await(); - Assert.assertEquals(pool.getAcquiredChannelCount(), 0); - - { - Future channelFuture = CompletableFuture.supplyAsync(pool::acquire, _eventLoopGroup.next()).join(); - channelFuture.sync(); - Assert.assertTrue(channelFuture.isSuccess()); - - Assert.assertEquals(pool.getConnectedChannels(), minConnections); - Assert.assertEquals(createAdder.intValue(), minConnections); - Assert.assertEquals(closeAdder.intValue(), 0); - - _eventLoopGroup.execute(() -> pool.release(channelFuture.getNow())); - } - - CountDownLatch latch = new CountDownLatch(1); - - // To test ESPENG-22776 - pool.acquire().addListener((Future f) -> { - if (f.isSuccess()) { - LOG.info("Before close :" + pool.acquiredChannelCount()); - Assert.assertEquals(pool.acquiredChannelCount(), 1); - - // Close the channel - f.getNow().close().addListener(ignored -> f.getNow().eventLoop().execute(() -> { - Assert.assertEquals(pool.acquiredChannelCount(), 0); - LOG.info("After close :" + pool.acquiredChannelCount()); - - // Release the channel - pool.release(f.getNow()).addListener(bar -> { - Assert.assertEquals(pool.acquiredChannelCount(), 0); - LOG.info("After release :" + pool.acquiredChannelCount()); - latch.countDown(); - }); - })); - } - }); - - latch.await(); - LOG.info("closing pool {}", pool); - CompletableFuture.runAsync(pool::close, _eventLoopGroup.next()).join(); - - timeout = Time.currentTimeMillis() + 1000L; - do { - Thread.sleep(100L); - LOG.info("created={}, closed={}", createAdder, closeAdder); - } while (pool.getConnectedChannels() != 0 && timeout > Time.currentTimeMillis()); - - Assert.assertEquals(pool.getConnectedChannels(), 0); - Assert.assertEquals(closeAdder.intValue(), minConnections); - } finally { - server.channel().close().sync(); - } - } - - @Test(groups = "unit", dataProvider = "useQueueSizeForAcquiredChannelCount") - public void testPoolClose(boolean useQueueSizeForAcquiredChannelCount) throws InterruptedException { - LocalAddress localAddress = new LocalAddress("testPoolClose"); - - LoggingHandler listenLog = new Log4J2LoggingHandler("listen", LogLevel.DEBUG); - LoggingHandler serverLog = new Log4J2LoggingHandler("server", LogLevel.DEBUG); - - ServerBootstrap serverBootstrap = new ServerBootstrap().group(_eventLoopGroup) - .channel(LocalServerChannel.class) - .handler(listenLog) - .childHandler(new ChannelInitializer() { - @Override - protected void initChannel(Channel ch) throws Exception { - ch.pipeline().addLast(serverLog); - } - }); - - Bootstrap bootstrap = - new Bootstrap().group(_eventLoopGroup).channel(LocalChannel.class).remoteAddress(localAddress); - - ChannelFuture server = serverBootstrap.bind(localAddress).sync(); - try { - - int minConnections = 10; - int maxConnections = 100; - int maxPendingAcquires = 100; - - LongAdder createAdder = new LongAdder(); - LongAdder closeAdder = new LongAdder(); - - FixedChannelPoolImpl pool = createNewFixedChannelPool( - useQueueSizeForAcquiredChannelCount, - bootstrap, - minConnections, - maxConnections, - maxPendingAcquires, - createAdder, - closeAdder); - - Time.sleep(100L); - - Assert.assertEquals(pool.getConnectedChannels(), 0); - - // Acquire a connection, which will kick off the connection build process - { - Future channelFuture = CompletableFuture.supplyAsync(pool::acquire, _eventLoopGroup.next()).join(); - channelFuture.sync(); - Assert.assertTrue(channelFuture.isSuccess()); - _eventLoopGroup.execute(() -> pool.release(channelFuture.getNow())); - } - - // Wait until min connections are built. - long timeout = Time.currentTimeMillis() + 1000L; - do { - Time.sleep(100L); - LOG.info("created={}, closed={}", createAdder, closeAdder); - } while (pool.getConnectedChannels() != minConnections && timeout > Time.currentTimeMillis()); - - Assert.assertEquals(pool.getConnectedChannels(), minConnections); - Assert.assertEquals(createAdder.intValue(), minConnections); - Assert.assertEquals(closeAdder.intValue(), 0); - - LOG.info("closing pool {}", pool); - CompletableFuture.runAsync(pool::close, _eventLoopGroup.next()).join(); - - timeout = Time.currentTimeMillis() + 1000L; - do { - Time.sleep(100L); - LOG.info("created={}, closed={}", createAdder, closeAdder); - } while (pool.getConnectedChannels() != 0 && timeout > Time.currentTimeMillis()); - - Assert.assertEquals(pool.getConnectedChannels(), 0); - // All the connections are closed. - Assert.assertEquals(closeAdder.intValue(), minConnections); - } finally { - server.channel().close().sync(); - } - } - - private FixedChannelPoolImpl createNewFixedChannelPool( - boolean useQueueSizeForAcquiredChannelCount, - Bootstrap bootstrap, - int minConnections, - int maxConnections, - int maxPendingAcquires, - LongAdder createAdder, - LongAdder closeAdder) { - return new FixedChannelPoolImpl(bootstrap, new ChannelPoolHandler() { - @Override - public void channelReleased(Channel ch) throws Exception { - LOG.info("channelReleased {}", ch.id()); - } - - @Override - public void channelAcquired(Channel ch) throws Exception { - LOG.info("channelAcquired {}", ch.id()); - } - - @Override - public void channelCreated(Channel ch) throws Exception { - LOG.info("channelCreated {}", ch.id()); - ch.closeFuture().addListener(future -> closeAdder.increment()); - createAdder.increment(); - } - }, - ChannelHealthChecker.ACTIVE, - FixedChannelPool.AcquireTimeoutAction.FAIL, - 100, - minConnections, - maxConnections, - maxPendingAcquires, - true, - false, - () -> useQueueSizeForAcquiredChannelCount); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestFixedFastChannelPoolImpl.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestFixedFastChannelPoolImpl.java deleted file mode 100644 index 1abf3b5e875..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestFixedFastChannelPoolImpl.java +++ /dev/null @@ -1,313 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import com.linkedin.alpini.base.misc.Time; -import com.linkedin.alpini.netty4.handlers.Log4J2LoggingHandler; -import com.linkedin.venice.utils.TestUtils; -import io.netty.bootstrap.Bootstrap; -import io.netty.bootstrap.ServerBootstrap; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.local.LocalAddress; -import io.netty.channel.local.LocalChannel; -import io.netty.channel.local.LocalServerChannel; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.pool.ChannelHealthChecker; -import io.netty.channel.pool.ChannelPoolHandler; -import io.netty.channel.pool.FixedChannelPool; -import io.netty.handler.logging.LogLevel; -import io.netty.handler.logging.LoggingHandler; -import io.netty.util.concurrent.Future; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.LongAdder; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - - -/** - * Created by acurtis on 5/8/18. - */ -public class TestFixedFastChannelPoolImpl { - private static final Logger LOG = LogManager.getLogger(TestFixedFastChannelPoolImpl.class); - - private EventLoopGroup _eventLoopGroup; - - @BeforeClass(groups = "unit") - public void beforeClass() { - _eventLoopGroup = new NioEventLoopGroup(1); - } - - @AfterClass(groups = "unit") - public void afterClass() { - Optional.ofNullable(_eventLoopGroup).ifPresent(EventLoopGroup::shutdownGracefully); - } - - @DataProvider - public Object[][] useQueueSizeForAcquiredChannelCount() { - return new Object[][] { new Object[] { true }, new Object[] { false } }; - } - - @Test(groups = "unit", dataProvider = "useQueueSizeForAcquiredChannelCount") - public void testMinPoolSize(boolean useQueueSizeForAcquiredChannelCount) throws Exception { - - LocalAddress localAddress = new LocalAddress("testMinPoolSize"); - - LoggingHandler listenLog = new Log4J2LoggingHandler("listen", LogLevel.DEBUG); - LoggingHandler serverLog = new Log4J2LoggingHandler("server", LogLevel.DEBUG); - - ServerBootstrap serverBootstrap = new ServerBootstrap().group(_eventLoopGroup) - .channel(LocalServerChannel.class) - .handler(listenLog) - .childHandler(new ChannelInitializer() { - @Override - protected void initChannel(Channel ch) throws Exception { - ch.pipeline().addLast(serverLog); - } - }); - - Bootstrap bootstrap = - new Bootstrap().group(_eventLoopGroup).channel(LocalChannel.class).remoteAddress(localAddress); - - ChannelFuture server = serverBootstrap.bind(localAddress).sync(); - try { - - int minConnections = 10; - int maxConnections = 100; - int maxPendingAcquires = 100; - - LongAdder createAdder = new LongAdder(); - LongAdder closeAdder = new LongAdder(); - - FixedFastChannelPoolImpl pool = createNewFixedChannelPool( - useQueueSizeForAcquiredChannelCount, - bootstrap, - minConnections, - maxConnections, - maxPendingAcquires, - createAdder, - closeAdder); - - TestUtils.waitForNonDeterministicAssertion(1, TimeUnit.SECONDS, () -> { - Assert.assertEquals(pool.getConnectedChannels(), 0); - }); - - { - Future channelFuture = CompletableFuture.supplyAsync(pool::acquire, _eventLoopGroup.next()).join(); - channelFuture.sync(); - Assert.assertTrue(channelFuture.isSuccess()); - _eventLoopGroup.execute(() -> pool.release(channelFuture.getNow())); - } - - { - Future channelFuture = CompletableFuture.supplyAsync(pool::acquire, _eventLoopGroup.next()).join(); - channelFuture.sync(); - Assert.assertTrue(channelFuture.isSuccess()); - _eventLoopGroup.execute(() -> pool.release(channelFuture.getNow())); - } - - TestUtils.waitForNonDeterministicAssertion(1, TimeUnit.SECONDS, () -> { - LOG.info("created={}, closed={}", createAdder, closeAdder); - Assert.assertEquals(pool.getConnectedChannels(), minConnections); - }); - - Assert.assertEquals(pool.getConnectedChannels(), minConnections); - Assert.assertEquals(createAdder.intValue(), minConnections); - Assert.assertEquals(closeAdder.intValue(), 0); - - { - Future channelFuture = CompletableFuture.supplyAsync(pool::acquire, _eventLoopGroup.next()).join(); - channelFuture.sync(); - Assert.assertTrue(channelFuture.isSuccess()); - - Assert.assertEquals(pool.getConnectedChannels(), minConnections); - Assert.assertEquals(createAdder.intValue(), minConnections); - Assert.assertEquals(closeAdder.intValue(), 0); - - _eventLoopGroup.execute(() -> pool.release(channelFuture.getNow())); - } - - // Using a CompletableFuture as that will allow us to propagate out any exceptions. - CompletableFuture latch = new CompletableFuture<>(); - - // To test ESPENG-22776 - pool.acquire().addListener((Future f) -> { - try { - if (f.isSuccess()) { - TestUtils.waitForNonDeterministicAssertion(1, TimeUnit.SECONDS, () -> { - int beforeCloseCount = pool.acquiredChannelCount(); - LOG.info("Before close :{}", beforeCloseCount); - Assert.assertEquals(beforeCloseCount, 1); - }); - - // Close the channel - f.getNow().close().addListener(ignored -> f.getNow().eventLoop().execute(() -> { - try { - TestUtils.waitForNonDeterministicAssertion(1, TimeUnit.SECONDS, () -> { - int afterCloseCount = pool.acquiredChannelCount(); - LOG.info("After close :{}", afterCloseCount); - Assert.assertEquals(afterCloseCount, 0); - }); - - // Release the channel - pool.release(f.getNow()).addListener(bar -> { - try { - TestUtils.waitForNonDeterministicAssertion(1, TimeUnit.SECONDS, () -> { - int afterReleaseCount = pool.acquiredChannelCount(); - LOG.info("After release :{}", afterReleaseCount); - Assert.assertEquals(afterReleaseCount, 0); - }); - latch.complete(null); - } catch (Throwable ex) { - latch.completeExceptionally(ex); - } - }); - } catch (Throwable ex) { - latch.completeExceptionally(ex); - } - })); - } else { - latch.completeExceptionally(f.cause()); - } - } catch (Throwable ex) { - latch.completeExceptionally(ex); - } - }); - - latch.join(); - LOG.info("closing pool {}", pool); - CompletableFuture.runAsync(pool::close, _eventLoopGroup.next()).join(); - - TestUtils.waitForNonDeterministicAssertion(1, TimeUnit.SECONDS, () -> { - LOG.info("created={}, closed={}", createAdder, closeAdder); - Assert.assertEquals(pool.getConnectedChannels(), 0); - }); - - Assert.assertEquals(pool.getConnectedChannels(), 0); - Assert.assertEquals(closeAdder.intValue(), minConnections + 1); - } finally { - server.channel().close().sync(); - } - } - - @Test(groups = "unit", dataProvider = "useQueueSizeForAcquiredChannelCount") - public void testPoolClose(boolean useQueueSizeForAcquiredChannelCount) throws InterruptedException { - LocalAddress localAddress = new LocalAddress("testPoolClose"); - - LoggingHandler listenLog = new Log4J2LoggingHandler("listen", LogLevel.DEBUG); - LoggingHandler serverLog = new Log4J2LoggingHandler("server", LogLevel.DEBUG); - - ServerBootstrap serverBootstrap = new ServerBootstrap().group(_eventLoopGroup) - .channel(LocalServerChannel.class) - .handler(listenLog) - .childHandler(new ChannelInitializer() { - @Override - protected void initChannel(Channel ch) throws Exception { - ch.pipeline().addLast(serverLog); - } - }); - - Bootstrap bootstrap = - new Bootstrap().group(_eventLoopGroup).channel(LocalChannel.class).remoteAddress(localAddress); - - ChannelFuture server = serverBootstrap.bind(localAddress).sync(); - try { - - int minConnections = 10; - int maxConnections = 100; - int maxPendingAcquires = 100; - - LongAdder createAdder = new LongAdder(); - LongAdder closeAdder = new LongAdder(); - - FixedFastChannelPoolImpl pool = createNewFixedChannelPool( - useQueueSizeForAcquiredChannelCount, - bootstrap, - minConnections, - maxConnections, - maxPendingAcquires, - createAdder, - closeAdder); - - Time.sleep(100L); - - Assert.assertEquals(pool.getConnectedChannels(), 0); - - // Acquire a connection, which will kick off the connection build process - { - Future channelFuture = CompletableFuture.supplyAsync(pool::acquire, _eventLoopGroup.next()).join(); - channelFuture.sync(); - Assert.assertTrue(channelFuture.isSuccess()); - _eventLoopGroup.execute(() -> pool.release(channelFuture.getNow())); - } - - // Wait until min connections are built. - TestUtils.waitForNonDeterministicAssertion(1, TimeUnit.SECONDS, () -> { - LOG.info("created={}, closed={}", createAdder, closeAdder); - Assert.assertEquals(pool.getConnectedChannels(), minConnections); - }); - - Assert.assertEquals(pool.getConnectedChannels(), minConnections); - Assert.assertEquals(createAdder.intValue(), minConnections); - Assert.assertEquals(closeAdder.intValue(), 0); - - LOG.info("closing pool {}", pool); - CompletableFuture.runAsync(pool::close, _eventLoopGroup.next()).join(); - - TestUtils.waitForNonDeterministicAssertion(1, TimeUnit.SECONDS, () -> { - LOG.info("created={}, closed={}", createAdder, closeAdder); - Assert.assertEquals(pool.getConnectedChannels(), 0); - }); - - Assert.assertEquals(pool.getConnectedChannels(), 0); - // All the connections are closed. - Assert.assertEquals(closeAdder.intValue(), minConnections); - } finally { - server.channel().close().sync(); - } - } - - private FixedFastChannelPoolImpl createNewFixedChannelPool( - boolean useQueueSizeForAcquiredChannelCount, - Bootstrap bootstrap, - int minConnections, - int maxConnections, - int maxPendingAcquires, - LongAdder createAdder, - LongAdder closeAdder) { - return new FixedFastChannelPoolImpl(bootstrap, new ChannelPoolHandler() { - @Override - public void channelReleased(Channel ch) throws Exception { - LOG.info("channelReleased {}", ch.id()); - } - - @Override - public void channelAcquired(Channel ch) throws Exception { - LOG.info("channelAcquired {}", ch.id()); - } - - @Override - public void channelCreated(Channel ch) throws Exception { - LOG.info("channelCreated {}", ch.id()); - ch.closeFuture().addListener(future -> closeAdder.increment()); - createAdder.increment(); - } - }, - ChannelHealthChecker.ACTIVE, - FixedChannelPool.AcquireTimeoutAction.FAIL, - 100, - minConnections, - maxConnections, - maxPendingAcquires, - true, - 1, - () -> useQueueSizeForAcquiredChannelCount); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestHttp2AwareChannelPool.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestHttp2AwareChannelPool.java deleted file mode 100644 index 433518d2854..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestHttp2AwareChannelPool.java +++ /dev/null @@ -1,726 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import static com.linkedin.alpini.netty4.pool.Http2AwareChannelPool.HTTP2_CONNECTION; -import static com.linkedin.alpini.netty4.pool.Http2AwareChannelPool.HTTP2_STREAM_CHANNEL_AVAILABLE_FOR_REUSE; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandler; -import io.netty.channel.embedded.EmbeddedChannel; -import io.netty.channel.pool.ChannelPoolHandler; -import io.netty.handler.codec.http.DefaultHttpRequest; -import io.netty.handler.codec.http.HttpMethod; -import io.netty.handler.codec.http.HttpVersion; -import io.netty.handler.codec.http2.EspressoHttp2MultiplexHandler; -import io.netty.handler.codec.http2.Http2Error; -import io.netty.handler.codec.http2.Http2Exception; -import io.netty.handler.codec.http2.Http2FrameCodec; -import io.netty.handler.codec.http2.Http2FrameCodecBuilder; -import io.netty.handler.codec.http2.Http2MultiplexHandler; -import io.netty.handler.codec.http2.Http2Stream; -import io.netty.handler.codec.http2.Http2StreamChannel; -import io.netty.util.concurrent.CompleteFuture; -import io.netty.util.concurrent.EventExecutor; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.GenericFutureListener; -import io.netty.util.concurrent.ImmediateEventExecutor; -import io.netty.util.concurrent.Promise; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Consumer; -import org.mockito.Mockito; -import org.testng.Assert; -import org.testng.annotations.Test; - - -public class TestHttp2AwareChannelPool { - private final AtomicInteger _streamId = new AtomicInteger(1); - - private final EventExecutor _executor = ImmediateEventExecutor.INSTANCE; - - private static final Consumer CONSUME_NOTHING = c -> {}; - - private static class BlahException extends RuntimeException { - } - - private Future makeFuture(boolean successfulAcquire, boolean isHttp2) { - return makeFuture(successfulAcquire, isHttp2, false); - } - - private Future makeFuture(boolean successfulAcquire, boolean isHttp2, boolean reuse) { - - return new CompleteFuture(_executor) { - EmbeddedChannel _embeddedChannel; - - @Override - public boolean isSuccess() { - return successfulAcquire; - } - - @Override - public Throwable cause() { - return successfulAcquire ? null : new BlahException(); - } - - @Override - public Channel getNow() { - if (_embeddedChannel != null) { - return _embeddedChannel; - } - EmbeddedChannel channel = new EmbeddedChannel(); - ChannelHandler channelHandler = Mockito.mock(ChannelHandler.class); - if (isHttp2) { - channel.pipeline().addLast(Http2FrameCodecBuilder.forClient().build()); - ChannelHandler multiplexHandler = reuse - ? new EspressoHttp2MultiplexHandler(channelHandler, true, false) - : new Http2MultiplexHandler(channelHandler); - channel.pipeline().addLast(multiplexHandler); - _embeddedChannel = channel; - } - return channel; - } - }; - } - - private ManagedChannelPool prepareAClosedParentPool() { - ManagedChannelPool parentPool = mock(ManagedChannelPool.class); - ChannelPoolHandler channelPoolHandler = mock(ChannelPoolHandler.class); - when(parentPool.handler()).thenReturn(channelPoolHandler); - - Future successfulAcquire = makeFuture(true, true); - Future failedFuture = makeFuture(false, true); - when(parentPool.acquire()).thenReturn(successfulAcquire).thenReturn(failedFuture); - when(parentPool.isClosed()).thenReturn(true); - when(parentPool.name()).thenReturn("closedPool"); - - return parentPool; - } - - private ManagedChannelPool prepareParentPool(boolean successfulAcquire, boolean isHttp2) { - return prepareParentPool(successfulAcquire, isHttp2, false); - } - - private ManagedChannelPool prepareParentPool(boolean successfulAcquire, boolean isHttp2, boolean reuse) { - Future future = makeFuture(successfulAcquire, isHttp2, reuse); - ManagedChannelPool parentPool = parentPool(); - when(parentPool.acquire()).thenReturn(future); - when(parentPool.name()).thenReturn("pool"); - return parentPool; - } - - private ManagedChannelPool parentPool() { - ManagedChannelPool parentPool = mock(ManagedChannelPool.class); - ChannelPoolHandler channelPoolHandler = mock(ChannelPoolHandler.class); - when(parentPool.handler()).thenReturn(channelPoolHandler); - when(parentPool.name()).thenReturn("pool"); - return parentPool; - } - - /** - * Return a mock parent pool that will return successful acquire future until the latch is 0. - * @param latch Latch to use - * @return Mock parent pool - */ - private ManagedChannelPool prepareParentPoolWithCountDown(CountDownLatch latch) { - Future future = makeFuture(true, true, true); - Future failedFuture = makeFuture(false, true, true); - ManagedChannelPool parentPool = parentPool(); - when(parentPool.acquire()).thenAnswer(invocation -> latch.getCount() == 0 ? failedFuture : future); - return parentPool; - } - - private Http2Stream createStream(Channel ch) throws Exception { - Channel channel = ch instanceof Http2StreamChannel ? ch.parent() : ch; - Assert.assertTrue(channel.hasAttr(HTTP2_CONNECTION)); - return channel.attr(HTTP2_CONNECTION).get().local().createStream(_streamId.getAndAdd(2), false); - } - - /** - * Creates a wrapped {@link Http2AwareChannelPool} that will create a new H2 stream when acquire succeeds, - * and close the corresponding H2 stream when release succeeds. This is for simulating the active streams in the - * underlying HTTP/2 connection. - * - * @param parentPool Parent pool - * @return Wrapped H2 channel pool - */ - private Http2AwareChannelPool createHttp2AwareChannelPool(ManagedChannelPool parentPool) { - return createHttp2AwareChannelPool(parentPool, new HashMap<>(), f -> {}); - } - - private Http2AwareChannelPool createHttp2AwareChannelPool( - ManagedChannelPool parentPool, - Map streams, - GenericFutureListener> acquire0Listener) { - return new Http2AwareChannelPool(parentPool, CONSUME_NOTHING, CONSUME_NOTHING) { - @Override - public Future acquire() { - Future future = super.acquire(); - future.addListener((Future f) -> { - if (f.isSuccess()) { - streams.put(f.getNow(), createStream(f.getNow())); - } - }); - return future; - } - - @Override - protected Promise acquire0(Promise promise) { - return super.acquire0(promise).addListener(acquire0Listener); - } - - @Override - public Future release(Channel channel) { - Future future = super.release(channel); - future.addListener(f -> { - if (f.isSuccess()) { - streams.remove(channel).close(); - } - }); - return future; - } - }; - } - - private static void assertActiveStreams(ManagedChannelPool pool, int expectedCount) { - Assert.assertEquals(pool.getTotalActiveStreams(), expectedCount, "Netty active stream count should be correct"); - Assert.assertEquals( - pool.getTotalActiveStreamChannels(), - expectedCount, - "Active stream channel counter should be correct"); - } - - @Test(groups = "unit") - public void testAcquireWithPromiseSucceedForHttp2AndReturnAnHttp2StreamChannel() throws Exception { - ManagedChannelPool parentPool = prepareParentPool(true, true); - Http2AwareChannelPool pool = createHttp2AwareChannelPool(parentPool); - pool.setMoreThanOneHttp2Connection(false); - Future future = pool.acquire(); - Channel channel = future.sync().getNow(); - Assert.assertNotNull(channel); - Assert.assertTrue(channel instanceof Http2StreamChannel, channel.getClass().toString()); - assertActiveStreams(pool, 1); - verify(parentPool, times(1)).release(any(Channel.class)); - verify(parentPool, times(1)).acquire(); - verify(parentPool, times(1)).handler(); - verify(parentPool, atLeastOnce()).name(); - Assert.assertTrue(future.isSuccess()); - verifyNoMoreInteractions(parentPool); - pool.release(channel); - assertActiveStreams(pool, 0); - Assert.assertEquals(pool.getTotalStreamCreations(), 1, "Should increment stream creation count"); - } - - @Test(groups = "unit") - public void testTotalActiveStreams() throws Exception { - ManagedChannelPool parentPool = prepareParentPool(true, true); - Http2AwareChannelPool pool = createHttp2AwareChannelPool(parentPool); - pool.setMoreThanOneHttp2Connection(false); - Future future = pool.acquire(); - Channel channel1 = future.sync().getNow(); - assertActiveStreams(pool, 1); - Assert.assertNotNull(channel1); - Assert.assertTrue(channel1 instanceof Http2StreamChannel); - verify(parentPool, times(1)).release(any(Channel.class)); - verify(parentPool, times(1)).acquire(); - verify(parentPool, times(1)).handler(); - verify(parentPool, atLeastOnce()).name(); - Assert.assertTrue(future.isSuccess()); - verifyNoMoreInteractions(parentPool); - - Channel channel2 = pool.acquire().sync().getNow(); - Assert.assertNotNull(channel2); - Assert.assertTrue(channel2 instanceof Http2StreamChannel); - assertActiveStreams(pool, 2); - Assert.assertEquals(pool.getTotalStreamCreations(), 2, "Should increment stream creation count"); - - pool.release(channel1); - assertActiveStreams(pool, 1); - pool.release(channel2); - assertActiveStreams(pool, 0); - } - - @Test(groups = "unit") - public void testAcquireWithPromiseFailedWithClosedParentPool() throws InterruptedException { - // The the parentPool is mocked in such a way that it would return a succeeded future first then failed as second. - ManagedChannelPool parentPool = prepareAClosedParentPool(); - Http2AwareChannelPool pool = new Http2AwareChannelPool(parentPool, CONSUME_NOTHING, CONSUME_NOTHING); - pool.setMoreThanOneHttp2Connection(true); - Future future = pool.acquire(); - Channel channel = future.sync().getNow(); - Assert.assertNotNull(channel); - Assert.assertTrue(channel instanceof Http2StreamChannel); - verify(parentPool, times(1)).release(any(Channel.class)); - verify(parentPool, times(1)).release(any(Channel.class)); - verify(parentPool, times(1)).isClosed(); - Assert.assertEquals(pool.getTotalStreamCreations(), 1, "Should increment stream creation count"); - Assert.assertTrue(future.isSuccess()); - } - - @Test(groups = "unit") - public void testAcquireWithPromiseSucceed2ForHttp2AndReturnAnHttp2StreamChannel() throws Exception { - ManagedChannelPool parentPool = prepareParentPool(true, true); - Http2AwareChannelPool pool = createHttp2AwareChannelPool(parentPool); - pool.setMoreThanOneHttp2Connection(true); - Future future = pool.acquire(); - Channel channel = future.sync().getNow(); - Assert.assertNotNull(channel); - Assert.assertTrue(channel instanceof Http2StreamChannel); - assertActiveStreams(pool, 1); - verify(parentPool, times(2)).release(any(Channel.class)); - verify(parentPool, times(2)).acquire(); - verify(parentPool, times(1)).handler(); - verify(parentPool, times(1)).isClosing(); - verify(parentPool, atLeastOnce()).name(); - Assert.assertEquals(pool.getTotalStreamCreations(), 1, "Should increment stream creation count"); - Assert.assertTrue(future.isSuccess()); - verifyNoMoreInteractions(parentPool); - } - - @Test(groups = "unit") - public void testAcquireWithPromiseSucceedForHttp1AndReturnAChannel() throws InterruptedException { - ManagedChannelPool parentPool = prepareParentPool(true, false); - doAnswer(invocation -> { - Promise promise = invocation.getArgument(1); - return promise.setSuccess(null); - }).when(parentPool).release(any(), any()); - Http2AwareChannelPool pool = new Http2AwareChannelPool(parentPool, CONSUME_NOTHING, CONSUME_NOTHING); - Future future = pool.acquire(); - Channel channel = future.sync().getNow(); - Assert.assertNotNull(channel); - Assert.assertFalse(channel instanceof Http2StreamChannel); - Assert.assertTrue(channel instanceof EmbeddedChannel); - Assert.assertEquals(pool.getTotalStreamCreations(), 0, "Should not increment creation count since not H2"); - verify(parentPool, times(0)).release(any(Channel.class)); - Assert.assertTrue(future.isSuccess()); - pool.release(channel).sync(); - } - - @Test(groups = "unit") - public void testAcquireWithPromiseSucceedForHttp1AndReturnAChannelTwice() throws InterruptedException { - ManagedChannelPool parentPool = prepareParentPool(true, false); - Http2AwareChannelPool pool = new Http2AwareChannelPool(parentPool, CONSUME_NOTHING, CONSUME_NOTHING); - Future future = pool.acquire(); - Channel channel = future.sync().getNow(); - Assert.assertNotNull(channel); - Assert.assertFalse(channel instanceof Http2StreamChannel); - Assert.assertTrue(channel instanceof EmbeddedChannel); - verify(parentPool, times(0)).release(any(Channel.class)); - Assert.assertTrue(future.isSuccess()); - - Future future2 = pool.acquire(); - Channel channel2 = future2.sync().getNow(); - Assert.assertNotNull(channel2); - Assert.assertFalse(channel2 instanceof Http2StreamChannel); - Assert.assertTrue(channel2 instanceof EmbeddedChannel); - Assert.assertEquals(pool.getTotalStreamCreations(), 0, "Should not increment creation count since not H2"); - verify(parentPool, times(0)).release(any(Channel.class)); - Assert.assertTrue(future2.isSuccess()); - Assert.assertNotSame(channel, channel2, "In HTTP 1.1 we should expect two different parent channels"); - } - - @Test(groups = "unit") - public void testAcquireWithPromiseFailedForHttp2() throws InterruptedException { - ManagedChannelPool parentPool = prepareParentPool(false, true); - Http2AwareChannelPool pool = new Http2AwareChannelPool(parentPool, CONSUME_NOTHING, CONSUME_NOTHING); - pool.setRetryOnMaxStreamsLimit(true); - Future future = null; - Channel channel = null; - try { - future = pool.acquire(); - channel = future.sync().getNow(); - Assert.fail("Should throw exception"); - } catch (BlahException bl) { - // expected. - } - Assert.assertNull(channel); - assertActiveStreams(pool, 0); - Assert.assertEquals(pool.getTotalStreamCreations(), 0, "Should not increment creation count since creation failed"); - Assert.assertEquals(pool.getTotalAcquireRetries(), 0, "Should not retry on BlahException"); - verify(parentPool, times(1)).acquire(); - verify(parentPool, times(0)).release(any(Channel.class)); - Assert.assertFalse(future.isSuccess()); - Assert.assertTrue(future.cause() instanceof BlahException); - } - - @Test(groups = "unit") - public void testAcquireWithPromiseFailedForHttp1() throws InterruptedException { - ManagedChannelPool parentPool = prepareParentPool(false, false); - Http2AwareChannelPool pool = new Http2AwareChannelPool(parentPool, CONSUME_NOTHING, CONSUME_NOTHING); - pool.setRetryOnMaxStreamsLimit(true); - Future future = null; - Channel channel = null; - try { - future = pool.acquire(); - channel = future.sync().getNow(); - Assert.fail("Should throw exception"); - } catch (BlahException bl) { - // expected. - } - Assert.assertNull(channel); - Assert.assertEquals(pool.getTotalAcquireRetries(), 0, "Should not retry on BlahException"); - verify(parentPool, times(1)).acquire(); - verify(parentPool, times(0)).release(any(Channel.class)); - Assert.assertFalse(future.isSuccess()); - Assert.assertTrue(future.cause() instanceof BlahException); - Assert.assertEquals(pool.getTotalStreamCreations(), 0, "Should not increment creation count since not H2"); - } - - @Test(groups = "unit") - public void testHttp2ChannelReuse() throws Exception { - ManagedChannelPool parentPool = prepareParentPool(true, true, true); - Http2AwareChannelPool pool = createHttp2AwareChannelPool(parentPool); - pool.setChannelReuse(true); - pool.setMoreThanOneHttp2Connection(false); - pool.setUseCustomH2Codec(true); - Assert.assertTrue(pool.useCustomH2Codec()); - - // Acquire one stream channel - Channel channel = firstAcquire(pool, parentPool); - - pool.release(channel); - assertActiveStreams(pool, 0); - Assert.assertEquals(pool.getChannelReusePoolSize(), 1, "Should recycle channels to the deque"); - - // Acquire another channel, this should be the same channel because of the reuse - Future future = pool.acquire(); - Channel anotherChannel = future.sync().getNow(); - assertActiveStreams(pool, 1); - assertOccupiedStreamChannel(anotherChannel); - Assert.assertSame(channel, anotherChannel, "Both channels should be the same due to the reuse"); - anotherChannel.attr(HTTP2_STREAM_CHANNEL_AVAILABLE_FOR_REUSE).set(Boolean.TRUE); - verify(parentPool, times(2)).release(any(Channel.class)); - verify(parentPool, times(2)).acquire(); - verify(parentPool, times(3)).handler(); - Assert.assertTrue(future.isSuccess()); - verifyNoMoreInteractions(parentPool); - Assert.assertEquals(pool.getTotalStreamChannelsReused(), 1, "Should have reused one channel"); - Assert.assertEquals(pool.getTotalStreamCreations(), 1, "Should not increment missed count since reusing"); - - pool.release(anotherChannel); - assertActiveStreams(pool, 0); - Assert.assertEquals(pool.getChannelReusePoolSize(), 1, "Should recycle channels to the deque"); - Assert.assertEquals(pool.getTotalStreamChannelsReused(), 1, "Should have 1 reuse after release"); - Assert.assertEquals(pool.getCurrentStreamChannelsReused(), 0, "Should have 0 current reuses after release"); - - anotherChannel.parent().close().getNow(); - Assert.assertFalse(channel.isOpen()); - Assert.assertFalse(anotherChannel.isOpen()); - Assert.assertEquals(pool.getChannelReusePoolSize(), 0, "Should clear recycle queues after parent channel closed"); - } - - @Test(groups = "unit") - public void testHttp2ChannelReuseSequence() throws Exception { - ManagedChannelPool parentPool = prepareParentPool(true, true, true); - Http2AwareChannelPool pool = createHttp2AwareChannelPool(parentPool); - pool.setChannelReuse(true); - pool.setMoreThanOneHttp2Connection(false); - pool.setUseCustomH2Codec(true); - Assert.assertTrue(pool.useCustomH2Codec()); - - // Acquire one stream channel - Channel channel = firstAcquire(pool, parentPool); - - // Acquire another channel, this should be the a different channel since the first one is not released - Future anotherFuture = pool.acquire(); - Channel anotherChannel = anotherFuture.sync().getNow(); - assertActiveStreams(pool, 2); - Assert.assertNotNull(anotherChannel); - Assert.assertTrue(anotherChannel instanceof Http2StreamChannel); - anotherChannel.attr(HTTP2_STREAM_CHANNEL_AVAILABLE_FOR_REUSE).set(Boolean.TRUE); - verify(parentPool, times(2)).release(any(Channel.class)); - verify(parentPool, times(2)).acquire(); - verify(parentPool, times(2)).handler(); - Assert.assertTrue(anotherFuture.isSuccess()); - verifyNoMoreInteractions(parentPool); - // Release the second channel, it should be reused later - pool.release(anotherChannel); - assertActiveStreams(pool, 1); - Assert.assertEquals(pool.getChannelReusePoolSize(), 1, "Should recycle channel to the deque"); - Assert.assertEquals(pool.getTotalStreamChannelsReused(), 0, "Should have 0 reuses"); - Assert.assertEquals(pool.getTotalStreamCreations(), 2, "Should increment creation count"); - - // Acquire the third channel, should be the same as the second channel due to reuse - Future thirdFuture = pool.acquire(); - Channel thirdChannel = thirdFuture.sync().getNow(); - assertActiveStreams(pool, 2); - Assert.assertNotNull(thirdChannel); - Assert.assertTrue(thirdChannel instanceof Http2StreamChannel); - Assert.assertSame(anotherChannel, thirdChannel, "Both channels should be the same due to the reuse"); - thirdChannel.attr(HTTP2_STREAM_CHANNEL_AVAILABLE_FOR_REUSE).set(Boolean.TRUE); - verify(parentPool, times(3)).release(any(Channel.class)); - verify(parentPool, times(3)).acquire(); - verify(parentPool, times(4)).handler(); - Assert.assertTrue(thirdFuture.isSuccess()); - verifyNoMoreInteractions(parentPool); - Assert.assertEquals(pool.getTotalStreamChannelsReused(), 1, "Should have reused one channel"); - Assert.assertEquals(pool.getTotalStreamCreations(), 2, "Should not increment count since reusing"); - - pool.release(channel); - pool.release(thirdChannel); - assertActiveStreams(pool, 0); - Assert.assertEquals(pool.getChannelReusePoolSize(), 2, "Should recycle channels to the deque"); - Assert.assertEquals(pool.getTotalStreamChannelsReused(), 1, "Should have 1 reuse after release"); - Assert.assertEquals(pool.getCurrentStreamChannelsReused(), 0, "Should have 0 current reuses after release"); - Assert.assertTrue(channel.isOpen()); - Assert.assertTrue(thirdChannel.isOpen()); - } - - @Test(groups = "unit") - public void testHttp2ChannelReuseLimit() throws Exception { - ManagedChannelPool parentPool = prepareParentPool(true, true, true); - Http2AwareChannelPool pool = createHttp2AwareChannelPool(parentPool); - pool.setChannelReuse(true); - pool.setMoreThanOneHttp2Connection(false); - pool.setUseCustomH2Codec(true); - pool.setMaxReuseStreamChannelsLimit(1); - Assert.assertTrue(pool.useCustomH2Codec()); - Assert.assertEquals(pool.getMaxReuseStreamChannelsLimit(), 1); - - // Acquire one stream channel - Channel channel = firstAcquire(pool, parentPool); - - // Acquire another channel, this should be a different channel since the first one is not released - Future anotherFuture = pool.acquire(); - Channel anotherChannel = anotherFuture.sync().getNow(); - assertActiveStreams(pool, 2); - Assert.assertNotNull(anotherChannel); - Assert.assertTrue(anotherChannel instanceof Http2StreamChannel); - anotherChannel.attr(HTTP2_STREAM_CHANNEL_AVAILABLE_FOR_REUSE).set(Boolean.TRUE); - verify(parentPool, times(2)).release(any(Channel.class)); - verify(parentPool, times(2)).acquire(); - verify(parentPool, times(2)).handler(); - Assert.assertTrue(anotherFuture.isSuccess()); - verifyNoMoreInteractions(parentPool); - // Release the second channel, it should be reused later - pool.release(anotherChannel); - assertActiveStreams(pool, 1); - Assert.assertEquals(pool.getChannelReusePoolSize(), 1, "Should recycle channel to the deque"); - Assert.assertEquals(pool.getTotalStreamCreations(), 2, "Should increment stream creation count"); - Assert.assertTrue(anotherChannel.isOpen(), "Stream channel added back to queue, should not close"); - - pool.release(channel); - assertActiveStreams(pool, 0); - Assert.assertEquals( - pool.getChannelReusePoolSize(), - 1, - "Should not recycle channel to the deque since we hit the size limit"); - Assert.assertEquals(pool.getTotalStreamChannelsReused(), 0); - Assert.assertFalse(channel.isOpen(), "Should close the channel since recycle queue full"); - } - - @Test(groups = "unit") - public void testHttp2ActiveStreamLimit() throws Exception { - ManagedChannelPool parentPool = prepareParentPool(true, true, true); - Http2AwareChannelPool pool = createHttp2AwareChannelPool(parentPool); - pool.setChannelReuse(true); - pool.setMoreThanOneHttp2Connection(false); - pool.setUseCustomH2Codec(true); - pool.setMaxConcurrentStreams(1); - Assert.assertTrue(pool.useCustomH2Codec()); - - // Acquire one stream channel - Channel channel = firstAcquire(pool, parentPool); - - Future anotherFuture = pool.acquire(); - Assert.assertFalse(anotherFuture.isSuccess()); - Assert - .assertTrue(anotherFuture.cause() instanceof Http2Exception, "Acquire should fail due to active stream limit"); - Assert.assertEquals(((Http2Exception) anotherFuture.cause()).error(), Http2Error.REFUSED_STREAM); - Assert.assertTrue( - anotherFuture.cause().getMessage().contains("Reached maxConcurrentStreamsLimit=1, totalActiveStream=1")); - Assert.assertEquals(pool.getActiveStreamsLimitReachedCount(), 1); - - pool.release(channel); - assertActiveStreams(pool, 0); - Assert.assertEquals(pool.getChannelReusePoolSize(), 1, "Should recycle channels to the deque"); - - // After the channel is released, acquire should work again - Future future = pool.acquire(); - Channel anotherChannel = future.sync().getNow(); - assertActiveStreams(pool, 1); - assertOccupiedStreamChannel(anotherChannel); - Assert.assertSame(channel, anotherChannel, "Both channels should be the same due to the reuse"); - anotherChannel.attr(HTTP2_STREAM_CHANNEL_AVAILABLE_FOR_REUSE).set(Boolean.TRUE); - verify(parentPool, times(3)).release(any(Channel.class)); - verify(parentPool, times(3)).acquire(); - verify(parentPool, times(3)).handler(); - Assert.assertTrue(future.isSuccess()); - verifyNoMoreInteractions(parentPool); - Assert.assertEquals(pool.getTotalStreamChannelsReused(), 1, "Should have reused one channel"); - Assert.assertEquals(pool.getTotalStreamCreations(), 1); - - pool.release(anotherChannel); - assertActiveStreams(pool, 0); - Assert.assertEquals(pool.getChannelReusePoolSize(), 1, "Should recycle channels to the deque"); - Assert.assertEquals(pool.getTotalStreamChannelsReused(), 1, "Should have 1 reuse after release"); - Assert.assertEquals(pool.getCurrentStreamChannelsReused(), 0, "Should have 0 current reuses after release"); - - pool.close(); - } - - @Test(groups = "unit") - public void testHttp2ActiveStreamLimitWithRetry() throws Exception { - ManagedChannelPool parentPool = prepareParentPool(true, true, true); - Http2AwareChannelPool pool = createHttp2AwareChannelPool(parentPool); - pool.setChannelReuse(true); - pool.setMoreThanOneHttp2Connection(false); - pool.setUseCustomH2Codec(true); - pool.setMaxConcurrentStreams(1); - pool.setRetryOnMaxStreamsLimit(true); - - // Acquire one stream channel - Channel channel = firstAcquire(pool, parentPool); - - Future anotherFuture = pool.acquire(); - Assert.assertFalse(anotherFuture.isSuccess()); - Assert - .assertTrue(anotherFuture.cause() instanceof Http2Exception, "Acquire should fail due to active stream limit"); - Assert.assertEquals(((Http2Exception) anotherFuture.cause()).error(), Http2Error.REFUSED_STREAM); - Assert.assertEquals(pool.getActiveStreamsLimitReachedCount(), 3); - Assert.assertEquals(pool.getTotalAcquireRetries(), 2); - - pool.release(channel); - assertActiveStreams(pool, 0); - Assert.assertEquals(pool.getChannelReusePoolSize(), 1, "Should recycle channels to the deque"); - - // After the channel is released, acquire should work again - Future future = pool.acquire(); - Channel anotherChannel = future.sync().getNow(); - assertActiveStreams(pool, 1); - assertOccupiedStreamChannel(anotherChannel); - Assert.assertSame(channel, anotherChannel, "Both channels should be the same due to the reuse"); - anotherChannel.attr(HTTP2_STREAM_CHANNEL_AVAILABLE_FOR_REUSE).set(Boolean.TRUE); - verify(parentPool, times(5)).release(any(Channel.class)); - verify(parentPool, times(5)).acquire(); - verify(parentPool, times(3)).handler(); - Assert.assertTrue(future.isSuccess()); - verifyNoMoreInteractions(parentPool); - Assert.assertEquals(pool.getTotalStreamChannelsReused(), 1, "Should have reused one channel"); - Assert.assertEquals(pool.getTotalStreamCreations(), 1); - - pool.release(anotherChannel); - assertActiveStreams(pool, 0); - Assert.assertEquals(pool.getChannelReusePoolSize(), 1, "Should recycle channels to the deque"); - Assert.assertEquals(pool.getTotalStreamChannelsReused(), 1, "Should have 1 reuse after release"); - Assert.assertEquals(pool.getCurrentStreamChannelsReused(), 0, "Should have 0 current reuses after release"); - - pool.close(); - - // Test when acquire retry succeeded on the second attempt - parentPool = prepareParentPool(true, true, true); - Map streams = new HashMap<>(); - pool = createHttp2AwareChannelPool(parentPool, streams, f -> { - if (!streams.isEmpty()) { - streams.values().iterator().next().close(); - } - }); - pool.setChannelReuse(true); - pool.setMoreThanOneHttp2Connection(false); - pool.setUseCustomH2Codec(true); - pool.setMaxConcurrentStreams(1); - pool.setRetryOnMaxStreamsLimit(true); - - channel = firstAcquire(pool, parentPool); - future = pool.acquire(); - anotherChannel = future.sync().getNow(); - Assert.assertEquals(pool.getTotalActiveStreams(), 1); - Assert.assertEquals(pool.getTotalActiveStreamChannels(), 2); - assertOccupiedStreamChannel(anotherChannel); - Assert.assertNotEquals(channel, anotherChannel, "Should create new channel since first one not released"); - anotherChannel.attr(HTTP2_STREAM_CHANNEL_AVAILABLE_FOR_REUSE).set(Boolean.TRUE); - verify(parentPool, times(3)).release(any(Channel.class)); - verify(parentPool, times(3)).acquire(); - verify(parentPool, times(2)).handler(); - Assert.assertTrue(future.isSuccess()); - verifyNoMoreInteractions(parentPool); - Assert.assertEquals(pool.getTotalStreamChannelsReused(), 0, "Should not have reused channels"); - Assert.assertEquals(pool.getTotalStreamCreations(), 2); - - pool.release(channel); - pool.release(anotherChannel); - assertActiveStreams(pool, 0); - Assert.assertEquals(pool.getChannelReusePoolSize(), 2, "Should recycle channels to the deque"); - pool.close(); - - // Test when acquire retry failed with other failures - CountDownLatch latch = new CountDownLatch(2); - parentPool = prepareParentPoolWithCountDown(latch); - pool = createHttp2AwareChannelPool(parentPool, new HashMap<>(), f -> latch.countDown()); - pool.setChannelReuse(true); - pool.setMoreThanOneHttp2Connection(false); - pool.setMaxConcurrentStreams(1); - pool.setRetryOnMaxStreamsLimit(true); - - channel = firstAcquire(pool, parentPool); - - anotherFuture = pool.acquire(); - Assert.assertFalse(anotherFuture.isSuccess()); - Assert.assertTrue(anotherFuture.cause() instanceof BlahException); - Assert.assertEquals(pool.getActiveStreamsLimitReachedCount(), 1); - Assert.assertEquals(pool.getTotalAcquireRetries(), 1); - - pool.release(channel); - assertActiveStreams(pool, 0); - Assert.assertEquals(pool.getChannelReusePoolSize(), 1, "Should recycle channels to the deque"); - pool.close(); - } - - private void assertOccupiedStreamChannel(Channel anotherChannel) { - Assert.assertNotNull(anotherChannel); - Assert.assertTrue(anotherChannel instanceof Http2StreamChannel); - Assert.assertNotEquals( - anotherChannel.attr(HTTP2_STREAM_CHANNEL_AVAILABLE_FOR_REUSE).get(), - Boolean.TRUE, - "Should set reuse to false since occupied"); - } - - private Channel firstAcquire(Http2AwareChannelPool pool, ManagedChannelPool parentPool) throws Exception { - Future future = pool.acquire(); - Channel channel = future.sync().getNow(); - channel.attr(HTTP2_STREAM_CHANNEL_AVAILABLE_FOR_REUSE).set(Boolean.TRUE); - assertActiveStreams(pool, 1); - Assert.assertNotNull(channel); - Assert.assertTrue(channel instanceof Http2StreamChannel); - verify(parentPool, times(1)).release(any(Channel.class)); - verify(parentPool, times(1)).acquire(); - verify(parentPool, times(1)).handler(); - verify(parentPool, atLeastOnce()).name(); - Assert.assertTrue(future.isSuccess()); - verifyNoMoreInteractions(parentPool); - Assert.assertEquals(pool.getTotalStreamCreations(), 1, "Should increment creation count"); - Assert.assertEquals(pool.getActiveStreamsLimitReachedCount(), 0); - Assert.assertEquals(pool.getTotalAcquireRetries(), 0); - return channel; - } - - @Test(groups = "unit") - public void testH2ActiveConnections() throws InterruptedException { - ManagedChannelPool parentPool = prepareParentPool(true, true, true); - Http2AwareChannelPool pool = new Http2AwareChannelPool(parentPool, CONSUME_NOTHING, CONSUME_NOTHING); - pool.setChannelReuse(true); - pool.setMoreThanOneHttp2Connection(false); - pool.setUseCustomH2Codec(true); - - // no active h2 tcp connections and no active streams - Assert.assertEquals(pool.getH2ActiveConnections(), -1); - - // The tcp connection is created but the stream it has is not activated - Future future = pool.acquire(); - Channel channel = future.sync().getNow(); - Assert.assertNotNull(channel.parent().pipeline().get(Http2FrameCodec.class).connection()); - Assert.assertEquals(pool.getH2ActiveConnections(), 0); - - // activate the stream, then the h2 tcp connection containing the active stream is active - channel.writeAndFlush(new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/foo/bar/0/21")); - Assert.assertEquals(pool.getH2ActiveConnections(), 1); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestHttp2PingHelper.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestHttp2PingHelper.java deleted file mode 100644 index 20ad28fba1a..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/com/linkedin/alpini/netty4/pool/TestHttp2PingHelper.java +++ /dev/null @@ -1,115 +0,0 @@ -package com.linkedin.alpini.netty4.pool; - -import com.linkedin.alpini.base.statistics.LongStats; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelPipeline; -import io.netty.handler.codec.http2.DefaultHttp2PingFrame; -import io.netty.handler.codec.http2.Http2ConnectionHandler; -import org.mockito.Mockito; -import org.testng.Assert; -import org.testng.annotations.Test; - - -/* -* This class is designed to test the Http2PingHelper -* -* @author Binbing Hou -* */ -public class TestHttp2PingHelper { - @Test - public void sendPingTest() { - Http2PingHelper http2PingHelper = new Http2PingHelper(); - - Channel channel = Mockito.mock(Channel.class); - ChannelFuture writeFuture = Mockito.mock(ChannelFuture.class); - Mockito.doReturn(writeFuture).when(channel).writeAndFlush(Mockito.any()); - - ChannelPipeline pipeline = Mockito.mock(ChannelPipeline.class); - Http2ConnectionHandler http2ConnectionHandler = Mockito.mock(Http2ConnectionHandler.class); - Mockito.doReturn(http2ConnectionHandler).when(pipeline).get(Mockito.eq(Http2ConnectionHandler.class)); - Mockito.doReturn(pipeline).when(channel).pipeline(); - - http2PingHelper.sendPing(channel); - Mockito.verify(channel).writeAndFlush(Mockito.any(DefaultHttp2PingFrame.class)); - - // reset - Mockito.reset(channel, writeFuture, pipeline, http2ConnectionHandler); - } - - @Test - public void pingCallTrackerTest_fewPingCalls() { - Http2PingHelper http2PingHelper = new Http2PingHelper(); - for (int i = 1; i < 5; i++) { - http2PingHelper.callStart(i, i); - http2PingHelper.callClose(i, i + 1); - } - Assert.assertEquals(http2PingHelper.getAvgResponseTimeOfLatestPings(), 0D); - LongStats pingLongStats = http2PingHelper.pingCallTracker().getCallStats().getCallTimeStats(); - Assert.assertNotNull(pingLongStats); - Assert.assertEquals(pingLongStats.getMinimum().longValue(), 1L); - Assert.assertEquals(pingLongStats.getMaximum().longValue(), 1L); - } - - @Test - public void pingCallTrackerTest_manyPingCalls() { - Http2PingHelper http2PingHelper = new Http2PingHelper(); - for (int i = 1; i < 101; i++) { - http2PingHelper.callStart(i, i); - http2PingHelper.callClose(i, 2 * i); - } - Assert.assertEquals(http2PingHelper.getAvgResponseTimeOfLatestPings(), 98D); - LongStats pingLongStats = http2PingHelper.pingCallTracker().getCallStats().getCallTimeStats(); - Assert.assertNotNull(pingLongStats); - Assert.assertEquals(pingLongStats.getMinimum().longValue(), 1L); - Assert.assertEquals(pingLongStats.getMaximum().longValue(), 100L); - } - - @Test - public void pingCallTrackerTest_errorPingCalls() { - Http2PingHelper http2PingHelper = new Http2PingHelper(); - for (int i = 1; i < 5; i++) { - http2PingHelper.callStart(i, i); - http2PingHelper.callClose(i, i + 1); - } - http2PingHelper.callStart(5, 6); - http2PingHelper.callCloseWithError(5, 102); - Assert.assertEquals(http2PingHelper.getAvgResponseTimeOfLatestPings(), 20D); - LongStats pingLongStats = http2PingHelper.pingCallTracker().getCallStats().getCallTimeStats(); - Assert.assertNotNull(pingLongStats); - Assert.assertEquals(pingLongStats.getMinimum().longValue(), 1L); - Assert.assertEquals(pingLongStats.getMaximum().longValue(), 96L); - } - - @Test - public void pingCallTrackerTest_wrongPingIds() { - Http2PingHelper http2PingHelper = new Http2PingHelper(); - for (int i = 1; i < 5; i++) { - http2PingHelper.callStart(i, i); - http2PingHelper.callClose(i, i + 1); - } - http2PingHelper.callStart(5, 6); - http2PingHelper.callCloseWithError(6, 102); - Assert.assertEquals(http2PingHelper.getAvgResponseTimeOfLatestPings(), 0D); - LongStats pingLongStats = http2PingHelper.pingCallTracker().getCallStats().getCallTimeStats(); - Assert.assertNotNull(pingLongStats); - Assert.assertEquals(pingLongStats.getMinimum().longValue(), 1L); - Assert.assertEquals(pingLongStats.getMaximum().longValue(), 1L); - } - - @Test - public void pingCallCompleteTest() { - Http2PingHelper http2PingHelper = new Http2PingHelper(); - Assert.assertTrue(http2PingHelper.isCallComplete(0)); - http2PingHelper.callStart(1, 1); - Assert.assertFalse(http2PingHelper.isCallComplete(1)); - http2PingHelper.callClose(1, 2); - Assert.assertTrue(http2PingHelper.isCallComplete(1)); - } - - @Test - public void createHttp2PingHandlerTest() { - Http2PingHelper http2PingHelper = new Http2PingHelper(); - Assert.assertNotNull(http2PingHelper.getHttp2PingSendHandler()); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/io/netty/bootstrap/TestInstrumentedBootstrap.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/io/netty/bootstrap/TestInstrumentedBootstrap.java deleted file mode 100644 index 80e6f21d723..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/io/netty/bootstrap/TestInstrumentedBootstrap.java +++ /dev/null @@ -1,116 +0,0 @@ -package io.netty.bootstrap; - -import com.linkedin.alpini.base.monitoring.CallCompletion; -import com.linkedin.alpini.base.monitoring.CallTracker; -import io.netty.channel.ChannelFuture; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.nio.NioSocketChannel; -import io.netty.handler.logging.LoggingHandler; -import java.net.ConnectException; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.Optional; -import org.mockito.Mockito; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - - -/** - * Created by acurtis on 4/23/18. - */ -public class TestInstrumentedBootstrap { - private NioEventLoopGroup _group; - - @BeforeClass(groups = "unit") - public void beforeClass() { - _group = new NioEventLoopGroup(); - } - - @AfterClass(groups = "unit") - public void afterClass() { - Optional.ofNullable(_group).ifPresent(NioEventLoopGroup::shutdownGracefully); - } - - @Test(groups = "unit") - public void testConnect1() throws Exception { - - CallTracker callTracker = Mockito.mock(CallTracker.class); - CallCompletion callCompletion = Mockito.mock(CallCompletion.class, "testConnect1"); - Mockito.when(callTracker.startCall()).thenReturn(callCompletion); - - Bootstrap bootstrap = new InstrumentedBootstrap(callTracker).channel(NioSocketChannel.class) - .group(_group) - .handler(new LoggingHandler()); - - ServerSocket server = new ServerSocket(0); - - ChannelFuture connectFuture = bootstrap.clone().connect(server.getLocalSocketAddress()); - - Socket sock = server.accept(); - - connectFuture.sync(); - Thread.sleep(100); - - // noinspection ResultOfMethodCallIgnored - Mockito.verify(callTracker).startCall(); - Mockito.verify(callCompletion).closeCompletion(Mockito.any(), Mockito.isNull(Throwable.class)); - - server.close(); - sock.close(); - connectFuture.channel().close().sync(); - } - - @Test(groups = "unit") - public void testConnect0() throws Exception { - CallTracker callTracker = Mockito.mock(CallTracker.class); - CallCompletion callCompletion = Mockito.mock(CallCompletion.class, "testConnect0"); - Mockito.when(callTracker.startCall()).thenReturn(callCompletion); - - Bootstrap bootstrap = new InstrumentedBootstrap(callTracker).channel(NioSocketChannel.class) - .group(_group) - .handler(new LoggingHandler()); - - ServerSocket server = new ServerSocket(0); - - ChannelFuture connectFuture = bootstrap.clone().remoteAddress(server.getLocalSocketAddress()).connect(); - - Socket sock = server.accept(); - - connectFuture.sync(); - Thread.sleep(100); - - // noinspection ResultOfMethodCallIgnored - Mockito.verify(callTracker).startCall(); - Mockito.verify(callCompletion).closeCompletion(Mockito.any(), Mockito.isNull(Throwable.class)); - - server.close(); - sock.close(); - connectFuture.channel().close().sync(); - } - - @Test(groups = "unit") - public void testConnectError() throws Exception { - CallTracker callTracker = Mockito.mock(CallTracker.class); - CallCompletion callCompletion = Mockito.mock(CallCompletion.class, "testConnect0"); - Mockito.when(callTracker.startCall()).thenReturn(callCompletion); - - Bootstrap bootstrap = new InstrumentedBootstrap(callTracker).channel(NioSocketChannel.class) - .group(_group) - .handler(new LoggingHandler()); - - ServerSocket server = new ServerSocket(0); - bootstrap.remoteAddress(server.getLocalSocketAddress()); - server.close(); - - ChannelFuture connectFuture = bootstrap.clone().connect(); - - connectFuture.await(); - Thread.sleep(100); - - // noinspection ResultOfMethodCallIgnored - Mockito.verify(callTracker).startCall(); - Mockito.verify(callCompletion).closeCompletion(Mockito.isNull(), Mockito.isNotNull(ConnectException.class)); - } - -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/io/netty/bootstrap/TestResolveAllBootstrap.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/io/netty/bootstrap/TestResolveAllBootstrap.java deleted file mode 100644 index bee4228afab..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/io/netty/bootstrap/TestResolveAllBootstrap.java +++ /dev/null @@ -1,230 +0,0 @@ -package io.netty.bootstrap; - -import com.linkedin.alpini.base.monitoring.CallCompletion; -import com.linkedin.alpini.base.monitoring.CallTracker; -import com.linkedin.alpini.util.TestNettyUtil; -import io.netty.channel.ChannelFuture; -import io.netty.channel.epoll.EpollEventLoopGroup; -import io.netty.channel.epoll.EpollSocketChannel; -import io.netty.handler.logging.LoggingHandler; -import java.net.Inet6Address; -import java.net.InetSocketAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.Optional; -import org.mockito.Mockito; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - - -/** - * Created by acurtis on 4/23/18. - */ -public class TestResolveAllBootstrap { - private EpollEventLoopGroup _group; - - @BeforeClass(groups = "unit") - public void beforeClass() { - _group = TestNettyUtil.skipEpollIfNotFound(() -> new EpollEventLoopGroup()); - } - - @AfterClass(groups = "unit") - public void afterClass() { - Optional.ofNullable(_group).ifPresent(EpollEventLoopGroup::shutdownGracefully); - } - - @Test(groups = "unit") - public void testConnect0() throws Exception { - CallTracker connectCallTracker = Mockito.mock(CallTracker.class); - CallTracker resolveCallTracker = Mockito.mock(CallTracker.class); - CallCompletion connectCallCompletion = Mockito.mock(CallCompletion.class, "connectCallCompletion"); - CallCompletion resolveCallCompletion = Mockito.mock(CallCompletion.class, "resolveCallCompletion"); - Mockito.when(connectCallTracker.startCall()).thenReturn(connectCallCompletion); - Mockito.when(resolveCallTracker.startCall()).thenReturn(resolveCallCompletion); - - Bootstrap bootstrap = - new ResolveAllBootstrap(connectCallTracker, resolveCallTracker).channel(EpollSocketChannel.class) - .group(_group) - .handler(new LoggingHandler()); - - ServerSocket server = new ServerSocket(0); - - ChannelFuture connectFuture = - bootstrap.clone().connect(InetSocketAddress.createUnresolved("localhost", server.getLocalPort())); - - Socket sock = server.accept(); - - connectFuture.sync(); - Thread.sleep(100); - - // noinspection ResultOfMethodCallIgnored - Mockito.verify(resolveCallTracker).startCall(); - Mockito.verify(resolveCallCompletion).closeCompletion(Mockito.any(), Mockito.isNull(Throwable.class)); - - // noinspection ResultOfMethodCallIgnored - Mockito.verify(connectCallTracker).startCall(); - Mockito.verify(connectCallCompletion).closeCompletion(Mockito.any(), Mockito.isNull(Throwable.class)); - - server.close(); - sock.close(); - connectFuture.channel().close().sync(); - } - - @Test(groups = "unit") - public void testConnectIpv6Ipv4() throws Exception { - CallTracker connectCallTracker = Mockito.mock(CallTracker.class); - CallTracker resolveCallTracker = Mockito.mock(CallTracker.class); - CallCompletion connectCallCompletion = Mockito.mock(CallCompletion.class, "connectCallCompletion"); - CallCompletion resolveCallCompletion = Mockito.mock(CallCompletion.class, "resolveCallCompletion"); - Mockito.when(connectCallTracker.startCall()).thenReturn(connectCallCompletion); - Mockito.when(resolveCallTracker.startCall()).thenReturn(resolveCallCompletion); - - // The sort will make it try the IPv6 loopback address first but since the server is bound - // to the IPv4 loopback only, it will have to retry. - - Bootstrap bootstrap = - new ResolveAllBootstrap(connectCallTracker, resolveCallTracker).sortResolvedAddress((o1, o2) -> { - InetSocketAddress i1 = (InetSocketAddress) o1; - InetSocketAddress i2 = (InetSocketAddress) o2; - int v1 = i1.getAddress() instanceof Inet6Address ? -1 : +1; - int v2 = i2.getAddress() instanceof Inet6Address ? -1 : +1; - return Integer.compare(v1, v2); - }).channel(EpollSocketChannel.class).group(_group).handler(new LoggingHandler()); - - ServerSocket server = new ServerSocket(); - server.bind(new InetSocketAddress("127.0.0.1", 0)); - - ChannelFuture connectFuture = - bootstrap.remoteAddress(InetSocketAddress.createUnresolved("localhost", server.getLocalPort())) - .clone() - .connect(); - - Socket sock = server.accept(); - - connectFuture.sync(); - Thread.sleep(100); - - // noinspection ResultOfMethodCallIgnored - Mockito.verify(resolveCallTracker).startCall(); - Mockito.verify(resolveCallCompletion).closeCompletion(Mockito.any(), Mockito.isNull(Throwable.class)); - - // noinspection ResultOfMethodCallIgnored - Mockito.verify(connectCallTracker, Mockito.times(2)).startCall(); - Mockito.verify(connectCallCompletion).closeCompletion(Mockito.any(), Mockito.isNull(Throwable.class)); - Mockito.verify(connectCallCompletion).closeCompletion(Mockito.isNull(), Mockito.isNotNull(Throwable.class)); - - server.close(); - sock.close(); - connectFuture.channel().close().sync(); - } - - @Test(groups = "unit") - public void testConnectRefused() throws Exception { - CallTracker connectCallTracker = Mockito.mock(CallTracker.class); - CallTracker resolveCallTracker = Mockito.mock(CallTracker.class); - CallCompletion connectCallCompletion = Mockito.mock(CallCompletion.class, "connectCallCompletion"); - CallCompletion resolveCallCompletion = Mockito.mock(CallCompletion.class, "resolveCallCompletion"); - Mockito.when(connectCallTracker.startCall()).thenReturn(connectCallCompletion); - Mockito.when(resolveCallTracker.startCall()).thenReturn(resolveCallCompletion); - - Bootstrap bootstrap = - new ResolveAllBootstrap(connectCallTracker, resolveCallTracker).channel(EpollSocketChannel.class) - .group(_group) - .handler(new LoggingHandler()); - - ChannelFuture connectFuture = bootstrap.clone() - .remoteAddress(InetSocketAddress.createUnresolved("localhost", 79)) // doubt we have Gopher - .connect(); - - connectFuture.await(); - Thread.sleep(100); - - // noinspection ResultOfMethodCallIgnored - Mockito.verify(resolveCallTracker).startCall(); - Mockito.verify(resolveCallCompletion).closeCompletion(Mockito.any(), Mockito.isNull(Throwable.class)); - - // noinspection ResultOfMethodCallIgnored - Mockito.verify(connectCallTracker, Mockito.times(2)).startCall(); - Mockito.verify(connectCallCompletion, Mockito.times(2)) - .closeCompletion(Mockito.isNull(), Mockito.isNotNull(Throwable.class)); - - Assert.assertTrue(connectFuture.isDone()); - Assert.assertFalse(connectFuture.isSuccess()); - Assert.assertTrue( - connectFuture.cause().getMessage().matches(".*Connection refused: localhost/.*"), - connectFuture.cause().getMessage()); - } - - @Test(groups = "unit") - public void testConnectUnresolveable() throws Exception { - CallTracker connectCallTracker = Mockito.mock(CallTracker.class); - CallTracker resolveCallTracker = Mockito.mock(CallTracker.class); - CallCompletion connectCallCompletion = Mockito.mock(CallCompletion.class, "connectCallCompletion"); - CallCompletion resolveCallCompletion = Mockito.mock(CallCompletion.class, "resolveCallCompletion"); - Mockito.when(connectCallTracker.startCall()).thenReturn(connectCallCompletion); - Mockito.when(resolveCallTracker.startCall()).thenReturn(resolveCallCompletion); - - Bootstrap bootstrap = - new ResolveAllBootstrap(connectCallTracker, resolveCallTracker).channel(EpollSocketChannel.class) - .group(_group) - .handler(new LoggingHandler()); - - ChannelFuture connectFuture = bootstrap.clone() - .remoteAddress(InetSocketAddress.createUnresolved("unresolvable.linkedin.com", 79)) // doubt we have Gopher - .connect(); - - connectFuture.await(); - Thread.sleep(100); - - // noinspection ResultOfMethodCallIgnored - Mockito.verify(resolveCallTracker).startCall(); - Mockito.verify(resolveCallCompletion).closeCompletion(Mockito.isNull(), Mockito.isNotNull(Throwable.class)); - - Mockito.verifyNoMoreInteractions(connectCallTracker); - } - - @Test(groups = "unit") - public void testConnectResolvedRefused() throws Exception { - CallTracker connectCallTracker = Mockito.mock(CallTracker.class); - CallTracker resolveCallTracker = Mockito.mock(CallTracker.class); - CallCompletion connectCallCompletion = Mockito.mock(CallCompletion.class, "connectCallCompletion"); - CallCompletion resolveCallCompletion = Mockito.mock(CallCompletion.class, "resolveCallCompletion"); - Mockito.when(connectCallTracker.startCall()).thenReturn(connectCallCompletion); - Mockito.when(resolveCallTracker.startCall()).thenReturn(resolveCallCompletion); - - InetSocketAddress address = new InetSocketAddress("localhost", 79); - Assert.assertFalse(address.isUnresolved()); - - Bootstrap bootstrap = - new ResolveAllBootstrap(connectCallTracker, resolveCallTracker).channel(EpollSocketChannel.class) - .group(_group) - .handler(new LoggingHandler()); - - ChannelFuture connectFuture = bootstrap.clone() - .remoteAddress(address) // doubt we have Gopher - .connect(); - - connectFuture.await(); - Thread.sleep(100); - - // noinspection ResultOfMethodCallIgnored - Mockito.verifyNoMoreInteractions(resolveCallTracker); - Mockito.verifyNoMoreInteractions(resolveCallCompletion); - - // Since the address is already resolved, it will only make 1 connect attempt unlike - // the earlier testConnectRefused test - - // noinspection ResultOfMethodCallIgnored - Mockito.verify(connectCallTracker, Mockito.times(1)).startCall(); - Mockito.verify(connectCallCompletion, Mockito.times(1)) - .closeCompletion(Mockito.isNull(), Mockito.isNotNull(Throwable.class)); - - Assert.assertTrue(connectFuture.isDone()); - Assert.assertFalse(connectFuture.isSuccess()); - Assert.assertTrue( - connectFuture.cause().getMessage().matches(".*Connection refused: localhost/.*"), - connectFuture.cause().getMessage()); - } -} diff --git a/internal/alpini/netty4/alpini-netty4-base/src/test/java/io/netty/handler/codec/http/TestEspressoHttpObjectAggregator.java b/internal/alpini/netty4/alpini-netty4-base/src/test/java/io/netty/handler/codec/http/TestEspressoHttpObjectAggregator.java deleted file mode 100644 index c33334436bb..00000000000 --- a/internal/alpini/netty4/alpini-netty4-base/src/test/java/io/netty/handler/codec/http/TestEspressoHttpObjectAggregator.java +++ /dev/null @@ -1,729 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project 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 io.netty.handler.codec.http; - -import static io.netty.util.AsciiString.of; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertNull; -import static org.testng.Assert.assertSame; -import static org.testng.Assert.assertThrows; -import static org.testng.Assert.assertTrue; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.CompositeByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.embedded.EmbeddedChannel; -import io.netty.handler.codec.DecoderResult; -import io.netty.handler.codec.DecoderResultProvider; -import io.netty.handler.codec.TooLongFrameException; -import io.netty.util.AsciiString; -import io.netty.util.CharsetUtil; -import io.netty.util.ReferenceCountUtil; -import java.nio.channels.ClosedChannelException; -import java.util.List; -import org.mockito.Mockito; -import org.testng.annotations.Test; - - -public class TestEspressoHttpObjectAggregator { - @Test - public void testAggregate() { - EspressoHttpObjectAggregator aggr = new EspressoHttpObjectAggregator(1024 * 1024); - EmbeddedChannel embedder = new EmbeddedChannel(aggr); - - HttpRequest message = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "http://localhost"); - message.headers().set(of("X-Test"), true); - HttpContent chunk1 = new DefaultHttpContent(Unpooled.copiedBuffer("test", CharsetUtil.US_ASCII)); - HttpContent chunk2 = new DefaultHttpContent(Unpooled.copiedBuffer("test2", CharsetUtil.US_ASCII)); - HttpContent chunk3 = new DefaultLastHttpContent(Unpooled.EMPTY_BUFFER); - assertFalse(embedder.writeInbound(message)); - assertFalse(embedder.writeInbound(chunk1)); - assertFalse(embedder.writeInbound(chunk2)); - - // this should trigger a channelRead event so return true - assertTrue(embedder.writeInbound(chunk3)); - assertTrue(embedder.finish()); - FullHttpRequest aggregatedMessage = embedder.readInbound(); - assertNotNull(aggregatedMessage); - - assertEquals( - chunk1.content().readableBytes() + chunk2.content().readableBytes(), - HttpUtil.getContentLength(aggregatedMessage)); - assertEquals(Boolean.TRUE.toString(), aggregatedMessage.headers().get(of("X-Test"))); - checkContentBuffer(aggregatedMessage); - assertNull(embedder.readInbound()); - } - - private static void checkContentBuffer(FullHttpRequest aggregatedMessage) { - CompositeByteBuf buffer = (CompositeByteBuf) aggregatedMessage.content(); - assertEquals(2, buffer.numComponents()); - List buffers = buffer.decompose(0, buffer.capacity()); - assertEquals(2, buffers.size()); - for (ByteBuf buf: buffers) { - // This should be false as we decompose the buffer before to not have deep hierarchy - assertFalse(buf instanceof CompositeByteBuf); - } - aggregatedMessage.release(); - } - - @Test - public void testAggregateWithTrailer() { - EspressoHttpObjectAggregator aggr = new EspressoHttpObjectAggregator(1024 * 1024); - EmbeddedChannel embedder = new EmbeddedChannel(aggr); - HttpRequest message = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "http://localhost"); - message.headers().set(of("X-Test"), true); - HttpUtil.setTransferEncodingChunked(message, true); - HttpContent chunk1 = new DefaultHttpContent(Unpooled.copiedBuffer("test", CharsetUtil.US_ASCII)); - HttpContent chunk2 = new DefaultHttpContent(Unpooled.copiedBuffer("test2", CharsetUtil.US_ASCII)); - LastHttpContent trailer = new DefaultLastHttpContent(); - trailer.trailingHeaders().set(of("X-Trailer"), true); - - assertFalse(embedder.writeInbound(message)); - assertFalse(embedder.writeInbound(chunk1)); - assertFalse(embedder.writeInbound(chunk2)); - - // this should trigger a channelRead event so return true - assertTrue(embedder.writeInbound(trailer)); - assertTrue(embedder.finish()); - FullHttpRequest aggregatedMessage = embedder.readInbound(); - assertNotNull(aggregatedMessage); - - assertEquals( - chunk1.content().readableBytes() + chunk2.content().readableBytes(), - HttpUtil.getContentLength(aggregatedMessage)); - assertEquals(Boolean.TRUE.toString(), aggregatedMessage.headers().get(of("X-Test"))); - assertEquals(Boolean.TRUE.toString(), aggregatedMessage.trailingHeaders().get(of("X-Trailer"))); - checkContentBuffer(aggregatedMessage); - assertNull(embedder.readInbound()); - } - - @Test - public void testOversizedRequest() { - final EmbeddedChannel embedder = new EmbeddedChannel(new EspressoHttpObjectAggregator(4)); - HttpRequest message = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.PUT, "http://localhost"); - HttpContent chunk1 = new DefaultHttpContent(Unpooled.copiedBuffer("test", CharsetUtil.US_ASCII)); - HttpContent chunk2 = new DefaultHttpContent(Unpooled.copiedBuffer("test2", CharsetUtil.US_ASCII)); - final HttpContent chunk3 = LastHttpContent.EMPTY_LAST_CONTENT; - - assertFalse(embedder.writeInbound(message)); - assertFalse(embedder.writeInbound(chunk1)); - assertFalse(embedder.writeInbound(chunk2)); - - FullHttpResponse response = embedder.readOutbound(); - assertEquals(HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE, response.status()); - assertEquals("0", response.headers().get(HttpHeaderNames.CONTENT_LENGTH)); - assertFalse(embedder.isOpen()); - - assertThrows(ClosedChannelException.class, () -> embedder.writeInbound(chunk3)); - - assertFalse(embedder.finish()); - } - - @Test - public void testOversizedRequestWithContentLengthAndDecoder() { - EmbeddedChannel embedder = - new EmbeddedChannel(new HttpRequestDecoder(), new EspressoHttpObjectAggregator(4, false)); - assertFalse( - embedder.writeInbound( - Unpooled.copiedBuffer("PUT /upload HTTP/1.1\r\n" + "Content-Length: 5\r\n\r\n", CharsetUtil.US_ASCII))); - - assertNull(embedder.readInbound()); - - FullHttpResponse response = embedder.readOutbound(); - assertEquals(HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE, response.status()); - assertEquals("0", response.headers().get(HttpHeaderNames.CONTENT_LENGTH)); - - assertTrue(embedder.isOpen()); - - assertFalse(embedder.writeInbound(Unpooled.wrappedBuffer(new byte[] { 1, 2, 3, 4 }))); - assertFalse(embedder.writeInbound(Unpooled.wrappedBuffer(new byte[] { 5 }))); - - assertNull(embedder.readOutbound()); - - assertFalse( - embedder.writeInbound( - Unpooled.copiedBuffer("PUT /upload HTTP/1.1\r\n" + "Content-Length: 2\r\n\r\n", CharsetUtil.US_ASCII))); - - assertEquals(HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE, response.status()); - assertEquals("0", response.headers().get(HttpHeaderNames.CONTENT_LENGTH)); - - assertTrue(response instanceof LastHttpContent); - ReferenceCountUtil.release(response); - - assertTrue(embedder.isOpen()); - - assertFalse(embedder.writeInbound(Unpooled.copiedBuffer(new byte[] { 1 }))); - assertNull(embedder.readOutbound()); - assertTrue(embedder.writeInbound(Unpooled.copiedBuffer(new byte[] { 2 }))); - assertNull(embedder.readOutbound()); - - FullHttpRequest request = embedder.readInbound(); - assertEquals(HttpVersion.HTTP_1_1, request.protocolVersion()); - assertEquals(HttpMethod.PUT, request.method()); - assertEquals("/upload", request.uri()); - assertEquals(2, HttpUtil.getContentLength(request)); - - byte[] actual = new byte[request.content().readableBytes()]; - request.content().readBytes(actual); - assertArrayEquals(new byte[] { 1, 2 }, actual); - request.release(); - - assertFalse(embedder.finish()); - } - - private static void assertArrayEquals(byte[] bytes, byte[] actual) { - assertNotNull(bytes); - assertNotNull(actual); - assertEquals(bytes.length, actual.length); - for (int i = 0; i < bytes.length; i++) { - assertEquals(bytes[i], actual[i]); - } - } - - @Test - public void testOversizedRequestWithoutKeepAlive() { - // send an HTTP/1.0 request with no keep-alive header - HttpRequest message = new DefaultHttpRequest(HttpVersion.HTTP_1_0, HttpMethod.PUT, "http://localhost"); - HttpUtil.setContentLength(message, 5); - checkOversizedRequest(message); - } - - @Test - public void testOversizedRequestWithContentLength() { - HttpRequest message = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.PUT, "http://localhost"); - HttpUtil.setContentLength(message, 5); - checkOversizedRequest(message); - } - - private static void checkOversizedRequest(HttpRequest message) { - final EmbeddedChannel embedder = new EmbeddedChannel(new EspressoHttpObjectAggregator(4)); - - assertFalse(embedder.writeInbound(message)); - HttpResponse response = embedder.readOutbound(); - assertEquals(HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE, response.status()); - assertEquals("0", response.headers().get(HttpHeaderNames.CONTENT_LENGTH)); - - assertTrue(response instanceof LastHttpContent); - ReferenceCountUtil.release(response); - - if (serverShouldCloseConnection(message, response)) { - assertFalse(embedder.isOpen()); - - assertThrows( - ClosedChannelException.class, - () -> embedder.writeInbound(new DefaultHttpContent(Unpooled.EMPTY_BUFFER))); - - assertFalse(embedder.finish()); - } else { - assertTrue(embedder.isOpen()); - assertFalse(embedder.writeInbound(new DefaultHttpContent(Unpooled.copiedBuffer(new byte[8])))); - assertFalse(embedder.writeInbound(new DefaultHttpContent(Unpooled.copiedBuffer(new byte[8])))); - - // Now start a new message and ensure we will not reject it again. - HttpRequest message2 = new DefaultHttpRequest(HttpVersion.HTTP_1_0, HttpMethod.PUT, "http://localhost"); - HttpUtil.setContentLength(message, 2); - - assertFalse(embedder.writeInbound(message2)); - assertNull(embedder.readOutbound()); - assertFalse(embedder.writeInbound(new DefaultHttpContent(Unpooled.copiedBuffer(new byte[] { 1 })))); - assertNull(embedder.readOutbound()); - assertTrue(embedder.writeInbound(new DefaultLastHttpContent(Unpooled.copiedBuffer(new byte[] { 2 })))); - assertNull(embedder.readOutbound()); - - FullHttpRequest request = embedder.readInbound(); - assertEquals(message2.protocolVersion(), request.protocolVersion()); - assertEquals(message2.method(), request.method()); - assertEquals(message2.uri(), request.uri()); - assertEquals(2, HttpUtil.getContentLength(request)); - - byte[] actual = new byte[request.content().readableBytes()]; - request.content().readBytes(actual); - assertArrayEquals(new byte[] { 1, 2 }, actual); - request.release(); - - assertFalse(embedder.finish()); - } - } - - private static boolean serverShouldCloseConnection(HttpRequest message, HttpResponse response) { - // If the response wasn't keep-alive, the server should close the connection. - if (!HttpUtil.isKeepAlive(response)) { - return true; - } - // The connection should only be kept open if Expect: 100-continue is set, - // or if keep-alive is on. - if (HttpUtil.is100ContinueExpected(message)) { - return false; - } - if (HttpUtil.isKeepAlive(message)) { - return false; - } - return true; - } - - @Test - public void testOversizedResponse() { - final EmbeddedChannel embedder = new EmbeddedChannel(new EspressoHttpObjectAggregator(4)); - HttpResponse message = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); - HttpContent chunk1 = new DefaultHttpContent(Unpooled.copiedBuffer("test", CharsetUtil.US_ASCII)); - final HttpContent chunk2 = new DefaultHttpContent(Unpooled.copiedBuffer("test2", CharsetUtil.US_ASCII)); - - assertFalse(embedder.writeInbound(message)); - assertFalse(embedder.writeInbound(chunk1)); - - assertThrows(TooLongFrameException.class, () -> embedder.writeInbound(chunk2)); - - assertFalse(embedder.isOpen()); - assertFalse(embedder.finish()); - } - - @Test - public void testInvalidConstructorUsage() { - assertThrows(IllegalArgumentException.class, () -> new EspressoHttpObjectAggregator(-1) - - ); - } - - @Test - public void testInvalidMaxCumulationBufferComponents() { - final EspressoHttpObjectAggregator aggr = new EspressoHttpObjectAggregator(Integer.MAX_VALUE); - assertThrows(IllegalArgumentException.class, () -> aggr.setMaxCumulationBufferComponents(1)); - } - - @Test - public void testSetMaxCumulationBufferComponentsAfterInit() throws Exception { - final EspressoHttpObjectAggregator aggr = new EspressoHttpObjectAggregator(Integer.MAX_VALUE); - ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); - aggr.handlerAdded(ctx); - Mockito.verifyNoMoreInteractions(ctx); - assertThrows(IllegalStateException.class, () -> aggr.setMaxCumulationBufferComponents(10)); - } - - @Test - public void testAggregateTransferEncodingChunked() { - EspressoHttpObjectAggregator aggr = new EspressoHttpObjectAggregator(1024 * 1024); - EmbeddedChannel embedder = new EmbeddedChannel(aggr); - - HttpRequest message = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.PUT, "http://localhost"); - message.headers().set(of("X-Test"), true); - message.headers().set(of("Transfer-Encoding"), of("Chunked")); - HttpContent chunk1 = new DefaultHttpContent(Unpooled.copiedBuffer("test", CharsetUtil.US_ASCII)); - HttpContent chunk2 = new DefaultHttpContent(Unpooled.copiedBuffer("test2", CharsetUtil.US_ASCII)); - HttpContent chunk3 = LastHttpContent.EMPTY_LAST_CONTENT; - assertFalse(embedder.writeInbound(message)); - assertFalse(embedder.writeInbound(chunk1)); - assertFalse(embedder.writeInbound(chunk2)); - - // this should trigger a channelRead event so return true - assertTrue(embedder.writeInbound(chunk3)); - assertTrue(embedder.finish()); - FullHttpRequest aggregatedMessage = embedder.readInbound(); - assertNotNull(aggregatedMessage); - - assertEquals( - chunk1.content().readableBytes() + chunk2.content().readableBytes(), - HttpUtil.getContentLength(aggregatedMessage)); - assertEquals(Boolean.TRUE.toString(), aggregatedMessage.headers().get(of("X-Test"))); - checkContentBuffer(aggregatedMessage); - assertNull(embedder.readInbound()); - } - - @Test - public void testBadRequest() { - EmbeddedChannel ch = new EmbeddedChannel(new HttpRequestDecoder(), new EspressoHttpObjectAggregator(1024 * 1024)); - ch.writeInbound(Unpooled.copiedBuffer("GET / HTTP/1.0 with extra\r\n", CharsetUtil.UTF_8)); - Object inbound = ch.readInbound(); - assertTrue(inbound instanceof FullHttpRequest); - assertTrue(((DecoderResultProvider) inbound).decoderResult().isFailure()); - assertNull(ch.readInbound()); - ch.finish(); - } - - @Test - public void testBadResponse() throws Exception { - EmbeddedChannel ch = new EmbeddedChannel(new HttpResponseDecoder(), new EspressoHttpObjectAggregator(1024 * 1024)); - ch.writeInbound(Unpooled.copiedBuffer("HTTP/1.0 BAD_CODE Bad Server\r\n", CharsetUtil.UTF_8)); - Object inbound = ch.readInbound(); - assertTrue(inbound instanceof FullHttpResponse); - assertTrue(((DecoderResultProvider) inbound).decoderResult().isFailure()); - assertNull(ch.readInbound()); - ch.finish(); - } - - @Test - public void testOversizedRequestWith100Continue() { - EmbeddedChannel embedder = new EmbeddedChannel(new EspressoHttpObjectAggregator(8)); - - // Send an oversized request with 100 continue. - HttpRequest message = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.PUT, "http://localhost"); - HttpUtil.set100ContinueExpected(message, true); - HttpUtil.setContentLength(message, 16); - - HttpContent chunk1 = new DefaultHttpContent(Unpooled.copiedBuffer("some", CharsetUtil.US_ASCII)); - HttpContent chunk2 = new DefaultHttpContent(Unpooled.copiedBuffer("test", CharsetUtil.US_ASCII)); - HttpContent chunk3 = LastHttpContent.EMPTY_LAST_CONTENT; - - // Send a request with 100-continue + large Content-Length header value. - assertFalse(embedder.writeInbound(message)); - - // The aggregator should respond with '413.' - FullHttpResponse response = embedder.readOutbound(); - assertEquals(HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE, response.status()); - assertEquals("0", response.headers().get(HttpHeaderNames.CONTENT_LENGTH)); - - // An ill-behaving client could continue to send data without a respect, and such data should be discarded. - assertFalse(embedder.writeInbound(chunk1)); - - // The aggregator should not close the connection because keep-alive is on. - assertTrue(embedder.isOpen()); - - // Now send a valid request. - HttpRequest message2 = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.PUT, "http://localhost"); - - assertFalse(embedder.writeInbound(message2)); - assertFalse(embedder.writeInbound(chunk2)); - assertTrue(embedder.writeInbound(chunk3)); - - FullHttpRequest fullMsg = embedder.readInbound(); - assertNotNull(fullMsg); - - assertEquals( - chunk2.content().readableBytes() + chunk3.content().readableBytes(), - HttpUtil.getContentLength(fullMsg)); - - assertEquals(HttpUtil.getContentLength(fullMsg), fullMsg.content().readableBytes()); - - fullMsg.release(); - assertFalse(embedder.finish()); - } - - @Test - public void testUnsupportedExpectHeaderExpectation() { - runUnsupportedExceptHeaderExceptionTest(true); - runUnsupportedExceptHeaderExceptionTest(false); - } - - private static void runUnsupportedExceptHeaderExceptionTest(final boolean close) { - final EspressoHttpObjectAggregator aggregator; - final int maxContentLength = 4; - if (close) { - aggregator = new EspressoHttpObjectAggregator(maxContentLength, true); - } else { - aggregator = new EspressoHttpObjectAggregator(maxContentLength); - } - final EmbeddedChannel embedder = new EmbeddedChannel(new HttpRequestDecoder(), aggregator); - - assertFalse( - embedder.writeInbound( - Unpooled.copiedBuffer( - "GET / HTTP/1.1\r\n" + "Expect: chocolate=yummy\r\n" + "Content-Length: 100\r\n\r\n", - CharsetUtil.US_ASCII))); - assertNull(embedder.readInbound()); - - final FullHttpResponse response = embedder.readOutbound(); - assertEquals(HttpResponseStatus.EXPECTATION_FAILED, response.status()); - assertEquals("0", response.headers().get(HttpHeaderNames.CONTENT_LENGTH)); - response.release(); - - if (close) { - assertFalse(embedder.isOpen()); - } else { - // keep-alive is on by default in HTTP/1.1, so the connection should be still alive - assertTrue(embedder.isOpen()); - - // the decoder should be reset by the aggregator at this point and be able to decode the next request - assertTrue(embedder.writeInbound(Unpooled.copiedBuffer("GET / HTTP/1.1\r\n\r\n", CharsetUtil.US_ASCII))); - - final FullHttpRequest request = embedder.readInbound(); - assertEquals(request.method(), HttpMethod.GET); - assertEquals(request.uri(), "/"); - assertEquals(request.content().readableBytes(), 0); - request.release(); - } - - assertFalse(embedder.finish()); - } - - @Test - public void testValidRequestWith100ContinueAndDecoder() { - EmbeddedChannel embedder = new EmbeddedChannel(new HttpRequestDecoder(), new EspressoHttpObjectAggregator(100)); - embedder.writeInbound( - Unpooled.copiedBuffer( - "GET /upload HTTP/1.1\r\n" + "Expect: 100-continue\r\n" + "Content-Length: 0\r\n\r\n", - CharsetUtil.US_ASCII)); - - FullHttpResponse response = embedder.readOutbound(); - assertEquals(HttpResponseStatus.CONTINUE, response.status()); - FullHttpRequest request = embedder.readInbound(); - assertFalse(request.headers().contains(HttpHeaderNames.EXPECT)); - request.release(); - response.release(); - assertFalse(embedder.finish()); - } - - @Test - public void testOversizedRequestWith100ContinueAndDecoder() { - EmbeddedChannel embedder = new EmbeddedChannel(new HttpRequestDecoder(), new EspressoHttpObjectAggregator(4)); - embedder.writeInbound( - Unpooled.copiedBuffer( - "PUT /upload HTTP/1.1\r\n" + "Expect: 100-continue\r\n" + "Content-Length: 100\r\n\r\n", - CharsetUtil.US_ASCII)); - - assertNull(embedder.readInbound()); - - FullHttpResponse response = embedder.readOutbound(); - assertEquals(HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE, response.status()); - assertEquals("0", response.headers().get(HttpHeaderNames.CONTENT_LENGTH)); - - // Keep-alive is on by default in HTTP/1.1, so the connection should be still alive. - assertTrue(embedder.isOpen()); - - // The decoder should be reset by the aggregator at this point and be able to decode the next request. - embedder.writeInbound(Unpooled.copiedBuffer("GET /max-upload-size HTTP/1.1\r\n\r\n", CharsetUtil.US_ASCII)); - - FullHttpRequest request = embedder.readInbound(); - assertEquals(request.method(), HttpMethod.GET); - assertEquals(request.uri(), "/max-upload-size"); - assertEquals(request.content().readableBytes(), 0); - request.release(); - - assertFalse(embedder.finish()); - } - - @Test - public void testOversizedRequestWith100ContinueAndDecoderCloseConnection() { - EmbeddedChannel embedder = new EmbeddedChannel(new HttpRequestDecoder(), new EspressoHttpObjectAggregator(4, true)); - embedder.writeInbound( - Unpooled.copiedBuffer( - "PUT /upload HTTP/1.1\r\n" + "Expect: 100-continue\r\n" + "Content-Length: 100\r\n\r\n", - CharsetUtil.US_ASCII)); - - assertNull(embedder.readInbound()); - - FullHttpResponse response = embedder.readOutbound(); - assertEquals(HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE, response.status()); - assertEquals("0", response.headers().get(HttpHeaderNames.CONTENT_LENGTH)); - - // We are forcing the connection closed if an expectation is exceeded. - assertFalse(embedder.isOpen()); - assertFalse(embedder.finish()); - } - - @Test - public void testRequestAfterOversized100ContinueAndDecoder() { - EmbeddedChannel embedder = new EmbeddedChannel(new HttpRequestDecoder(), new EspressoHttpObjectAggregator(15)); - - // Write first request with Expect: 100-continue. - HttpRequest message = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.PUT, "http://localhost"); - HttpUtil.set100ContinueExpected(message, true); - HttpUtil.setContentLength(message, 16); - - HttpContent chunk1 = new DefaultHttpContent(Unpooled.copiedBuffer("some", CharsetUtil.US_ASCII)); - HttpContent chunk2 = new DefaultHttpContent(Unpooled.copiedBuffer("test", CharsetUtil.US_ASCII)); - HttpContent chunk3 = LastHttpContent.EMPTY_LAST_CONTENT; - - // Send a request with 100-continue + large Content-Length header value. - assertFalse(embedder.writeInbound(message)); - - // The aggregator should respond with '413'. - FullHttpResponse response = embedder.readOutbound(); - assertEquals(HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE, response.status()); - assertEquals("0", response.headers().get(HttpHeaderNames.CONTENT_LENGTH)); - - // An ill-behaving client could continue to send data without a respect, and such data should be discarded. - assertFalse(embedder.writeInbound(chunk1)); - - // The aggregator should not close the connection because keep-alive is on. - assertTrue(embedder.isOpen()); - - // Now send a valid request. - HttpRequest message2 = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.PUT, "http://localhost"); - - assertFalse(embedder.writeInbound(message2)); - assertFalse(embedder.writeInbound(chunk2)); - assertTrue(embedder.writeInbound(chunk3)); - - FullHttpRequest fullMsg = embedder.readInbound(); - assertNotNull(fullMsg); - - assertEquals( - chunk2.content().readableBytes() + chunk3.content().readableBytes(), - HttpUtil.getContentLength(fullMsg)); - - assertEquals(HttpUtil.getContentLength(fullMsg), fullMsg.content().readableBytes()); - - fullMsg.release(); - assertFalse(embedder.finish()); - } - - @Test - public void testReplaceAggregatedRequest() { - EmbeddedChannel embedder = new EmbeddedChannel(new EspressoHttpObjectAggregator(1024 * 1024)); - - Exception boom = new Exception("boom"); - HttpRequest req = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "http://localhost"); - req.setDecoderResult(DecoderResult.failure(boom)); - - assertTrue(embedder.writeInbound(req) && embedder.finish()); - - FullHttpRequest aggregatedReq = embedder.readInbound(); - FullHttpRequest replacedReq = aggregatedReq.replace(Unpooled.EMPTY_BUFFER); - - assertEquals(replacedReq.decoderResult(), aggregatedReq.decoderResult()); - aggregatedReq.release(); - replacedReq.release(); - } - - @Test - public void testReplaceAggregatedResponse() { - EmbeddedChannel embedder = new EmbeddedChannel(new EspressoHttpObjectAggregator(1024 * 1024)); - - Exception boom = new Exception("boom"); - HttpResponse rep = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); - rep.setDecoderResult(DecoderResult.failure(boom)); - - assertTrue(embedder.writeInbound(rep) && embedder.finish()); - - FullHttpResponse aggregatedRep = embedder.readInbound(); - FullHttpResponse replacedRep = aggregatedRep.replace(Unpooled.EMPTY_BUFFER); - - assertEquals(replacedRep.decoderResult(), aggregatedRep.decoderResult()); - aggregatedRep.release(); - replacedRep.release(); - } - - @Test - public void testSelectiveRequestAggregation() { - EspressoHttpObjectAggregator myPostAggregator = new EspressoHttpObjectAggregator(1024 * 1024) { - @Override - protected boolean isStartMessage(HttpObject msg) throws Exception { - if (msg instanceof HttpRequest) { - HttpRequest request = (HttpRequest) msg; - HttpMethod method = request.method(); - - if (method.equals(HttpMethod.POST)) { - return true; - } - } - - return false; - } - }; - - EmbeddedChannel channel = new EmbeddedChannel(myPostAggregator); - - try { - // Aggregate: POST - HttpRequest request1 = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/"); - HttpContent content1 = new DefaultHttpContent(Unpooled.copiedBuffer("Hello, World!", CharsetUtil.UTF_8)); - request1.headers().set(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN); - - assertTrue(channel.writeInbound(request1, content1, LastHttpContent.EMPTY_LAST_CONTENT)); - - // Getting an aggregated response out - Object msg1 = channel.readInbound(); - try { - assertTrue(msg1 instanceof FullHttpRequest); - } finally { - ReferenceCountUtil.release(msg1); - } - - // Don't aggregate: non-POST - HttpRequest request2 = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.PUT, "/"); - HttpContent content2 = new DefaultHttpContent(Unpooled.copiedBuffer("Hello, World!", CharsetUtil.UTF_8)); - request2.headers().set(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN); - - try { - assertTrue(channel.writeInbound(request2, content2, LastHttpContent.EMPTY_LAST_CONTENT)); - - // Getting the same response objects out - assertSame(request2, channel.readInbound()); - assertSame(content2, channel.readInbound()); - assertSame(LastHttpContent.EMPTY_LAST_CONTENT, channel.readInbound()); - } finally { - ReferenceCountUtil.release(request2); - ReferenceCountUtil.release(content2); - } - - assertFalse(channel.finish()); - } finally { - channel.close(); - } - } - - @Test - public void testSelectiveResponseAggregation() { - EspressoHttpObjectAggregator myTextAggregator = new EspressoHttpObjectAggregator(1024 * 1024) { - @Override - protected boolean isStartMessage(HttpObject msg) throws Exception { - if (msg instanceof HttpResponse) { - HttpResponse response = (HttpResponse) msg; - HttpHeaders headers = response.headers(); - - String contentType = headers.get(HttpHeaderNames.CONTENT_TYPE); - if (AsciiString.contentEqualsIgnoreCase(contentType, HttpHeaderValues.TEXT_PLAIN)) { - return true; - } - } - - return false; - } - }; - - EmbeddedChannel channel = new EmbeddedChannel(myTextAggregator); - - try { - // Aggregate: text/plain - HttpResponse response1 = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); - HttpContent content1 = new DefaultHttpContent(Unpooled.copiedBuffer("Hello, World!", CharsetUtil.UTF_8)); - response1.headers().set(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN); - - assertTrue(channel.writeInbound(response1, content1, LastHttpContent.EMPTY_LAST_CONTENT)); - - // Getting an aggregated response out - Object msg1 = channel.readInbound(); - try { - assertTrue(msg1 instanceof FullHttpResponse); - } finally { - ReferenceCountUtil.release(msg1); - } - - // Don't aggregate: application/json - HttpResponse response2 = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); - HttpContent content2 = new DefaultHttpContent(Unpooled.copiedBuffer("{key: 'value'}", CharsetUtil.UTF_8)); - response2.headers().set(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.APPLICATION_JSON); - - try { - assertTrue(channel.writeInbound(response2, content2, LastHttpContent.EMPTY_LAST_CONTENT)); - - // Getting the same response objects out - assertSame(response2, channel.readInbound()); - assertSame(content2, channel.readInbound()); - assertSame(LastHttpContent.EMPTY_LAST_CONTENT, channel.readInbound()); - } finally { - ReferenceCountUtil.release(response2); - ReferenceCountUtil.release(content2); - } - - assertFalse(channel.finish()); - } finally { - channel.close(); - } - } -} diff --git a/internal/alpini/router/alpini-router-api/src/main/java/com/linkedin/alpini/router/api/MetricsDecoder.java b/internal/alpini/router/alpini-router-api/src/main/java/com/linkedin/alpini/router/api/MetricsDecoder.java deleted file mode 100644 index 1bcaa8d4989..00000000000 --- a/internal/alpini/router/alpini-router-api/src/main/java/com/linkedin/alpini/router/api/MetricsDecoder.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.linkedin.alpini.router.api; - -import com.linkedin.alpini.base.misc.Headers; -import com.linkedin.alpini.base.misc.Metrics; - - -/** - * @author Antony T Curtis {@literal } - */ -public interface MetricsDecoder { - Metrics decode(Headers headers); -} diff --git a/internal/alpini/router/alpini-router-api/src/main/java/com/linkedin/alpini/router/api/MetricsDecorator.java b/internal/alpini/router/alpini-router-api/src/main/java/com/linkedin/alpini/router/api/MetricsDecorator.java deleted file mode 100644 index 2e34f720f51..00000000000 --- a/internal/alpini/router/alpini-router-api/src/main/java/com/linkedin/alpini/router/api/MetricsDecorator.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.linkedin.alpini.router.api; - -import com.linkedin.alpini.base.misc.Headers; -import com.linkedin.alpini.base.misc.Metrics; - - -/** - * @author Antony T Curtis {@literal } - */ -public interface MetricsDecorator { - Headers decorate(Headers headers, Metrics metrics); -} diff --git a/internal/alpini/router/alpini-router-api/src/main/java/com/linkedin/alpini/router/api/MetricsProvider.java b/internal/alpini/router/alpini-router-api/src/main/java/com/linkedin/alpini/router/api/MetricsProvider.java deleted file mode 100644 index 64447d466a8..00000000000 --- a/internal/alpini/router/alpini-router-api/src/main/java/com/linkedin/alpini/router/api/MetricsProvider.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.linkedin.alpini.router.api; - -import com.linkedin.alpini.base.misc.BasicRequest; -import com.linkedin.alpini.base.misc.Metrics; - - -/** - * @author Antony T Curtis {@literal } - */ -public interface MetricsProvider { - Metrics provider(BasicRequest request); -} diff --git a/internal/alpini/router/alpini-router-api/src/main/java/com/linkedin/alpini/router/api/ResourcePath.java b/internal/alpini/router/alpini-router-api/src/main/java/com/linkedin/alpini/router/api/ResourcePath.java index f693e732449..9189c3289bf 100644 --- a/internal/alpini/router/alpini-router-api/src/main/java/com/linkedin/alpini/router/api/ResourcePath.java +++ b/internal/alpini/router/alpini-router-api/src/main/java/com/linkedin/alpini/router/api/ResourcePath.java @@ -10,15 +10,6 @@ * @author Antony T Curtis {@literal } */ public interface ResourcePath { - default boolean hasMultiplePartitionKeys() { - Iterator it = getPartitionKeys().iterator(); - if (it.hasNext()) { - it.next(); - return it.hasNext(); - } - return false; - } - default K getPartitionKey() { Iterator it = getPartitionKeys().iterator(); K key = it.next(); diff --git a/internal/alpini/router/alpini-router-api/src/main/java/com/linkedin/alpini/router/monitoring/ScatterGatherStats.java b/internal/alpini/router/alpini-router-api/src/main/java/com/linkedin/alpini/router/monitoring/ScatterGatherStats.java index d32dcff1a51..8c10642e665 100644 --- a/internal/alpini/router/alpini-router-api/src/main/java/com/linkedin/alpini/router/monitoring/ScatterGatherStats.java +++ b/internal/alpini/router/alpini-router-api/src/main/java/com/linkedin/alpini/router/monitoring/ScatterGatherStats.java @@ -25,90 +25,49 @@ public ScatterGatherStats() { public class Delta { private long _totalRetries; - private long _total429Retries; private long _totalRetriedKeys; private long _totalRetriesWinner; private long _totalRetriesDiscarded; private long _totalRetriesError; - private long _totalDiscardedBytes; - private long _totalRequestsSent; - private long _totalRequestsReceived; - private long _total503Retries; - private long _total503RetriesWinner; - private long _total503RetriesError; public Delta() { } Delta(Delta x, Delta y) { _totalRetries = x._totalRetries + y._totalRetries; - _total429Retries = x._total429Retries + y._total429Retries; _totalRetriedKeys = x._totalRetriedKeys + y._totalRetriedKeys; _totalRetriesWinner = x._totalRetriesWinner + y._totalRetriesWinner; _totalRetriesDiscarded = x._totalRetriesDiscarded + y._totalRetriesDiscarded; _totalRetriesError = x._totalRetriesError + y._totalRetriesError; - _totalDiscardedBytes = x._totalDiscardedBytes + y._totalDiscardedBytes; - _totalRequestsSent = x._totalRequestsSent + y._totalRequestsSent; - _totalRequestsReceived = x._totalRequestsReceived + y._totalRequestsReceived; - _total503Retries = x._total503Retries + y._total503Retries; - _total503RetriesWinner = x._total503RetriesWinner + y._total503RetriesWinner; - _total503RetriesError = x._total503RetriesError + y._total503RetriesError; } void accumulate(Delta delta) { _totalRetries += delta._totalRetries; - _total429Retries += delta._total429Retries; _totalRetriedKeys += delta._totalRetriedKeys; _totalRetriesWinner += delta._totalRetriesWinner; _totalRetriesDiscarded += delta._totalRetriesDiscarded; _totalRetriesError += delta._totalRetriesError; - _totalDiscardedBytes += delta._totalDiscardedBytes; - _totalRequestsSent += delta._totalRequestsSent; - _totalRequestsReceived += delta._totalRequestsReceived; - _total503Retries += delta._total503Retries; - _total503RetriesWinner += delta._total503RetriesWinner; - _total503RetriesError += delta._total503RetriesError; } public void apply() { _accumulator.accept(this); _totalRetries = 0; - _total429Retries = 0; _totalRetriedKeys = 0; _totalRetriesWinner = 0; _totalRetriesDiscarded = 0; _totalRetriesError = 0; - _totalDiscardedBytes = 0; - _totalRequestsSent = 0; - _totalRequestsReceived = 0; - _total503Retries = 0; - _total503RetriesWinner = 0; - _total503RetriesError = 0; - } - - public void incrementFanoutRequestsSent(int fanout) { - _totalRequestsSent += fanout; - } - - public void incrementTotalRequestsReceived() { - _totalRequestsReceived++; } public void incrementTotalRetries() { _totalRetries++; } - public void incrementTotalRetriesOn429() { - _total429Retries++; - } - public void incrementTotalRetriedKeys(int retriedKeys) { _totalRetriedKeys += retriedKeys; } - public void incrementTotalRetriesDiscarded(long bytes) { + public void incrementTotalRetriesDiscarded() { _totalRetriesDiscarded++; - _totalDiscardedBytes += bytes; } public void incrementTotalRetriesWinner() { @@ -118,18 +77,6 @@ public void incrementTotalRetriesWinner() { public void incrementTotalRetriesError() { _totalRetriesError++; } - - public void incrementTotalRetriesOn503() { - _total503Retries++; - } - - public void incrementTotalRetriesOn503Winner() { - _total503RetriesWinner++; - } - - public void incrementTotalRetriesOn503Error() { - _total503RetriesError++; - } } @Nonnull @@ -148,11 +95,6 @@ public long getTotalRetriedKeys() { return data()._totalRetriedKeys; } - @Override - public long getTotalRetriedOn429() { - return data()._total429Retries; - } - @Override public long getTotalRetriesDiscarded() { return data()._totalRetriesDiscarded; @@ -167,34 +109,4 @@ public long getTotalRetriesWinner() { public long getTotalRetriesError() { return data()._totalRetriesError; } - - @Override - public long getTotalDiscardedBytes() { - return data()._totalDiscardedBytes; - } - - @Override - public long getTotalRequestsSent() { - return data()._totalRequestsSent; - } - - @Override - public long getTotalRequestsReceived() { - return data()._totalRequestsReceived; - } - - @Override - public long getTotalRetriesOn503() { - return data()._total503Retries; - } - - @Override - public long getTotalRetriesOn503Winner() { - return data()._total503RetriesWinner; - } - - @Override - public long getTotalRetriesOn503Error() { - return data()._total503RetriesError; - } } diff --git a/internal/alpini/router/alpini-router-api/src/main/java/com/linkedin/alpini/router/monitoring/ScatterGatherStatsMBean.java b/internal/alpini/router/alpini-router-api/src/main/java/com/linkedin/alpini/router/monitoring/ScatterGatherStatsMBean.java index 5052fc58eda..0099f9a60da 100644 --- a/internal/alpini/router/alpini-router-api/src/main/java/com/linkedin/alpini/router/monitoring/ScatterGatherStatsMBean.java +++ b/internal/alpini/router/alpini-router-api/src/main/java/com/linkedin/alpini/router/monitoring/ScatterGatherStatsMBean.java @@ -8,23 +8,9 @@ public interface ScatterGatherStatsMBean { long getTotalRetriedKeys(); - long getTotalRetriedOn429(); - long getTotalRetriesDiscarded(); long getTotalRetriesWinner(); long getTotalRetriesError(); - - long getTotalDiscardedBytes(); - - long getTotalRequestsSent(); - - long getTotalRequestsReceived(); - - long getTotalRetriesOn503(); - - long getTotalRetriesOn503Winner(); - - long getTotalRetriesOn503Error(); } diff --git a/internal/alpini/router/alpini-router-api/src/test/java/com/linkedin/alpini/router/monitoring/TestScatterGatherStats.java b/internal/alpini/router/alpini-router-api/src/test/java/com/linkedin/alpini/router/monitoring/TestScatterGatherStats.java index 05a1235d7dc..e8141a54f8c 100644 --- a/internal/alpini/router/alpini-router-api/src/test/java/com/linkedin/alpini/router/monitoring/TestScatterGatherStats.java +++ b/internal/alpini/router/alpini-router-api/src/test/java/com/linkedin/alpini/router/monitoring/TestScatterGatherStats.java @@ -9,59 +9,32 @@ public class TestScatterGatherStats { public void testStats() { ScatterGatherStats stats = new ScatterGatherStats(); ScatterGatherStats.Delta delta = stats.new Delta(); - delta.incrementFanoutRequestsSent(3); delta.incrementTotalRetries(); delta.incrementTotalRetriedKeys(100); - delta.incrementTotalRequestsReceived(); - delta.incrementTotalRetriesDiscarded(1000); + delta.incrementTotalRetriesDiscarded(); delta.incrementTotalRetriesError(); delta.incrementTotalRetriesWinner(); - delta.incrementTotalRetriesOn429(); - delta.incrementTotalRetriesOn503(); - delta.incrementTotalRetriesOn503Winner(); - delta.incrementTotalRetriesOn503Error(); - Assert.assertEquals(stats.getTotalRequestsSent(), 0); Assert.assertEquals(stats.getTotalRetries(), 0); Assert.assertEquals(stats.getTotalRetriedKeys(), 0); - Assert.assertEquals(stats.getTotalRequestsReceived(), 0); Assert.assertEquals(stats.getTotalRetriesDiscarded(), 0); - Assert.assertEquals(stats.getTotalDiscardedBytes(), 0); Assert.assertEquals(stats.getTotalRetriesError(), 0); Assert.assertEquals(stats.getTotalRetriesWinner(), 0); - Assert.assertEquals(stats.getTotalRetriedOn429(), 0); - Assert.assertEquals(stats.getTotalRetriesOn503(), 0); - Assert.assertEquals(stats.getTotalRetriesOn503Winner(), 0); - Assert.assertEquals(stats.getTotalRetriesOn503Error(), 0); delta.apply(); - Assert.assertEquals(stats.getTotalRequestsSent(), 3); Assert.assertEquals(stats.getTotalRetries(), 1); Assert.assertEquals(stats.getTotalRetriedKeys(), 100); - Assert.assertEquals(stats.getTotalRequestsReceived(), 1); Assert.assertEquals(stats.getTotalRetriesDiscarded(), 1); - Assert.assertEquals(stats.getTotalDiscardedBytes(), 1000); Assert.assertEquals(stats.getTotalRetriesError(), 1); Assert.assertEquals(stats.getTotalRetriesWinner(), 1); - Assert.assertEquals(stats.getTotalRetriedOn429(), 1); - Assert.assertEquals(stats.getTotalRetriesOn503(), 1); - Assert.assertEquals(stats.getTotalRetriesOn503Winner(), 1); - Assert.assertEquals(stats.getTotalRetriesOn503Error(), 1); delta.apply(); - Assert.assertEquals(stats.getTotalRequestsSent(), 3); Assert.assertEquals(stats.getTotalRetries(), 1); Assert.assertEquals(stats.getTotalRetriedKeys(), 100); - Assert.assertEquals(stats.getTotalRequestsReceived(), 1); Assert.assertEquals(stats.getTotalRetriesDiscarded(), 1); - Assert.assertEquals(stats.getTotalDiscardedBytes(), 1000); Assert.assertEquals(stats.getTotalRetriesError(), 1); Assert.assertEquals(stats.getTotalRetriesWinner(), 1); - Assert.assertEquals(stats.getTotalRetriedOn429(), 1); - Assert.assertEquals(stats.getTotalRetriesOn503(), 1); - Assert.assertEquals(stats.getTotalRetriesOn503Winner(), 1); - Assert.assertEquals(stats.getTotalRetriesOn503Error(), 1); } } diff --git a/internal/alpini/router/alpini-router-base/src/main/java/com/linkedin/alpini/router/ScatterGatherRequestHandler4.java b/internal/alpini/router/alpini-router-base/src/main/java/com/linkedin/alpini/router/ScatterGatherRequestHandler4.java index 034a0a34934..cc674821c43 100644 --- a/internal/alpini/router/alpini-router-base/src/main/java/com/linkedin/alpini/router/ScatterGatherRequestHandler4.java +++ b/internal/alpini/router/alpini-router-base/src/main/java/com/linkedin/alpini/router/ScatterGatherRequestHandler4.java @@ -161,11 +161,6 @@ protected HttpResponseStatus gatewayTimeout() { return HttpResponseStatus.GATEWAY_TIMEOUT; } - @Override - protected HttpResponseStatus tooManyRequests() { - return HttpResponseStatus.TOO_MANY_REQUESTS; - } - @Override protected HttpResponseStatus serviceUnavailable() { return HttpResponseStatus.SERVICE_UNAVAILABLE; @@ -186,11 +181,6 @@ protected boolean isRequestRetriable(@Nonnull P path, @Nonnull R role, HttpRespo return getScatterGatherHelper().isRequestRetriable(path, role, httpResponseStatus); } - @Override - protected boolean isServiceUnavailable(HttpResponseStatus httpResponseStatus) { - return serviceUnavailable().equals(httpResponseStatus); - } - @Override protected String getReasonPhrase(HttpResponseStatus httpResponseStatus) { return httpResponseStatus.reasonPhrase(); diff --git a/internal/alpini/router/alpini-router-base/src/main/java/com/linkedin/alpini/router/ScatterGatherRequestHandlerImpl.java b/internal/alpini/router/alpini-router-base/src/main/java/com/linkedin/alpini/router/ScatterGatherRequestHandlerImpl.java index b203cf6d45b..e72954d4c85 100644 --- a/internal/alpini/router/alpini-router-base/src/main/java/com/linkedin/alpini/router/ScatterGatherRequestHandlerImpl.java +++ b/internal/alpini/router/alpini-router-base/src/main/java/com/linkedin/alpini/router/ScatterGatherRequestHandlerImpl.java @@ -154,11 +154,10 @@ private static void setFailure(AsyncPromise promise, Throwable cause, String } protected @Nonnull AsyncFuture
handler(@Nonnull CHC ctx, @Nonnull BHS request) throws Exception { - Metrics m = null; AsyncPromise
promise = AsyncFuture.deferred(false); try { LOG.debug("[{}] handler", request.getRequestId()); - final Metrics m2 = (m = _scatterGatherHelper.initializeMetrics(request)); // SUPPRESS CHECKSTYLE InnerAssignment + final Metrics m2 = _scatterGatherHelper.initializeMetrics(request); CompletableFuture.completedFuture(retainRequest(request)) .thenCompose(r -> handler0(ctx, m2, r)) .exceptionally(ex -> { @@ -244,8 +243,6 @@ private HR handlerException(@Nonnull BHS request, Metrics m, @Nonnull Throwable final @Nonnull ScatterGatherStats.Delta stats = (_scatterGatherHelper.getScatterGatherStatsByPath(path)).new Delta(); - stats.incrementTotalRequestsReceived(); - long requestTimeout = _scatterGatherHelper.getRequestTimeout(request.getRequestHeaders()); long requestDeadline = request.getRequestTimestamp() + requestTimeout; @@ -405,8 +402,6 @@ private HR handlerException(@Nonnull BHS request, Metrics m, @Nonnull Throwable } } - stats.incrementFanoutRequestsSent(scatter.getOnlineRequestCount()); - // We are done sending out requests... // We can decrement the reference count obtained before the call to handler0() releaseRequest(request); @@ -573,8 +568,6 @@ private boolean isQueryRequest(String uri) { protected abstract HRS gatewayTimeout(); - protected abstract HRS tooManyRequests(); - protected abstract HRS serviceUnavailable(); protected abstract HRS internalServerError(); @@ -583,8 +576,6 @@ private boolean isQueryRequest(String uri) { protected abstract boolean isRequestRetriable(P path, R role, HRS status); - protected abstract boolean isServiceUnavailable(HRS status); - protected abstract String getReasonPhrase(HRS status); protected @Nonnull BHS prepareRequest(@Nonnull BHS value) { @@ -769,14 +760,9 @@ private void prepareRetry(AsyncFuture retryFuture) { return; } - incrementTotalRetries(stats, retryStatus); + incrementTotalRetries(stats); stats.incrementTotalRetriedKeys(path.getPartitionKeys().size()); - if (HttpResponseStatus.TOO_MANY_REQUESTS.equals(retryStatus)) { - LOG.info("Long tail retry on TOO_MANY_REQUESTS for initial request {}", request); - stats.incrementTotalRetriesOn429(); - } - List>> responseFutures = new ArrayList<>(scatter.getOnlineRequestCount() + scatter.getOfflineRequestCount()); try { @@ -820,7 +806,7 @@ private void prepareRetry(AsyncFuture retryFuture) { AsyncFuture.collect(responseFutures, false).whenCompleteAsync((responses, failure) -> { if (failure != null) { - incrementTotalRetriesError(stats, retryStatus); + incrementTotalRetriesError(stats); if (lastAttempt) { setFailure(responseFuture, failure, "Retry failure"); } @@ -831,12 +817,12 @@ private void prepareRetry(AsyncFuture retryFuture) { && responses.stream().allMatch(r -> isSuccessStatus(statusOf(getResponseCode(r)))); if (!allSuccess) { - incrementTotalRetriesError(stats, retryStatus); + incrementTotalRetriesError(stats); } if ((lastAttempt || allSuccess) && responseFuture.setSuccess(responses)) { if (allSuccess) { - incrementTotalRetriesWinner(stats, retryStatus); + incrementTotalRetriesWinner(stats); } return; } @@ -844,7 +830,7 @@ private void prepareRetry(AsyncFuture retryFuture) { long contentBytes = responses.stream().mapToInt(ScatterGatherRequestHandlerImpl.this::getResponseReadable).sum(); releaseResponses(responses); - stats.incrementTotalRetriesDiscarded(contentBytes); + stats.incrementTotalRetriesDiscarded(); LOG.debug("Long tail response discarded, contentBytes={}", contentBytes); }, stageExecutor); } @@ -853,25 +839,16 @@ private void prepareRetry(AsyncFuture retryFuture) { }; } - protected void incrementTotalRetries(ScatterGatherStats.Delta stats, HRS responseStatus) { + protected void incrementTotalRetries(ScatterGatherStats.Delta stats) { stats.incrementTotalRetries(); - if (isServiceUnavailable(responseStatus)) { - stats.incrementTotalRetriesOn503(); - } } - protected void incrementTotalRetriesError(ScatterGatherStats.Delta stats, HRS responseStatus) { + protected void incrementTotalRetriesError(ScatterGatherStats.Delta stats) { stats.incrementTotalRetriesError(); - if (isServiceUnavailable(responseStatus)) { - stats.incrementTotalRetriesOn503Error(); - } } - protected void incrementTotalRetriesWinner(ScatterGatherStats.Delta stats, HRS responseStatus) { + protected void incrementTotalRetriesWinner(ScatterGatherStats.Delta stats) { stats.incrementTotalRetriesWinner(); - if (isServiceUnavailable(responseStatus)) { - stats.incrementTotalRetriesOn503Winner(); - } } protected abstract int getResponseCode(HR response); diff --git a/internal/alpini/router/alpini-router-base/src/test/java/com/linkedin/alpini/router/TestScatterGatherRequestHandlerImpl.java b/internal/alpini/router/alpini-router-base/src/test/java/com/linkedin/alpini/router/TestScatterGatherRequestHandlerImpl.java index ef362cf74f0..7a93e1d0894 100644 --- a/internal/alpini/router/alpini-router-base/src/test/java/com/linkedin/alpini/router/TestScatterGatherRequestHandlerImpl.java +++ b/internal/alpini/router/alpini-router-base/src/test/java/com/linkedin/alpini/router/TestScatterGatherRequestHandlerImpl.java @@ -176,11 +176,6 @@ protected Status gatewayTimeout() { return Status.GATEWAY_TIMEOUT; } - @Override - protected Status tooManyRequests() { - return Status.TOO_BUSY; - } - @Override protected Status serviceUnavailable() { return Status.SERVICE_UNAVAILABLE; @@ -202,11 +197,6 @@ protected boolean isRequestRetriable(@Nonnull P path, @Nonnull R role, @Nonnull return getScatterGatherHelper().isRequestRetriable(path, role, status); } - @Override - protected boolean isServiceUnavailable(Status status) { - return serviceUnavailable().equals(status); - } - @Override protected String getReasonPhrase(Status status) { return status._name; @@ -1802,30 +1792,24 @@ public void testIncrementTotalRetriesCounts() { ScatterGatherStats.Delta delta = stats.new Delta(); // 503 retry count will not increase if response status is not 503 - scatterGatherRequestHandler.incrementTotalRetries(delta, HttpResponseStatus.TOO_MANY_REQUESTS); - scatterGatherRequestHandler.incrementTotalRetriesWinner(delta, HttpResponseStatus.TOO_MANY_REQUESTS); - scatterGatherRequestHandler.incrementTotalRetriesError(delta, HttpResponseStatus.TOO_MANY_REQUESTS); + scatterGatherRequestHandler.incrementTotalRetries(delta); + scatterGatherRequestHandler.incrementTotalRetriesWinner(delta); + scatterGatherRequestHandler.incrementTotalRetriesError(delta); delta.apply(); Assert.assertEquals(stats.getTotalRetries(), 1); Assert.assertEquals(stats.getTotalRetriesWinner(), 1); Assert.assertEquals(stats.getTotalRetriesError(), 1); - Assert.assertEquals(stats.getTotalRetriesOn503(), 0); - Assert.assertEquals(stats.getTotalRetriesOn503Winner(), 0); - Assert.assertEquals(stats.getTotalRetriesOn503Error(), 0); // 503 retry count will increase if response status is 503 - scatterGatherRequestHandler.incrementTotalRetries(delta, HttpResponseStatus.SERVICE_UNAVAILABLE); - scatterGatherRequestHandler.incrementTotalRetriesWinner(delta, HttpResponseStatus.SERVICE_UNAVAILABLE); - scatterGatherRequestHandler.incrementTotalRetriesError(delta, HttpResponseStatus.SERVICE_UNAVAILABLE); + scatterGatherRequestHandler.incrementTotalRetries(delta); + scatterGatherRequestHandler.incrementTotalRetriesWinner(delta); + scatterGatherRequestHandler.incrementTotalRetriesError(delta); delta.apply(); Assert.assertEquals(stats.getTotalRetries(), 2); Assert.assertEquals(stats.getTotalRetriesWinner(), 2); Assert.assertEquals(stats.getTotalRetriesError(), 2); - Assert.assertEquals(stats.getTotalRetriesOn503(), 1); - Assert.assertEquals(stats.getTotalRetriesOn503Winner(), 1); - Assert.assertEquals(stats.getTotalRetriesOn503Error(), 1); } /** diff --git a/internal/alpini/router/alpini-router-impl/src/main/java/com/linkedin/alpini/router/impl/netty4/Router4PipelineFactory.java b/internal/alpini/router/alpini-router-impl/src/main/java/com/linkedin/alpini/router/impl/netty4/Router4PipelineFactory.java index fbae7919ebd..30ff93d03bd 100644 --- a/internal/alpini/router/alpini-router-impl/src/main/java/com/linkedin/alpini/router/impl/netty4/Router4PipelineFactory.java +++ b/internal/alpini/router/alpini-router-impl/src/main/java/com/linkedin/alpini/router/impl/netty4/Router4PipelineFactory.java @@ -4,7 +4,6 @@ import com.linkedin.alpini.netty4.handlers.ConnectionLimitHandler; import com.linkedin.alpini.netty4.handlers.Http2SettingsFrameLogger; import com.linkedin.alpini.netty4.http2.Http2PipelineInitializer; -import com.linkedin.alpini.netty4.misc.EventGroupLoopSupplier; import com.linkedin.alpini.netty4.misc.NettyUtils; import com.linkedin.alpini.router.ScatterGatherRequestHandler4; import com.linkedin.alpini.router.api.ResourcePath; @@ -83,15 +82,6 @@ public , K, R> Router4PipelineFactory( (ChannelHandler) entry.getSecond()))); } - void addLast(ChannelPipeline channelPipeline, String handlerName, ChannelHandler channelHandler) { - if (channelHandler instanceof EventGroupLoopSupplier) { - channelPipeline - .addLast(((EventGroupLoopSupplier) channelHandler).getEventLoopGroup(), handlerName, channelHandler); - } else { - channelPipeline.addLast(NettyUtils.executorGroup(channelPipeline), handlerName, channelHandler); - } - } - private Router4PipelineFactory add( List> list, Consumer pipelineConsumer) { diff --git a/internal/venice-client-common/src/main/java/com/linkedin/venice/utils/CollectionUtils.java b/internal/venice-client-common/src/main/java/com/linkedin/venice/utils/CollectionUtils.java index 5498c2c18a4..fcfc661f596 100644 --- a/internal/venice-client-common/src/main/java/com/linkedin/venice/utils/CollectionUtils.java +++ b/internal/venice-client-common/src/main/java/com/linkedin/venice/utils/CollectionUtils.java @@ -1,14 +1,22 @@ package com.linkedin.venice.utils; +import com.linkedin.alpini.base.misc.ImmutableMapEntry; import java.util.AbstractList; +import java.util.AbstractMap; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.RandomAccess; +import java.util.Set; +import javax.annotation.Nonnull; public class CollectionUtils { @@ -112,4 +120,92 @@ public static Map convertCharSequenceMapToStringMap(Map Map substituteEmptyMap(Map map) { return map == null || map.isEmpty() ? Collections.emptyMap() : map; } + + public static MapBuilder mapBuilder() { + return new MapBuilder<>(); + } + + public static Set setOf(T value) { + return Collections.singleton(value); + } + + @SafeVarargs + public static Set setOf(T... values) { + if (values == null || values.length == 0) { + return Collections.emptySet(); + } else if (values.length == 1) { + return setOf(values[0]); + } else { + return setOf(Arrays.asList(values)); + } + } + + public static Set setOf(Collection values) { + if (values == null || values.isEmpty()) { + return Collections.emptySet(); + } else { + return Collections.unmodifiableSet(new HashSet<>(values)); + } + } + + private static Map mapOfEntries(Set> entries) { + return Collections.unmodifiableMap(new HashMap<>(new AbstractMap() { + @Override + @Nonnull + public Set> entrySet() { + return entries; + } + })); + } + + public static final class MapBuilder extends CollectionBuilder, MapBuilder> { + private MapBuilder() { + } + + public MapBuilder put(K key, V value) { + return super.add(ImmutableMapEntry.make(key, value)); + } + + public MapBuilder putAll(Map values) { + return super.addAll(values.entrySet().stream().map(ImmutableMapEntry::make).iterator()); + } + + @SuppressWarnings("unchecked") + public Map build() { + List> list = (List>) (List) this._list; + return mapOfEntries(setOf(list)); + } + } + + private static class CollectionBuilder> { + protected LinkedList _list = new LinkedList<>(); + + private CollectionBuilder() { + } + + @SuppressWarnings("unchecked") + protected B self() { + return (B) this; + } + + public B add(@Nonnull T value) { + _list.add(Objects.requireNonNull(value)); + return self(); + } + + @SafeVarargs + public final B add(T... values) { + return addAll(Arrays.asList(values)); + } + + public B addAll(Collection values) { + _list.addAll(values); + return self(); + } + + public B addAll(Iterator values) { + values.forEachRemaining(this::add); + return self(); + } + } } diff --git a/internal/venice-client-common/src/test/java/com/linkedin/venice/compression/CompressionStrategyTest.java b/internal/venice-client-common/src/test/java/com/linkedin/venice/compression/CompressionStrategyTest.java index a8f54c296be..920ea2d278a 100644 --- a/internal/venice-client-common/src/test/java/com/linkedin/venice/compression/CompressionStrategyTest.java +++ b/internal/venice-client-common/src/test/java/com/linkedin/venice/compression/CompressionStrategyTest.java @@ -1,6 +1,6 @@ package com.linkedin.venice.compression; -import com.linkedin.alpini.base.misc.CollectionUtil; +import com.linkedin.venice.utils.CollectionUtils; import com.linkedin.venice.utils.VeniceEnumValueTest; import java.util.Map; @@ -12,7 +12,7 @@ public CompressionStrategyTest() { @Override protected Map expectedMapping() { - return CollectionUtil.mapBuilder() + return CollectionUtils.mapBuilder() .put(0, CompressionStrategy.NO_OP) .put(1, CompressionStrategy.GZIP) .put(2, CompressionStrategy.ZSTD) diff --git a/internal/venice-client-common/src/test/java/com/linkedin/venice/compute/protocol/request/enums/ComputeOperationTypeTest.java b/internal/venice-client-common/src/test/java/com/linkedin/venice/compute/protocol/request/enums/ComputeOperationTypeTest.java index b2f4568d7b9..c3951dbff86 100644 --- a/internal/venice-client-common/src/test/java/com/linkedin/venice/compute/protocol/request/enums/ComputeOperationTypeTest.java +++ b/internal/venice-client-common/src/test/java/com/linkedin/venice/compute/protocol/request/enums/ComputeOperationTypeTest.java @@ -1,6 +1,6 @@ package com.linkedin.venice.compute.protocol.request.enums; -import com.linkedin.alpini.base.misc.CollectionUtil; +import com.linkedin.venice.utils.CollectionUtils; import com.linkedin.venice.utils.VeniceEnumValueTest; import java.util.Map; @@ -12,7 +12,7 @@ public ComputeOperationTypeTest() { @Override protected Map expectedMapping() { - return CollectionUtil.mapBuilder() + return CollectionUtils.mapBuilder() .put(0, ComputeOperationType.DOT_PRODUCT) .put(1, ComputeOperationType.COSINE_SIMILARITY) .put(2, ComputeOperationType.HADAMARD_PRODUCT) diff --git a/internal/venice-client-common/src/test/java/com/linkedin/venice/pushmonitor/ExecutionStatusTest.java b/internal/venice-client-common/src/test/java/com/linkedin/venice/pushmonitor/ExecutionStatusTest.java index 6f2d1f5ce16..83807bd4012 100644 --- a/internal/venice-client-common/src/test/java/com/linkedin/venice/pushmonitor/ExecutionStatusTest.java +++ b/internal/venice-client-common/src/test/java/com/linkedin/venice/pushmonitor/ExecutionStatusTest.java @@ -17,7 +17,7 @@ import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; -import com.linkedin.alpini.base.misc.CollectionUtil; +import com.linkedin.venice.utils.CollectionUtils; import com.linkedin.venice.utils.VeniceEnumValueTest; import java.util.HashMap; import java.util.HashSet; @@ -34,7 +34,7 @@ public ExecutionStatusTest() { @Override protected Map expectedMapping() { - return CollectionUtil.mapBuilder() + return CollectionUtils.mapBuilder() .put(0, ExecutionStatus.NOT_CREATED) .put(1, ExecutionStatus.NEW) .put(2, ExecutionStatus.STARTED) diff --git a/internal/venice-client-common/src/test/java/com/linkedin/venice/utils/CollectionUtilsTest.java b/internal/venice-client-common/src/test/java/com/linkedin/venice/utils/CollectionUtilsTest.java index a44d6fc37eb..703d74966f6 100644 --- a/internal/venice-client-common/src/test/java/com/linkedin/venice/utils/CollectionUtilsTest.java +++ b/internal/venice-client-common/src/test/java/com/linkedin/venice/utils/CollectionUtilsTest.java @@ -7,11 +7,13 @@ import static org.testng.Assert.assertNotEquals; import static org.testng.Assert.assertTrue; +import com.linkedin.alpini.base.misc.ImmutableMapEntry; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import org.apache.avro.generic.GenericData; import org.testng.Assert; import org.testng.annotations.Test; @@ -165,4 +167,38 @@ public int hashCode() { return res; } } + + @Test + public void testMapBuilder() { + Map map = CollectionUtils.mapBuilder().build(); + Assert.assertEquals(map.size(), 0); + + map = CollectionUtils.mapBuilder().add(ImmutableMapEntry.make("TEST", 1)).build(); + Assert.assertEquals(map.size(), 1); + Assert.assertSame(map.get("TEST"), 1); + + map = CollectionUtils.mapBuilder() + .add(ImmutableMapEntry.make("TEST", 1)) + .add(ImmutableMapEntry.make("FOO", 2)) + .build(); + Assert.assertEquals(map.size(), 2); + Assert.assertSame(map.get("TEST"), 1); + Assert.assertSame(map.get("FOO"), 2); + } + + @Test + public void testSetOf0() { + Set set = CollectionUtils.setOf(Collections.emptyList()); + Assert.assertEquals(set.size(), 0); + + set = CollectionUtils.setOf(new String[0]); + Assert.assertEquals(set.size(), 0); + } + + @Test + public void testSetOf1() { + Set set = CollectionUtils.setOf("TEST"); + Assert.assertEquals(set.size(), 1); + Assert.assertTrue(set.contains("TEST")); + } } diff --git a/internal/venice-common/src/test/java/com/linkedin/venice/PushJobCheckPointsTest.java b/internal/venice-common/src/test/java/com/linkedin/venice/PushJobCheckPointsTest.java index eb282b63528..eae2863e9e7 100644 --- a/internal/venice-common/src/test/java/com/linkedin/venice/PushJobCheckPointsTest.java +++ b/internal/venice-common/src/test/java/com/linkedin/venice/PushJobCheckPointsTest.java @@ -3,7 +3,7 @@ import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; -import com.linkedin.alpini.base.misc.CollectionUtil; +import com.linkedin.venice.utils.CollectionUtils; import com.linkedin.venice.utils.VeniceEnumValueTest; import java.util.Map; import org.testng.annotations.Test; @@ -16,7 +16,7 @@ public PushJobCheckPointsTest() { @Override protected Map expectedMapping() { - return CollectionUtil.mapBuilder() + return CollectionUtils.mapBuilder() .put(0, PushJobCheckpoints.INITIALIZE_PUSH_JOB) .put(1, PushJobCheckpoints.NEW_VERSION_CREATED) .put(2, PushJobCheckpoints.START_DATA_WRITER_JOB) diff --git a/internal/venice-common/src/test/java/com/linkedin/venice/helix/HelixReadOnlySchemaRepositoryTest.java b/internal/venice-common/src/test/java/com/linkedin/venice/helix/HelixReadOnlySchemaRepositoryTest.java index ca90c15a6d4..fb34966b7d8 100644 --- a/internal/venice-common/src/test/java/com/linkedin/venice/helix/HelixReadOnlySchemaRepositoryTest.java +++ b/internal/venice-common/src/test/java/com/linkedin/venice/helix/HelixReadOnlySchemaRepositoryTest.java @@ -14,7 +14,6 @@ import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertThrows; -import com.linkedin.alpini.io.IOUtils; import com.linkedin.avroutil1.compatibility.AvroCompatibilityHelper; import com.linkedin.venice.exceptions.InvalidVeniceSchemaException; import com.linkedin.venice.exceptions.VeniceNoStoreException; @@ -27,22 +26,18 @@ import com.linkedin.venice.schema.writecompute.DerivedSchemaEntry; import com.linkedin.venice.schema.writecompute.WriteComputeSchemaConverter; import com.linkedin.venice.utils.DataProviderUtils; +import com.linkedin.venice.utils.TestUtils; import com.linkedin.venice.utils.concurrent.VeniceConcurrentHashMap; -import com.linkedin.venice.writer.update.UpdateBuilderImplTest; -import java.nio.charset.StandardCharsets; import java.time.Duration; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import org.apache.avro.Schema; import org.apache.helix.zookeeper.impl.client.ZkClient; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; @@ -50,10 +45,8 @@ public class HelixReadOnlySchemaRepositoryTest { - private static final Logger LOGGER = LogManager.getLogger(UpdateBuilderImplTest.class); - private static final Schema VALUE_SCHEMA = - AvroCompatibilityHelper.parse(loadFileAsString("TestWriteComputeBuilder.avsc")); + AvroCompatibilityHelper.parse(TestUtils.loadFileAsString("TestWriteComputeBuilder.avsc")); private static final Schema UPDATE_SCHEMA = WriteComputeSchemaConverter.getInstance().convertFromValueRecordSchema(VALUE_SCHEMA); @@ -234,15 +227,4 @@ public void testSchemaDeletion() { listener.handleSchemaChanges(storeName, list); verify(accessor, times(1)).getValueSchema(anyString(), anyString()); } - - private static String loadFileAsString(String fileName) { - try { - return IOUtils.toString( - Objects.requireNonNull(Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName)), - StandardCharsets.UTF_8); - } catch (Exception e) { - LOGGER.error(e); - return null; - } - } } diff --git a/internal/venice-common/src/test/java/com/linkedin/venice/kafka/protocol/enums/ControlMessageTypeTest.java b/internal/venice-common/src/test/java/com/linkedin/venice/kafka/protocol/enums/ControlMessageTypeTest.java index d7f84865847..c5f3d48c1be 100644 --- a/internal/venice-common/src/test/java/com/linkedin/venice/kafka/protocol/enums/ControlMessageTypeTest.java +++ b/internal/venice-common/src/test/java/com/linkedin/venice/kafka/protocol/enums/ControlMessageTypeTest.java @@ -1,6 +1,6 @@ package com.linkedin.venice.kafka.protocol.enums; -import com.linkedin.alpini.base.misc.CollectionUtil; +import com.linkedin.venice.utils.CollectionUtils; import com.linkedin.venice.utils.VeniceEnumValueTest; import java.util.Map; @@ -12,7 +12,7 @@ public ControlMessageTypeTest() { @Override protected Map expectedMapping() { - return CollectionUtil.mapBuilder() + return CollectionUtils.mapBuilder() .put(0, ControlMessageType.START_OF_PUSH) .put(1, ControlMessageType.END_OF_PUSH) .put(2, ControlMessageType.START_OF_SEGMENT) diff --git a/internal/venice-common/src/test/java/com/linkedin/venice/kafka/protocol/enums/MessageTypeTest.java b/internal/venice-common/src/test/java/com/linkedin/venice/kafka/protocol/enums/MessageTypeTest.java index 2477b2ef839..800f3b0b5e2 100644 --- a/internal/venice-common/src/test/java/com/linkedin/venice/kafka/protocol/enums/MessageTypeTest.java +++ b/internal/venice-common/src/test/java/com/linkedin/venice/kafka/protocol/enums/MessageTypeTest.java @@ -1,6 +1,6 @@ package com.linkedin.venice.kafka.protocol.enums; -import com.linkedin.alpini.base.misc.CollectionUtil; +import com.linkedin.venice.utils.CollectionUtils; import com.linkedin.venice.utils.VeniceEnumValueTest; import java.util.Map; @@ -12,7 +12,7 @@ public MessageTypeTest() { @Override protected Map expectedMapping() { - return CollectionUtil.mapBuilder() + return CollectionUtils.mapBuilder() .put(0, MessageType.PUT) .put(1, MessageType.DELETE) .put(2, MessageType.CONTROL_MESSAGE) diff --git a/internal/venice-common/src/test/java/com/linkedin/venice/status/TestPushJobDetailsStatus.java b/internal/venice-common/src/test/java/com/linkedin/venice/status/TestPushJobDetailsStatus.java index 1941c315f69..a1f0b89eb40 100644 --- a/internal/venice-common/src/test/java/com/linkedin/venice/status/TestPushJobDetailsStatus.java +++ b/internal/venice-common/src/test/java/com/linkedin/venice/status/TestPushJobDetailsStatus.java @@ -8,7 +8,7 @@ import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; -import com.linkedin.alpini.base.misc.CollectionUtil; +import com.linkedin.venice.utils.CollectionUtils; import com.linkedin.venice.utils.VeniceEnumValueTest; import java.util.Map; import org.testng.annotations.Test; @@ -21,7 +21,7 @@ public TestPushJobDetailsStatus() { @Override protected Map expectedMapping() { - return CollectionUtil.mapBuilder() + return CollectionUtils.mapBuilder() .put(0, PushJobDetailsStatus.STARTED) .put(1, PushJobDetailsStatus.COMPLETED) .put(2, PushJobDetailsStatus.ERROR) diff --git a/internal/venice-common/src/test/java/com/linkedin/venice/system/store/MetaStoreDataTypeTest.java b/internal/venice-common/src/test/java/com/linkedin/venice/system/store/MetaStoreDataTypeTest.java index fd6db7adbcd..04a9cba4f1d 100644 --- a/internal/venice-common/src/test/java/com/linkedin/venice/system/store/MetaStoreDataTypeTest.java +++ b/internal/venice-common/src/test/java/com/linkedin/venice/system/store/MetaStoreDataTypeTest.java @@ -1,6 +1,6 @@ package com.linkedin.venice.system.store; -import com.linkedin.alpini.base.misc.CollectionUtil; +import com.linkedin.venice.utils.CollectionUtils; import com.linkedin.venice.utils.VeniceEnumValueTest; import java.util.Map; @@ -12,7 +12,7 @@ public MetaStoreDataTypeTest() { @Override protected Map expectedMapping() { - return CollectionUtil.mapBuilder() + return CollectionUtils.mapBuilder() .put(0, MetaStoreDataType.STORE_PROPERTIES) .put(1, MetaStoreDataType.STORE_KEY_SCHEMAS) .put(2, MetaStoreDataType.STORE_VALUE_SCHEMAS) diff --git a/internal/venice-common/src/test/java/com/linkedin/venice/writer/LeaderCompleteStateTest.java b/internal/venice-common/src/test/java/com/linkedin/venice/writer/LeaderCompleteStateTest.java index fd66d6643e3..aaf84bdfa0f 100644 --- a/internal/venice-common/src/test/java/com/linkedin/venice/writer/LeaderCompleteStateTest.java +++ b/internal/venice-common/src/test/java/com/linkedin/venice/writer/LeaderCompleteStateTest.java @@ -1,6 +1,6 @@ package com.linkedin.venice.writer; -import com.linkedin.alpini.base.misc.CollectionUtil; +import com.linkedin.venice.utils.CollectionUtils; import com.linkedin.venice.utils.VeniceEnumValueTest; import java.util.Map; @@ -12,7 +12,7 @@ public LeaderCompleteStateTest() { @Override protected Map expectedMapping() { - return CollectionUtil.mapBuilder() + return CollectionUtils.mapBuilder() .put(0, LeaderCompleteState.LEADER_NOT_COMPLETED) .put(1, LeaderCompleteState.LEADER_COMPLETED) .build(); diff --git a/internal/venice-common/src/test/java/com/linkedin/venice/writer/update/UpdateBuilderImplTest.java b/internal/venice-common/src/test/java/com/linkedin/venice/writer/update/UpdateBuilderImplTest.java index 7387dcad4af..d1cfa100497 100644 --- a/internal/venice-common/src/test/java/com/linkedin/venice/writer/update/UpdateBuilderImplTest.java +++ b/internal/venice-common/src/test/java/com/linkedin/venice/writer/update/UpdateBuilderImplTest.java @@ -4,20 +4,18 @@ import static org.testng.Assert.assertNull; import static org.testng.Assert.assertTrue; -import com.linkedin.alpini.io.IOUtils; import com.linkedin.avroutil1.compatibility.AvroCompatibilityHelper; import com.linkedin.venice.exceptions.VeniceException; import com.linkedin.venice.schema.writecompute.WriteComputeSchemaConverter; import com.linkedin.venice.serialization.avro.VeniceAvroKafkaSerializer; import com.linkedin.venice.serializer.VeniceSerializationException; -import java.nio.charset.StandardCharsets; +import com.linkedin.venice.utils.TestUtils; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import org.apache.avro.Schema; import org.apache.avro.generic.GenericData; import org.apache.avro.generic.GenericRecord; @@ -30,9 +28,9 @@ public class UpdateBuilderImplTest { private static final Logger LOGGER = LogManager.getLogger(UpdateBuilderImplTest.class); private static final Schema VALUE_SCHEMA = - AvroCompatibilityHelper.parse(loadFileAsString("TestWriteComputeBuilder.avsc")); + AvroCompatibilityHelper.parse(TestUtils.loadFileAsString("TestWriteComputeBuilder.avsc")); private static final Schema EVOLVED_VALUE_SCHEMA = - AvroCompatibilityHelper.parse(loadFileAsString("TestEvolvedWriteComputeBuilder.avsc")); + AvroCompatibilityHelper.parse(TestUtils.loadFileAsString("TestEvolvedWriteComputeBuilder.avsc")); private static final Schema UPDATE_SCHEMA = WriteComputeSchemaConverter.getInstance().convertFromValueRecordSchema(VALUE_SCHEMA); private static final Schema EVOLVED_UPDATE_SCHEMA = @@ -472,15 +470,4 @@ private GenericRecord createFieldNoOpRecord(String fieldName) { Schema noOpSchema = UPDATE_SCHEMA.getField(fieldName).schema().getTypes().get(0); return new GenericData.Record(noOpSchema); } - - private static String loadFileAsString(String fileName) { - try { - return IOUtils.toString( - Objects.requireNonNull(Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName)), - StandardCharsets.UTF_8); - } catch (Exception e) { - LOGGER.error(e); - return null; - } - } } diff --git a/internal/venice-test-common/src/integrationTest/java/com/linkedin/venice/endToEnd/TestActiveActiveReplicationForIncPush.java b/internal/venice-test-common/src/integrationTest/java/com/linkedin/venice/endToEnd/TestActiveActiveReplicationForIncPush.java index 7c1f072a326..b50bc298565 100644 --- a/internal/venice-test-common/src/integrationTest/java/com/linkedin/venice/endToEnd/TestActiveActiveReplicationForIncPush.java +++ b/internal/venice-test-common/src/integrationTest/java/com/linkedin/venice/endToEnd/TestActiveActiveReplicationForIncPush.java @@ -39,7 +39,6 @@ import com.linkedin.venice.pubsub.PubSubTopicRepository; import com.linkedin.venice.pubsub.api.PubSubTopicPartition; import com.linkedin.venice.pubsub.manager.TopicManager; -import com.linkedin.venice.utils.DataProviderUtils; import com.linkedin.venice.utils.IntegrationTestPushUtils; import com.linkedin.venice.utils.TestUtils; import com.linkedin.venice.utils.TestWriteUtils; @@ -123,12 +122,23 @@ public void cleanUp() { multiRegionMultiClusterWrapper.close(); } + @Test(timeOut = TEST_TIMEOUT) + public void testAAReplicationForIncPushWithSeparateRT() throws Exception { + // TODO: Remove this hack if we solve the test-retry plugin's flakiness with DataProviders + testAAReplicationForIncPush(true); + } + + @Test(timeOut = TEST_TIMEOUT) + public void testAAReplicationForIncPush() throws Exception { + // TODO: Remove this hack if we solve the test-retry plugin's flakiness with DataProviders + testAAReplicationForIncPush(false); + } + /** * The purpose of this test is to verify that incremental push with RT policy succeeds when A/A is enabled in all * regions. And also incremental push can push to the closes kafka cluster from the grid using the SOURCE_GRID_CONFIG. */ - @Test(timeOut = TEST_TIMEOUT, dataProvider = "True-and-False", dataProviderClass = DataProviderUtils.class) - public void testAAReplicationForIncrementalPushToRT(boolean isSeparateRealTimeTopicEnabled) throws Exception { + private void testAAReplicationForIncPush(boolean isSeparateRealTimeTopicEnabled) throws Exception { File inputDirBatch = getTempDataDirectory(); File inputDirInc1 = getTempDataDirectory(); File inputDirInc2 = getTempDataDirectory(); diff --git a/services/venice-router/src/main/java/com/linkedin/venice/router/stats/RouterHttpRequestStats.java b/services/venice-router/src/main/java/com/linkedin/venice/router/stats/RouterHttpRequestStats.java index 4e927c32ab9..ed9debd11ce 100644 --- a/services/venice-router/src/main/java/com/linkedin/venice/router/stats/RouterHttpRequestStats.java +++ b/services/venice-router/src/main/java/com/linkedin/venice/router/stats/RouterHttpRequestStats.java @@ -24,7 +24,6 @@ import static com.linkedin.venice.stats.dimensions.VeniceMetricsDimensions.VENICE_STORE_NAME; import static java.util.Collections.singletonList; -import com.linkedin.alpini.base.misc.CollectionUtil; import com.linkedin.alpini.router.monitoring.ScatterGatherStats; import com.linkedin.venice.common.VeniceSystemStoreUtils; import com.linkedin.venice.read.RequestType; @@ -42,6 +41,7 @@ import com.linkedin.venice.stats.dimensions.VeniceResponseStatusCategory; import com.linkedin.venice.stats.metrics.MetricEntityState; import com.linkedin.venice.stats.metrics.TehutiMetricNameEnum; +import com.linkedin.venice.utils.CollectionUtils; import io.netty.handler.codec.http.HttpResponseStatus; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.AttributesBuilder; @@ -177,7 +177,7 @@ public RouterHttpRequestStats( INCOMING_CALL_COUNT.getMetricEntity(), otelRepository, this::registerSensorFinal, - CollectionUtil.>mapBuilder() + CollectionUtils.>mapBuilder() .put(RouterTehutiMetricNameEnum.REQUEST, Arrays.asList(new Count(), requestRate)) .build()); @@ -190,7 +190,7 @@ public RouterHttpRequestStats( CALL_COUNT.getMetricEntity(), otelRepository, this::registerSensorFinal, - CollectionUtil.>mapBuilder() + CollectionUtils.>mapBuilder() .put(RouterTehutiMetricNameEnum.HEALTHY_REQUEST, Arrays.asList(new Count(), healthyRequestRate)) .put(RouterTehutiMetricNameEnum.UNHEALTHY_REQUEST, singletonList(new Count())) .put(RouterTehutiMetricNameEnum.TARDY_REQUEST, Arrays.asList(new Count(), tardyRequestRate)) @@ -203,7 +203,7 @@ public RouterHttpRequestStats( CALL_TIME.getMetricEntity(), otelRepository, this::registerSensorFinal, - CollectionUtil.>mapBuilder() + CollectionUtils.>mapBuilder() .put( RouterTehutiMetricNameEnum.HEALTHY_REQUEST_LATENCY, Arrays.asList( @@ -221,7 +221,7 @@ public RouterHttpRequestStats( RETRY_COUNT.getMetricEntity(), otelRepository, this::registerSensorFinal, - CollectionUtil.>mapBuilder() + CollectionUtils.>mapBuilder() .put(RouterTehutiMetricNameEnum.ERROR_RETRY, singletonList(new Count())) .build()); @@ -229,7 +229,7 @@ public RouterHttpRequestStats( ALLOWED_RETRY_COUNT.getMetricEntity(), otelRepository, this::registerSensorFinal, - CollectionUtil.>mapBuilder() + CollectionUtils.>mapBuilder() .put(RouterTehutiMetricNameEnum.ALLOWED_RETRY_REQUEST_COUNT, singletonList(new OccurrenceRate())) .build()); @@ -237,7 +237,7 @@ public RouterHttpRequestStats( DISALLOWED_RETRY_COUNT.getMetricEntity(), otelRepository, this::registerSensorFinal, - CollectionUtil.>mapBuilder() + CollectionUtils.>mapBuilder() .put(RouterTehutiMetricNameEnum.DISALLOWED_RETRY_REQUEST_COUNT, singletonList(new OccurrenceRate())) .build()); @@ -245,7 +245,7 @@ public RouterHttpRequestStats( RETRY_DELAY.getMetricEntity(), otelRepository, this::registerSensorFinal, - CollectionUtil.>mapBuilder() + CollectionUtils.>mapBuilder() .put(RouterTehutiMetricNameEnum.RETRY_DELAY, Arrays.asList(new Avg(), new Max())) .build()); @@ -253,7 +253,7 @@ public RouterHttpRequestStats( ABORTED_RETRY_COUNT.getMetricEntity(), otelRepository, this::registerSensorFinal, - CollectionUtil.>mapBuilder() + CollectionUtils.>mapBuilder() .put(RouterTehutiMetricNameEnum.DELAY_CONSTRAINT_ABORTED_RETRY_REQUEST, singletonList(new Count())) .put(RouterTehutiMetricNameEnum.SLOW_ROUTE_ABORTED_RETRY_REQUEST, singletonList(new Count())) .put(RouterTehutiMetricNameEnum.RETRY_ROUTE_LIMIT_ABORTED_RETRY_REQUEST, singletonList(new Count())) @@ -264,7 +264,7 @@ public RouterHttpRequestStats( CALL_KEY_COUNT.getMetricEntity(), otelRepository, this::registerSensorFinal, - CollectionUtil.>mapBuilder() + CollectionUtils.>mapBuilder() .put(RouterTehutiMetricNameEnum.KEY_NUM, Arrays.asList(new OccurrenceRate(), new Avg(), new Max(0))) .put( RouterTehutiMetricNameEnum.BAD_REQUEST_KEY_COUNT, diff --git a/settings.gradle b/settings.gradle index e9eeebc98f6..7a52d4739f3 100644 --- a/settings.gradle +++ b/settings.gradle @@ -57,12 +57,7 @@ include 'internal:venice-test-common' // Alpini modules include 'internal:alpini:common:alpini-common-base' -include 'internal:alpini:common:alpini-common-cli' -include 'internal:alpini:common:alpini-common-const' include 'internal:alpini:common:alpini-common-io' -include 'internal:alpini:common:alpini-common-log' -include 'internal:alpini:common:alpini-common-native' -include 'internal:alpini:common:alpini-common-test' include 'internal:alpini:netty4:alpini-netty4-base' include 'internal:alpini:router:alpini-router-api' include 'internal:alpini:router:alpini-router-base'