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 <jbert...@apache.org>
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

Reply via email to