fix: Mattermost REST 클라이언트의 HTTP/1.1 고정을 테스트 전용으로 분리
WireMock(Jetty)의 h2c 업그레이드 협상 문제를 회피하려던 HTTP/1.1 고정이 운영 코드(RestClient)에 들어가 있어 실제로는 HTTPS/ALPN으로 협상하는 운영 전송 계층까지 불필요하게 좁히고 있었다. 전송 설정을 주입 가능한 생성자로 분리해 운영 생성자는 프레임워크 기본값을 쓰고, 테스트만 HTTP/1.1을 고정하도록 수정했다.
@b1ad537477470b323b942b95359298bc8d12a51c
--- src/main/java/kr/itn/itnhub/mattermost/MattermostRestClient.java
+++ src/main/java/kr/itn/itnhub/mattermost/MattermostRestClient.java
... | ... | @@ -3,12 +3,10 @@ |
| 3 | 3 |
import com.fasterxml.jackson.databind.JsonNode; |
| 4 | 4 |
import kr.itn.itnhub.config.MattermostProperties; |
| 5 | 5 |
import org.springframework.http.MediaType; |
| 6 |
-import org.springframework.http.client.JdkClientHttpRequestFactory; |
|
| 7 | 6 |
import org.springframework.stereotype.Component; |
| 8 | 7 |
import org.springframework.web.client.RestClient; |
| 9 | 8 |
import org.springframework.web.client.RestClientException; |
| 10 | 9 |
|
| 11 |
-import java.net.http.HttpClient; |
|
| 12 | 10 |
import java.util.LinkedHashMap; |
| 13 | 11 |
import java.util.Map; |
| 14 | 12 |
import java.util.Optional; |
... | ... | @@ -20,15 +18,17 @@ |
| 20 | 18 |
private final String teamId; |
| 21 | 19 |
|
| 22 | 20 |
public MattermostRestClient(MattermostProperties props) {
|
| 21 |
+ this(props, RestClient.builder()); |
|
| 22 |
+ } |
|
| 23 |
+ |
|
| 24 |
+ /** |
|
| 25 |
+ * 전송 계층(transport)을 직접 지정할 수 있는 생성자. 운영 코드에서는 사용하지 않으며, |
|
| 26 |
+ * 테스트 등 별도의 {@link RestClient.Builder} 설정이 필요한 호출자를 위한 확장 지점이다.
|
|
| 27 |
+ */ |
|
| 28 |
+ MattermostRestClient(MattermostProperties props, RestClient.Builder builder) {
|
|
| 23 | 29 |
this.teamId = props.teamId(); |
| 24 |
- // JDK HttpClient의 기본 HTTP/2 h2c 업그레이드 협상이 WireMock(Jetty) 상대로 |
|
| 25 |
- // POST 요청에서 간헐적으로 RST_STREAM을 유발해 HTTP/1.1로 고정한다. |
|
| 26 |
- HttpClient httpClient = HttpClient.newBuilder() |
|
| 27 |
- .version(HttpClient.Version.HTTP_1_1) |
|
| 28 |
- .build(); |
|
| 29 |
- this.rest = RestClient.builder() |
|
| 30 |
+ this.rest = builder |
|
| 30 | 31 |
.baseUrl(props.baseUrl()) |
| 31 |
- .requestFactory(new JdkClientHttpRequestFactory(httpClient)) |
|
| 32 | 32 |
.defaultHeader("Authorization", "Bearer " + props.token())
|
| 33 | 33 |
.build(); |
| 34 | 34 |
} |
--- src/test/java/kr/itn/itnhub/mattermost/MattermostRestClientTest.java
+++ src/test/java/kr/itn/itnhub/mattermost/MattermostRestClientTest.java
... | ... | @@ -5,6 +5,10 @@ |
| 5 | 5 |
import org.junit.jupiter.api.AfterEach; |
| 6 | 6 |
import org.junit.jupiter.api.BeforeEach; |
| 7 | 7 |
import org.junit.jupiter.api.Test; |
| 8 |
+import org.springframework.http.client.JdkClientHttpRequestFactory; |
|
| 9 |
+import org.springframework.web.client.RestClient; |
|
| 10 |
+ |
|
| 11 |
+import java.net.http.HttpClient; |
|
| 8 | 12 |
|
| 9 | 13 |
import static com.github.tomakehurst.wiremock.client.WireMock.*; |
| 10 | 14 |
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; |
... | ... | @@ -28,7 +32,16 @@ |
| 28 | 32 |
"문정원", |
| 29 | 33 |
"법률검토"); |
| 30 | 34 |
|
| 31 |
- client = new MattermostRestClient(props); |
|
| 35 |
+ // 이 HTTP/1.1 고정은 테스트 하네스(WireMock/Jetty)만의 제약이다: JDK 21 HttpClient의 |
|
| 36 |
+ // 기본 h2c 업그레이드 협상이 WireMock 상대로 POST 요청에서 간헐적으로 RST_STREAM을 |
|
| 37 |
+ // 유발하기 때문에 여기서만 고정한다. 운영 환경은 HTTPS/ALPN으로 협상하므로 해당되지 않는다. |
|
| 38 |
+ HttpClient httpClient = HttpClient.newBuilder() |
|
| 39 |
+ .version(HttpClient.Version.HTTP_1_1) |
|
| 40 |
+ .build(); |
|
| 41 |
+ RestClient.Builder builder = RestClient.builder() |
|
| 42 |
+ .requestFactory(new JdkClientHttpRequestFactory(httpClient)); |
|
| 43 |
+ |
|
| 44 |
+ client = new MattermostRestClient(props, builder); |
|
| 32 | 45 |
} |
| 33 | 46 |
|
| 34 | 47 |
@AfterEach |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?