Skip to content

Commit f977274

Browse files
committed
http appender and http appender build test file
1 parent 6b072ce commit f977274

File tree

2 files changed

+164
-23
lines changed

2 files changed

+164
-23
lines changed
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to you under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.logging.log4j.core.appender;
18+
19+
import org.apache.logging.log4j.Level;
20+
import org.apache.logging.log4j.core.Layout;
21+
import org.apache.logging.log4j.core.config.Configuration;
22+
import org.apache.logging.log4j.core.config.DefaultConfiguration;
23+
import org.apache.logging.log4j.core.config.Property;
24+
import org.apache.logging.log4j.core.net.ssl.SslConfiguration;
25+
import org.apache.logging.log4j.core.layout.JsonLayout;
26+
import org.apache.logging.log4j.status.StatusLogger;
27+
import org.apache.logging.log4j.test.ListStatusListener;
28+
import org.apache.logging.log4j.test.junit.UsingStatusListener;
29+
import org.junit.jupiter.api.Test;
30+
import org.mockito.Mockito;
31+
32+
import java.net.MalformedURLException;
33+
import java.net.URL;
34+
35+
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
36+
import static org.junit.jupiter.api.Assertions.*;
37+
import static org.mockito.Mockito.*;
38+
39+
class HttpAppenderBuilderTest {
40+
41+
// Mock the LOGGER to verify error logs
42+
private final StatusLogger mockStatusLogger = Mockito.mock(StatusLogger.class);
43+
44+
private HttpAppender.Builder<?> getBuilder() {
45+
Configuration mockConfig = new DefaultConfiguration();
46+
return HttpAppender.newBuilder()
47+
.setConfiguration(mockConfig)
48+
.setName("TestHttpAppender"); // Name is required
49+
}
50+
51+
@Test
52+
@UsingStatusListener
53+
void testBuilderWithoutUrl(final ListStatusListener listener) throws Exception {
54+
// Build the HttpAppender without URL
55+
HttpAppender appender = HttpAppender.newBuilder()
56+
.setConfiguration(new DefaultConfiguration())
57+
.setName("TestAppender")
58+
.setLayout(JsonLayout.createDefaultLayout()) // Providing a layout here
59+
.build();
60+
61+
// Verify that the error message for missing URL is captured
62+
assertThat(listener.findStatusData(Level.ERROR))
63+
.anyMatch(statusData -> statusData.getMessage().getFormattedMessage().contains("HttpAppender requires URL to be set."));
64+
}
65+
66+
@Test
67+
@UsingStatusListener
68+
void testBuilderWithUrlAndWithoutLayout(final ListStatusListener listener) throws Exception {
69+
// Build the HttpAppender with URL but without Layout
70+
HttpAppender appender = HttpAppender.newBuilder()
71+
.setConfiguration(new DefaultConfiguration())
72+
.setName("TestAppender")
73+
.setUrl(new URL("http://localhost:8080/logs")) // Providing the URL
74+
.build();
75+
76+
// Verify that the error message for missing layout is captured
77+
assertThat(listener.findStatusData(Level.ERROR))
78+
.anyMatch(statusData -> statusData.getMessage().getFormattedMessage().contains("HttpAppender requires a layout to be set."));
79+
}
80+
81+
82+
@Test
83+
void testBuilderWithValidConfiguration() throws Exception {
84+
URL url = new URL("http://example.com");
85+
Layout<?> layout = JsonLayout.createDefaultLayout(); // Valid layout
86+
87+
HttpAppender.Builder<?> builder = getBuilder()
88+
.setUrl(url)
89+
.setLayout(layout);
90+
91+
HttpAppender appender = builder.build();
92+
assertNotNull(appender, "HttpAppender should be created with valid configuration.");
93+
}
94+
95+
@Test
96+
void testBuilderWithCustomMethod() throws Exception {
97+
URL url = new URL("http://example.com");
98+
Layout<?> layout = JsonLayout.createDefaultLayout();
99+
String customMethod = "PUT";
100+
101+
HttpAppender.Builder<?> builder = getBuilder()
102+
.setUrl(url)
103+
.setLayout(layout)
104+
.setMethod(customMethod);
105+
106+
HttpAppender appender = builder.build();
107+
assertNotNull(appender, "HttpAppender should be created with a custom HTTP method.");
108+
}
109+
110+
@Test
111+
void testBuilderWithHeaders() throws Exception {
112+
URL url = new URL("http://example.com");
113+
Layout<?> layout = JsonLayout.createDefaultLayout();
114+
Property[] headers = new Property[]{
115+
Property.createProperty("Header1", "Value1"),
116+
Property.createProperty("Header2", "Value2")
117+
};
118+
119+
HttpAppender.Builder<?> builder = getBuilder()
120+
.setUrl(url)
121+
.setLayout(layout)
122+
.setHeaders(headers);
123+
124+
HttpAppender appender = builder.build();
125+
assertNotNull(appender, "HttpAppender should be created with headers.");
126+
}
127+
128+
@Test
129+
void testBuilderWithSslConfiguration() throws Exception {
130+
URL url = new URL("https://example.com");
131+
Layout<?> layout = JsonLayout.createDefaultLayout();
132+
SslConfiguration sslConfig = mock(SslConfiguration.class);
133+
134+
HttpAppender.Builder<?> builder = getBuilder()
135+
.setUrl(url)
136+
.setLayout(layout)
137+
.setSslConfiguration(sslConfig);
138+
139+
HttpAppender appender = builder.build();
140+
assertNotNull(appender, "HttpAppender should be created with SSL configuration.");
141+
}
142+
143+
@Test
144+
void testBuilderWithInvalidUrl() {
145+
assertThrows(MalformedURLException.class, () -> new URL("invalid-url"));
146+
}
147+
}

