Skip to content

Commit

Permalink
Merge branch 'main' into allow-distribution-config-customization
Browse files Browse the repository at this point in the history
  • Loading branch information
ikhoon committed Aug 14, 2023
2 parents ff7fae8 + b2e31ee commit 337c09c
Show file tree
Hide file tree
Showing 22 changed files with 618 additions and 108 deletions.
4 changes: 4 additions & 0 deletions core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ mrJarVersions.each { version->
testClassesDirs = sourceSets."java${version}Test".output.classesDirs
classpath = sourceSets."java${version}Test".runtimeClasspath

useJUnitPlatform()
project.ext.configureCommonTestSettings(it)
enabled = project.ext.testJavaVersion >= targetJavaVersion
}
Expand Down Expand Up @@ -94,6 +95,9 @@ dependencies {
api libs.jackson.datatype.jdk8
api libs.jackson.datatype.jsr310

// Logback is only used for RequestScopedMdc integration.
compileOnly libs.logback14

// Micrometer and other metric-related stuff
api libs.micrometer.core
optionalApi libs.micrometer.prometheus
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -527,8 +527,7 @@ protected final Consumer<DnsNameResolverBuilder> buildConfigurator(EventLoopGrou
builder.queryTimeoutMillis(queryTimeoutMillisForEachAttempt);
} else {
if (queryTimeoutMillis == 0 || queryTimeoutMillis == Long.MAX_VALUE) {
// Use 0 to disable the timeout once https://github.com/netty/netty/pull/13505 is merged.
builder.queryTimeoutMillis(3600000); // 1 hour
builder.queryTimeoutMillis(0);
} else {
builder.queryTimeoutMillis(queryTimeoutMillis);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,20 @@ public interface AggregatedHttpObject {
HttpData content();

/**
* Returns the content of this message as a string encoded in the specified {@link Charset}.
* Returns the content decoded in the {@link Charset} of the {@code content-type} header if present,
* or the content decoded in the specified {@link Charset} otherwise.
*/
default String content(Charset charset) {
final MediaType contentType = headers().contentType();

if (contentType != null) {
final Charset contentTypeCharset = contentType.charset();

if (contentTypeCharset != null) {
return content().toString(contentTypeCharset);
}
}

return content().toString(charset);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* Copyright 2023 LINE Corporation
*
* LINE Corporation 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 com.linecorp.armeria.common.logging;

import java.lang.reflect.Field;
import java.util.Deque;
import java.util.Map;

import org.slf4j.LoggerFactory;
import org.slf4j.spi.MDCAdapter;

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.util.LogbackMDCAdapter;

final class DelegatingLogbackMDCAdapter extends LogbackMDCAdapter {

static void maybeUpdateMdcAdapter(MDCAdapter adapter) {
final Logger rootLogger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
final LoggerContext loggerContext = rootLogger.getLoggerContext();
final Field mdcAdapter;
try {
mdcAdapter = LoggerContext.class.getDeclaredField("mdcAdapter");
mdcAdapter.setAccessible(true);
mdcAdapter.set(loggerContext, new DelegatingLogbackMDCAdapter(adapter));
} catch (NoSuchFieldException | IllegalAccessException e) {
// Maybe Logback 1.4.7 or earlier. LoggerContext#mdcAdapter is added in Logback 1.4.8
// https://github.com/qos-ch/logback/commit/ca7fbc7f4c1b1883092037ee4a662034586df07a#diff-1158785ec39613a90566e0290fa18a453340eb54352f678f5a25f2857289b4e4
}
}

private final MDCAdapter delegate;

private DelegatingLogbackMDCAdapter(MDCAdapter delegate) {
this.delegate = delegate;
}

@Override
public void put(String key, String val) {
delegate.put(key, val);
}

@Override
public String get(String key) {
return delegate.get(key);
}

@Override
public void remove(String key) {
delegate.remove(key);
}

@Override
public void clear() {
delegate.clear();
}

@Override
public Map<String, String> getPropertyMap() {
return delegate.getCopyOfContextMap();
}

@Override
public Map getCopyOfContextMap() {
return delegate.getCopyOfContextMap();
}

@Override
public void setContextMap(Map contextMap) {
delegate.setContextMap(contextMap);
}

@Override
public void pushByKey(String key, String value) {
delegate.pushByKey(key, value);
}

@Override
public String popByKey(String key) {
return delegate.popByKey(key);
}

@Override
public Deque<String> getCopyOfDequeByKey(String key) {
return delegate.getCopyOfDequeByKey(key);
}

@Override
public void clearDequeByKey(String key) {
delegate.clearDequeByKey(key);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Field;
import java.util.Deque;
import java.util.Map;

import org.slf4j.Logger;
Expand Down Expand Up @@ -119,7 +120,13 @@ public final class RequestScopedMdc {
final Field mdcAdapterField = MDC.class.getDeclaredField("mdcAdapter");
mdcAdapterField.setAccessible(true);
oldAdapter = (MDCAdapter) mdcAdapterField.get(null);
mdcAdapterField.set(null, new Adapter(oldAdapter));
final MDCAdapter newAdapter = new Adapter(oldAdapter);
mdcAdapterField.set(null, newAdapter);

if ("ch.qos.logback.classic.util.LogbackMDCAdapter".equals(oldAdapter.getClass().getName())) {
// Since Logback 1.4.8, LoggingEvent does not directly use MDC.getMDCAdapter().
DelegatingLogbackMDCAdapter.maybeUpdateMdcAdapter(newAdapter);
}
} catch (Throwable t) {
oldAdapter = null;
logger.warn(ERROR_MESSAGE, t);
Expand Down Expand Up @@ -447,5 +454,23 @@ public void clear() {
public void setContextMap(Map<String, String> contextMap) {
delegate.setContextMap(contextMap);
}

// Methods added in SLF4J 2.0.0

public void pushByKey(String key, String value) {
delegate.pushByKey(key, value);
}

public String popByKey(String key) {
return delegate.popByKey(key);
}

public Deque<String> getCopyOfDequeByKey(String key) {
return delegate.getCopyOfDequeByKey(key);
}

public void clearDequeByKey(String key) {
delegate.clearDequeByKey(key);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,11 @@ assert keepAliveHandler() instanceof Http2ServerKeepAliveHandler ||
@Override
public ChannelFuture doWriteHeaders(int id, int streamId, ResponseHeaders headers, boolean endStream,
boolean isTrailersEmpty) {
if (!isStreamPresentAndWritable(streamId)) {
if (!isStreamPresentAndWritable(streamId) || isResponseHeadersSent(id, streamId)) {
// One of the following cases:
// - Stream has been closed already.
// - (bug) Server tried to send a response HEADERS frame before receiving a request HEADERS frame.
// - Server tried to send a response HEADERS frame twice.
return newFailedFuture(ClosedStreamException.get());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5154,7 +5154,6 @@ musica.bo
musician.io
mutsu.aomori.jp
mutsuzawa.chiba.jp
mutual
mutual.ar
mv
mw
Expand Down Expand Up @@ -5691,7 +5690,6 @@ nordre-land.no
nordreisa.no
nore-og-uvdal.no
north-kazakhstan.su
northwesternmutual
norton
nose.osaka.jp
nosegawa.nara.jp
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright 2023 LINE Corporation
*
* LINE Corporation 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 com.linecorp.armeria.common;

import static org.assertj.core.api.Assertions.assertThat;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import org.junit.jupiter.api.Test;

class AggregatedHttpObjectTest {

@Test
void testDecodingContentCorrectly() {
final RequestHeaders headers = RequestHeaders.of(
HttpMethod.GET, "/",
HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=utf-8");
final HttpData httpData = HttpData.of(StandardCharsets.UTF_8, "foo");

final AggregatedHttpRequest request = AggregatedHttpRequest.of(headers, httpData);

final Charset contentTypeCharset = request.headers().contentType().charset();

assertThat(contentTypeCharset).isEqualTo(StandardCharsets.UTF_8);
assertThat(request.content(StandardCharsets.UTF_16BE)).isEqualTo("foo");
assertThat(request.content(StandardCharsets.UTF_8)).isEqualTo("foo");
}

@Test
void testDecodingContentCorrectlyWhenContentTypeIsNull() {
final RequestHeaders headers = RequestHeaders.of(
HttpMethod.GET, "/");
final HttpData httpData = HttpData.of(StandardCharsets.UTF_8, "foo");

final AggregatedHttpRequest request = AggregatedHttpRequest.of(headers, httpData);

assertThat(request.content(StandardCharsets.UTF_16BE)).isNotEqualTo("foo");
assertThat(request.content(StandardCharsets.UTF_8)).isEqualTo("foo");
}
}

0 comments on commit 337c09c

Please sign in to comment.