This is an automated email from the ASF dual-hosted git repository.
clebertsuconic pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/activemq-artemis.git
The following commit(s) were added to refs/heads/main by this push:
new 36056a5bdd ARTEMIS-4513 HTTP request logging not working
36056a5bdd is described below
commit 36056a5bddeaf431bd282cc0f231f53675549117
Author: Justin Bertram <[email protected]>
AuthorDate: Tue Nov 21 14:37:47 2023 -0600
ARTEMIS-4513 HTTP request logging not working
---
.../artemis/component/WebServerComponent.java | 12 +-
tests/integration-tests-isolated/pom.xml | 6 +
.../isolated/web/WebServerComponentTest.java | 185 +++++++++++++++++++++
.../resources/webapps/WebServerComponentTest.txt | 1 +
4 files changed, 197 insertions(+), 7 deletions(-)
diff --git
a/artemis-web/src/main/java/org/apache/activemq/artemis/component/WebServerComponent.java
b/artemis-web/src/main/java/org/apache/activemq/artemis/component/WebServerComponent.java
index 8f71d73694..f1d1300d03 100644
---
a/artemis-web/src/main/java/org/apache/activemq/artemis/component/WebServerComponent.java
+++
b/artemis-web/src/main/java/org/apache/activemq/artemis/component/WebServerComponent.java
@@ -18,6 +18,7 @@ package org.apache.activemq.artemis.component;
import javax.servlet.DispatcherType;
import java.io.File;
+import java.lang.invoke.MethodHandles;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -40,6 +41,7 @@ import org.eclipse.jetty.server.ConnectionFactory;
import org.eclipse.jetty.server.CustomRequestLog;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
+import org.eclipse.jetty.server.RequestLog;
import org.eclipse.jetty.server.RequestLogWriter;
import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server;
@@ -47,14 +49,12 @@ import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.HandlerList;
-import org.eclipse.jetty.server.handler.RequestLogHandler;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.webapp.WebAppContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.lang.invoke.MethodHandles;
public class WebServerComponent implements ExternalComponent,
WebServerComponentMarker {
@@ -175,7 +175,7 @@ public class WebServerComponent implements
ExternalComponent, WebServerComponent
defaultHandler.setRootRedirectLocation(this.webServerConfig.rootRedirectLocation);
if (this.webServerConfig.requestLog != null) {
- handlers.addHandler(getLogHandler());
+ server.setRequestLog(getRequestLog());
}
if (this.webServerConfig.webContentEnabled != null &&
@@ -269,7 +269,7 @@ public class WebServerComponent implements
ExternalComponent, WebServerComponent
return connector;
}
- private RequestLogHandler getLogHandler() {
+ private RequestLog getRequestLog() {
RequestLogWriter requestLogWriter = new RequestLogWriter();
CustomRequestLog requestLog;
@@ -305,9 +305,7 @@ public class WebServerComponent implements
ExternalComponent, WebServerComponent
requestLog.setIgnorePaths(ignorePaths);
}
- RequestLogHandler requestLogHandler = new RequestLogHandler();
- requestLogHandler.setRequestLog(requestLog);
- return requestLogHandler;
+ return requestLog;
}
private File getLibFolder() {
diff --git a/tests/integration-tests-isolated/pom.xml
b/tests/integration-tests-isolated/pom.xml
index 6724ad4b7b..083a56d9b7 100644
--- a/tests/integration-tests-isolated/pom.xml
+++ b/tests/integration-tests-isolated/pom.xml
@@ -205,6 +205,12 @@
<artifactId>protonj2-test-driver</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.activemq</groupId>
+ <artifactId>artemis-web</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>jakarta.management.j2ee</groupId>
<artifactId>jakarta.management.j2ee-api</artifactId>
diff --git
a/tests/integration-tests-isolated/src/test/java/org/apache/activemq/artemis/tests/integration/isolated/web/WebServerComponentTest.java
b/tests/integration-tests-isolated/src/test/java/org/apache/activemq/artemis/tests/integration/isolated/web/WebServerComponentTest.java
new file mode 100644
index 0000000000..cc0fb46047
--- /dev/null
+++
b/tests/integration-tests-isolated/src/test/java/org/apache/activemq/artemis/tests/integration/isolated/web/WebServerComponentTest.java
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.tests.integration.isolated.web;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.SimpleChannelInboundHandler;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import io.netty.handler.codec.http.DefaultFullHttpRequest;
+import io.netty.handler.codec.http.HttpClientCodec;
+import io.netty.handler.codec.http.HttpContent;
+import io.netty.handler.codec.http.HttpHeaderNames;
+import io.netty.handler.codec.http.HttpMethod;
+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.HttpVersion;
+import io.netty.handler.codec.http.LastHttpContent;
+import io.netty.util.CharsetUtil;
+import org.apache.activemq.artemis.component.WebServerComponent;
+import org.apache.activemq.artemis.core.server.ActiveMQComponent;
+import org.apache.activemq.artemis.dto.BindingDTO;
+import org.apache.activemq.artemis.dto.RequestLogDTO;
+import org.apache.activemq.artemis.dto.WebServerDTO;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * This test leaks a thread named
org.eclipse.jetty.util.RolloverFileOutputStream which is why it is isolated now.
+ * In the future Jetty might fix this.
+ */
+public class WebServerComponentTest extends Assert {
+
+ static final String URL = System.getProperty("url",
"http://localhost:8161/WebServerComponentTest.txt");
+
+ private List<ActiveMQComponent> testedComponents;
+
+ @Before
+ public void setupNetty() throws URISyntaxException {
+ System.setProperty("jetty.base", "./target");
+ // Configure the client.
+ testedComponents = new ArrayList<>();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ System.clearProperty("jetty.base");
+ for (ActiveMQComponent c : testedComponents) {
+ c.stop();
+ }
+ testedComponents.clear();
+ }
+
+ @Test
+ public void testRequestLog() throws Exception {
+ String requestLogFileName = "target/httpRequest.log";
+ BindingDTO bindingDTO = new BindingDTO();
+ bindingDTO.uri = "http://localhost:0";
+ WebServerDTO webServerDTO = new WebServerDTO();
+ webServerDTO.setBindings(Collections.singletonList(bindingDTO));
+ webServerDTO.path = "webapps";
+ webServerDTO.webContentEnabled = true;
+ RequestLogDTO requestLogDTO = new RequestLogDTO();
+ requestLogDTO.filename = requestLogFileName;
+ webServerDTO.setRequestLog(requestLogDTO);
+ WebServerComponent webServerComponent = new WebServerComponent();
+ Assert.assertFalse(webServerComponent.isStarted());
+ webServerComponent.configure(webServerDTO, "./src/test/resources/",
"./src/test/resources/");
+ testedComponents.add(webServerComponent);
+ webServerComponent.start();
+
+ final int port = webServerComponent.getPort();
+ // Make the connection attempt.
+ CountDownLatch latch = new CountDownLatch(1);
+ final ClientHandler clientHandler = new ClientHandler(latch);
+ Channel ch = getChannel(port, clientHandler);
+
+ URI uri = new URI(URL);
+ // Prepare the HTTP request.
+ HttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1,
HttpMethod.GET, uri.getRawPath());
+ request.headers().set(HttpHeaderNames.HOST, "localhost");
+
+ // Send the HTTP request.
+ ch.writeAndFlush(request);
+ assertTrue(latch.await(5, TimeUnit.SECONDS));
+ assertEquals("12345", clientHandler.body.toString());
+ assertEquals(clientHandler.body.toString(), "12345");
+ assertNull(clientHandler.serverHeader);
+ // Wait for the server to close the connection.
+ ch.close();
+ ch.eventLoop().shutdownGracefully();
+ ch.eventLoop().awaitTermination(5, TimeUnit.SECONDS);
+ Assert.assertTrue(webServerComponent.isStarted());
+ webServerComponent.stop(true);
+ Assert.assertFalse(webServerComponent.isStarted());
+ File requestLog = new File(requestLogFileName);
+ assertTrue(requestLog.exists());
+ boolean logEntryFound = false;
+ try (BufferedReader reader = new BufferedReader(new
FileReader(requestLog))) {
+ String line;
+ while ((line = reader.readLine()) != null) {
+ if (line.contains("\"GET /WebServerComponentTest.txt HTTP/1.1\"
200 5")) {
+ logEntryFound = true;
+ break;
+ }
+ }
+ }
+ assertTrue(logEntryFound);
+ }
+
+ private Channel getChannel(int port, ClientHandler clientHandler) throws
InterruptedException {
+ EventLoopGroup group = new NioEventLoopGroup();
+ Bootstrap bootstrap = new Bootstrap();
+ bootstrap.group(group).channel(NioSocketChannel.class).handler(new
ChannelInitializer() {
+ @Override
+ protected void initChannel(Channel ch) throws Exception {
+ ch.pipeline().addLast(new HttpClientCodec());
+ ch.pipeline().addLast(clientHandler);
+ }
+ });
+ return bootstrap.connect("localhost", port).sync().channel();
+ }
+
+ class ClientHandler extends SimpleChannelInboundHandler<HttpObject> {
+
+ private CountDownLatch latch;
+ private StringBuilder body = new StringBuilder();
+ private String serverHeader;
+
+ ClientHandler(CountDownLatch latch) {
+ this.latch = latch;
+ }
+
+ @Override
+ public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) {
+ if (msg instanceof HttpResponse) {
+ HttpResponse response = (HttpResponse) msg;
+ serverHeader = response.headers().get("Server");
+ } else if (msg instanceof HttpContent) {
+ HttpContent content = (HttpContent) msg;
+ body.append(content.content().toString(CharsetUtil.UTF_8));
+ if (msg instanceof LastHttpContent) {
+ latch.countDown();
+ }
+ }
+ }
+
+ @Override
+ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
+ cause.printStackTrace();
+ ctx.close();
+ }
+ }
+}
diff --git
a/tests/integration-tests-isolated/src/test/resources/webapps/WebServerComponentTest.txt
b/tests/integration-tests-isolated/src/test/resources/webapps/WebServerComponentTest.txt
new file mode 100644
index 0000000000..bd41cba781
--- /dev/null
+++
b/tests/integration-tests-isolated/src/test/resources/webapps/WebServerComponentTest.txt
@@ -0,0 +1 @@
+12345
\ No newline at end of file