log4j-core/src/main/java/org/apache/logging/log4j/core/appender/HttpAppender.java

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,3 @@
1-
/*
2-
* Licensed to the Apache Software Foundation (ASF) under one or more
3-
* contributor license agreements. See the NOTICE file distributed with
4-
* this work for additional information regarding copyright ownership.
5-
* The ASF licenses this file to you under the Apache License, Version 2.0
6-
* (the "License"); you may not use this file except in compliance with
7-
* the License. You may obtain a copy of the License at
8-
*
9-
* http://www.apache.org/licenses/LICENSE-2.0
10-
*
11-
* Unless required by applicable law or agreed to in writing, software
12-
* distributed under the License is distributed on an "AS IS" BASIS,
13-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14-
* See the License for the specific language governing permissions and
15-
* limitations under the License.
16-
*/
171
package org.apache.logging.log4j.core.appender;
182

193
import java.io.Serializable;
@@ -32,16 +16,15 @@
3216
import org.apache.logging.log4j.core.config.plugins.PluginElement;
3317
import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
3418
import org.apache.logging.log4j.core.net.ssl.SslConfiguration;
19+
import org.apache.logging.log4j.status.StatusLogger;
3520

36-
/**
37-
* Sends log events over HTTP.
38-
*/
3921
@Plugin(name = "Http", category = Node.CATEGORY, elementType = Appender.ELEMENT_TYPE, printObject = true)
4022
public final class HttpAppender extends AbstractAppender {
4123

24+
private static final StatusLogger LOGGER = StatusLogger.getLogger();
25+
4226
/**
4327
* Builds HttpAppender instances.
44-
* @param <B> The type to build
4528
*/
4629
public static class Builder<B extends Builder<B>> extends AbstractAppender.Builder<B>
4730
implements org.apache.logging.log4j.core.util.Builder<HttpAppender> {
@@ -70,6 +53,18 @@ public static class Builder<B extends Builder<B>> extends AbstractAppender.Build
7053

7154
@Override
7255
public HttpAppender build() {
56+
// Validate URL presence
57+
if (url == null) {
58+
LOGGER.error("HttpAppender requires URL to be set.");
59+
return null; // Return null if URL is missing
60+
}
61+
62+
// Validate layout presence
63+
if (getLayout() == null) {
64+
LOGGER.error("HttpAppender requires a layout to be set.");
65+
return null; // Return null if layout is missing
66+
}
67+
7368
final HttpManager httpManager = new HttpURLConnectionManager(
7469
getConfiguration(),
7570
getConfiguration().getLoggerContext(),
@@ -81,10 +76,12 @@ public HttpAppender build() {
8176
headers,
8277
sslConfiguration,
8378
verifyHostname);
79+
8480
return new HttpAppender(
8581
getName(), getLayout(), getFilter(), isIgnoreExceptions(), httpManager, getPropertyArray());
8682
}
8783

84+
// Getter and Setter methods
8885
public URL getUrl() {
8986
return url;
9087
}
@@ -149,9 +146,6 @@ public B setVerifyHostname(final boolean verifyHostname) {
149146
}
150147
}
151148

152-
/**
153-
* @return a builder for a HttpAppender.
154-
*/
155149
@PluginBuilderFactory
156150
public static <B extends Builder<B>> B newBuilder() {
157151
return new Builder<B>().asBuilder();

0 commit comments

Comments
 (0)