localCertificates = handshake.localCertificates();
201 | return okhttp3.Handshake.get(TlsVersion.SSL_3_0,
202 | okhttp3.CipherSuite.forJavaName(cipherSuite),
203 | peerCertificates,
204 | localCertificates
205 | );
206 | }
207 | }
208 |
209 | private static okhttp3.Headers convertOkhttpHeadersTo3(com.squareup.okhttp.Headers headers) {
210 | final Headers.Builder headersBuilder = new Headers.Builder();
211 | headers.names().forEach(name -> headersBuilder.add(name, headers.get(name)));
212 | return headersBuilder.build();
213 | }
214 |
215 | private static okhttp3.ResponseBody convertOkhttpResponseBodyTo3(
216 | com.squareup.okhttp.ResponseBody responseBody) {
217 | if (responseBody == null) {
218 | return null;
219 | } else {
220 | final MediaType mediaType = responseBody.contentType();
221 | String responseBodyString = "";
222 | try {
223 | responseBodyString = new String(responseBody.bytes(), Charset.defaultCharset());
224 | } catch (IOException e) {
225 | logger.log(Level.SEVERE, e.getMessage(), e);
226 | }
227 | return okhttp3.ResponseBody
228 | .create(convertOkhttpMediaTypeTo3(mediaType), responseBodyString);
229 | }
230 | }
231 |
232 | private static okhttp3.Protocol convertOkhttpProtocolTo3(Protocol protocol) {
233 | switch (protocol) {
234 | case HTTP_1_0:
235 | return okhttp3.Protocol.HTTP_1_0;
236 | case HTTP_1_1:
237 | return okhttp3.Protocol.HTTP_1_1;
238 | case HTTP_2:
239 | return okhttp3.Protocol.HTTP_2;
240 | default:
241 | return okhttp3.Protocol.HTTP_1_1;
242 | }
243 | }
244 |
245 | private static okhttp3.Response convertBaseOkhttpResponseTo3(Response response) {
246 | if (response == null) {
247 | return null;
248 | } else {
249 | return new okhttp3.Response
250 | .Builder()
251 | .request(convertOkhttpRequestTo3(response.request()))
252 | .protocol(convertOkhttpProtocolTo3(response.protocol()))
253 | .code(response.code())
254 | .message(response.message())
255 | .handshake(convertOkhttpHandshakeTo3(response.handshake()))
256 | .headers(convertOkhttpHeadersTo3(response.headers()))
257 | .body(convertOkhttpResponseBodyTo3(response.body()))
258 | .build();
259 | }
260 | }
261 |
262 | public static okhttp3.Response convertOkhttpResponseTo3(Response response) {
263 | if (response == null) {
264 | return null;
265 | } else {
266 | final okhttp3.Response okhttp3Response = convertBaseOkhttpResponseTo3(response);
267 | return okhttp3Response
268 | .newBuilder()
269 | .cacheResponse(convertBaseOkhttpResponseTo3(response.cacheResponse()))
270 | .networkResponse(convertBaseOkhttpResponseTo3(response.networkResponse()))
271 | .build();
272 | }
273 | }
274 | }
275 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/dkorobtsov/logging/converters/ToOkhttpConverter.java:
--------------------------------------------------------------------------------
1 | package com.dkorobtsov.logging.converters;
2 |
3 | import com.squareup.okhttp.MediaType;
4 | import com.squareup.okhttp.RequestBody;
5 | import java.io.IOException;
6 | import okio.Buffer;
7 |
8 | public class ToOkhttpConverter {
9 |
10 | private ToOkhttpConverter() {
11 | }
12 |
13 | public static MediaType convertOkhttp3MediaType(okhttp3.MediaType okhttp3MediaType) {
14 | return okhttp3MediaType == null ? MediaType.parse("")
15 | : MediaType.parse(okhttp3MediaType.toString());
16 | }
17 |
18 | public static RequestBody convertOkhtt3pRequestBody(okhttp3.Request request) {
19 | final MediaType contentType = request.body() == null ? MediaType.parse("")
20 | : convertOkhttp3MediaType(request.body().contentType());
21 | try {
22 | final okhttp3.Request requestCopy = request.newBuilder().build();
23 |
24 | String requestBodyString = "";
25 | if (requestCopy.body() != null) {
26 | final Buffer buffer = new Buffer();
27 | requestCopy.body().writeTo(buffer);
28 | requestBodyString = buffer.readUtf8();
29 | }
30 | return RequestBody.create(contentType, requestBodyString);
31 | } catch (final IOException e) {
32 | return RequestBody
33 | .create(contentType, "[LoggingInterceptorError] : could not parse request body");
34 | }
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/dkorobtsov/logging/interceptors/ApacheHttpRequestInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.dkorobtsov.logging.interceptors;
2 |
3 | import static com.dkorobtsov.logging.ClientPrintingExecutor.printFileRequest;
4 | import static com.dkorobtsov.logging.ClientPrintingExecutor.printJsonRequest;
5 | import static com.dkorobtsov.logging.TextUtils.isFileRequest;
6 |
7 | import com.dkorobtsov.logging.Level;
8 | import com.dkorobtsov.logging.LoggerConfig;
9 | import com.dkorobtsov.logging.RequestDetails;
10 | import java.util.Objects;
11 | import okhttp3.Request;
12 | import okhttp3.RequestBody;
13 | import org.apache.http.HttpRequest;
14 | import org.apache.http.HttpRequestInterceptor;
15 | import org.apache.http.protocol.HttpContext;
16 |
17 | public class ApacheHttpRequestInterceptor implements HttpRequestInterceptor {
18 |
19 | private final boolean isDebug;
20 | private final LoggerConfig loggerConfig;
21 |
22 | public ApacheHttpRequestInterceptor(LoggerConfig loggerConfig) {
23 | this.loggerConfig = loggerConfig;
24 | this.isDebug = loggerConfig.isDebug;
25 | }
26 |
27 | @Override
28 | public void process(HttpRequest request, HttpContext context) {
29 | if (isDebug && loggerConfig.level != Level.NONE) {
30 | final Request requestDetails = new RequestDetails.Builder().from(request).build();
31 | final RequestBody requestBody = requestDetails.body();
32 |
33 | String requestSubtype = null;
34 |
35 | if (requestBody != null && requestBody.contentType() != null) {
36 | requestSubtype = Objects.requireNonNull(requestBody.contentType()).subtype();
37 | }
38 |
39 | if (isFileRequest(requestSubtype)) {
40 | printFileRequest(requestDetails, loggerConfig);
41 | } else {
42 | printJsonRequest(requestDetails, loggerConfig);
43 | }
44 | }
45 | }
46 |
47 | public LoggerConfig loggerConfig() {
48 | return this.loggerConfig;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/dkorobtsov/logging/interceptors/ApacheHttpResponseInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.dkorobtsov.logging.interceptors;
2 |
3 | import static com.dkorobtsov.logging.ClientPrintingExecutor.printFileResponse;
4 | import static com.dkorobtsov.logging.ClientPrintingExecutor.printJsonResponse;
5 | import static com.dkorobtsov.logging.TextUtils.isFileRequest;
6 |
7 | import com.dkorobtsov.logging.Level;
8 | import com.dkorobtsov.logging.LoggerConfig;
9 | import com.dkorobtsov.logging.ResponseDetails;
10 | import java.io.IOException;
11 | import java.util.Objects;
12 |
13 | import org.apache.http.HttpEntity;
14 | import org.apache.http.HttpResponse;
15 | import org.apache.http.HttpResponseInterceptor;
16 | import org.apache.http.protocol.HttpContext;
17 |
18 | public class ApacheHttpResponseInterceptor implements HttpResponseInterceptor {
19 |
20 | private final boolean isDebug;
21 | private final LoggerConfig loggerConfig;
22 |
23 | public ApacheHttpResponseInterceptor(LoggerConfig loggerConfig) {
24 | this.loggerConfig = loggerConfig;
25 | this.isDebug = loggerConfig.isDebug;
26 | }
27 |
28 | @Override
29 | public void process(HttpResponse response, HttpContext context) throws IOException {
30 | if (isDebug && loggerConfig.level != Level.NONE) {
31 | String subtype = null;
32 | final HttpEntity entity = response.getEntity();
33 | if (entity != null) {
34 | if (entity.getContentType() != null) {
35 | subtype = Objects.requireNonNull(entity.getContentType()).getValue();
36 | }
37 | }
38 |
39 | ResponseDetails responseDetails = ResponseDetails
40 | .from(response, isFileRequest(subtype));
41 |
42 | if (isFileRequest(subtype)) {
43 | printFileResponse(responseDetails, loggerConfig);
44 | } else {
45 | printJsonResponse(responseDetails, loggerConfig);
46 | }
47 | }
48 | }
49 |
50 | public LoggerConfig loggerConfig() {
51 | return this.loggerConfig;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/dkorobtsov/logging/interceptors/Okhttp3LoggingInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.dkorobtsov.logging.interceptors;
2 |
3 | import static com.dkorobtsov.logging.ClientPrintingExecutor.printFileRequest;
4 | import static com.dkorobtsov.logging.ClientPrintingExecutor.printFileResponse;
5 | import static com.dkorobtsov.logging.ClientPrintingExecutor.printJsonRequest;
6 | import static com.dkorobtsov.logging.ClientPrintingExecutor.printJsonResponse;
7 | import static com.dkorobtsov.logging.TextUtils.isFileRequest;
8 |
9 | import com.dkorobtsov.logging.Level;
10 | import com.dkorobtsov.logging.LoggerConfig;
11 | import com.dkorobtsov.logging.ResponseDetails;
12 | import java.io.IOException;
13 | import java.util.Objects;
14 | import java.util.concurrent.TimeUnit;
15 | import okhttp3.Interceptor;
16 | import okhttp3.Request;
17 | import okhttp3.RequestBody;
18 | import okhttp3.Response;
19 | import okhttp3.ResponseBody;
20 |
21 | public class Okhttp3LoggingInterceptor implements Interceptor {
22 |
23 | private final boolean isDebug;
24 | private final LoggerConfig loggerConfig;
25 |
26 | public Okhttp3LoggingInterceptor(LoggerConfig loggerConfig) {
27 | this.loggerConfig = loggerConfig;
28 | this.isDebug = loggerConfig.isDebug;
29 | }
30 |
31 | @Override
32 | public Response intercept(Chain chain) throws IOException {
33 | Request request = chain.request();
34 |
35 | if (!isDebug || loggerConfig.level == Level.NONE) {
36 | return chain.proceed(request);
37 | }
38 |
39 | final RequestBody requestBody = request.body();
40 |
41 | String requestSubtype = null;
42 | if (requestBody != null && requestBody.contentType() != null) {
43 | requestSubtype = Objects.requireNonNull(requestBody.contentType()).subtype();
44 | }
45 |
46 | if (isFileRequest(requestSubtype)) {
47 | printFileRequest(request, loggerConfig);
48 | } else {
49 | printJsonRequest(request, loggerConfig);
50 | }
51 |
52 | final long startTime = System.nanoTime();
53 | final Response response = chain.proceed(request);
54 | final long responseTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime);
55 |
56 | String subtype = null;
57 | final ResponseBody body;
58 |
59 | if (Objects.requireNonNull(response.body()).contentType() != null) {
60 | subtype = Objects.requireNonNull(response.body().contentType()).subtype();
61 | }
62 |
63 | ResponseDetails responseDetails = ResponseDetails
64 | .from(request, response, responseTime, isFileRequest(subtype));
65 |
66 | if (isFileRequest(subtype)) {
67 | printFileResponse(responseDetails, loggerConfig);
68 | return response;
69 | } else {
70 | printJsonResponse(responseDetails, loggerConfig);
71 | body = ResponseBody.create(responseDetails.contentType, responseDetails.originalBody);
72 | }
73 |
74 | return response.newBuilder()
75 | .body(body)
76 | .build();
77 | }
78 |
79 | public LoggerConfig loggerConfig() {
80 | return this.loggerConfig;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/dkorobtsov/logging/interceptors/OkhttpLoggingInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.dkorobtsov.logging.interceptors;
2 |
3 | import static com.dkorobtsov.logging.ClientPrintingExecutor.printFileRequest;
4 | import static com.dkorobtsov.logging.ClientPrintingExecutor.printFileResponse;
5 | import static com.dkorobtsov.logging.ClientPrintingExecutor.printJsonRequest;
6 | import static com.dkorobtsov.logging.ClientPrintingExecutor.printJsonResponse;
7 | import static com.dkorobtsov.logging.TextUtils.isFileRequest;
8 | import static com.dkorobtsov.logging.converters.ToOkhttp3Converter.convertOkhttpResponseTo3;
9 | import static com.dkorobtsov.logging.converters.ToOkhttpConverter.convertOkhttp3MediaType;
10 |
11 | import com.dkorobtsov.logging.Level;
12 | import com.dkorobtsov.logging.LoggerConfig;
13 | import com.dkorobtsov.logging.RequestDetails;
14 | import com.dkorobtsov.logging.ResponseDetails;
15 | import com.squareup.okhttp.Interceptor;
16 | import com.squareup.okhttp.MediaType;
17 | import com.squareup.okhttp.Request;
18 | import com.squareup.okhttp.Response;
19 | import com.squareup.okhttp.ResponseBody;
20 | import java.io.IOException;
21 | import java.util.Objects;
22 | import java.util.concurrent.TimeUnit;
23 | import okhttp3.RequestBody;
24 |
25 | public class OkhttpLoggingInterceptor implements Interceptor {
26 |
27 | private final boolean isDebug;
28 | private final LoggerConfig loggerConfig;
29 |
30 | public OkhttpLoggingInterceptor(LoggerConfig loggerConfig) {
31 | this.loggerConfig = loggerConfig;
32 | this.isDebug = loggerConfig.isDebug;
33 | }
34 |
35 | @Override
36 | public Response intercept(Chain chain) throws IOException {
37 | Request request = chain.request();
38 | final okhttp3.Request requestDetails = new RequestDetails.Builder().from(request).build();
39 |
40 | if (!isDebug || loggerConfig.level == Level.NONE) {
41 | return chain.proceed(request);
42 | }
43 |
44 | final RequestBody requestBody = requestDetails.body();
45 |
46 | String requestSubtype = null;
47 | if (requestBody != null && requestBody.contentType() != null) {
48 | requestSubtype = Objects.requireNonNull(requestBody.contentType()).subtype();
49 | }
50 |
51 | if (isFileRequest(requestSubtype)) {
52 | printFileRequest(requestDetails, loggerConfig);
53 | } else {
54 | printJsonRequest(requestDetails, loggerConfig);
55 | }
56 |
57 | final long requestStartTime = System.nanoTime();
58 | final Response response = chain.proceed(request);
59 | final long responseTime = TimeUnit.NANOSECONDS
60 | .toMillis(System.nanoTime() - requestStartTime);
61 |
62 | String subtype = null;
63 | final ResponseBody body;
64 |
65 | if (Objects.requireNonNull(response.body()).contentType() != null) {
66 | subtype = Objects.requireNonNull(response.body().contentType()).subtype();
67 | }
68 |
69 | ResponseDetails responseDetails = ResponseDetails
70 | .from(requestDetails, convertOkhttpResponseTo3(response), responseTime,
71 | isFileRequest(subtype));
72 |
73 | if (isFileRequest(subtype)) {
74 | printFileResponse(responseDetails, loggerConfig);
75 | return response;
76 | } else {
77 | printJsonResponse(responseDetails, loggerConfig);
78 | final okhttp3.MediaType okhttp3MediaType = responseDetails.contentType;
79 | final MediaType mediaType = convertOkhttp3MediaType(okhttp3MediaType);
80 | body = ResponseBody.create(mediaType, responseDetails.originalBody);
81 | }
82 |
83 | return response.newBuilder()
84 | .body(body)
85 | .build();
86 | }
87 |
88 | public LoggerConfig loggerConfig() {
89 | return this.loggerConfig;
90 | }
91 |
92 | }
93 |
--------------------------------------------------------------------------------
/lib/src/test/java/com/dkorobtsov/logging/BaseTest.java:
--------------------------------------------------------------------------------
1 | package com.dkorobtsov.logging;
2 |
3 | import static com.dkorobtsov.logging.converters.ToOkhttpConverter.convertOkhtt3pRequestBody;
4 | import static org.junit.Assert.fail;
5 |
6 | import com.dkorobtsov.logging.converters.ToApacheHttpClientConverter;
7 | import com.dkorobtsov.logging.interceptors.ApacheHttpRequestInterceptor;
8 | import com.dkorobtsov.logging.interceptors.ApacheHttpResponseInterceptor;
9 | import com.dkorobtsov.logging.interceptors.Okhttp3LoggingInterceptor;
10 | import com.dkorobtsov.logging.interceptors.OkhttpLoggingInterceptor;
11 | import com.squareup.okhttp.mockwebserver.MockResponse;
12 | import com.squareup.okhttp.mockwebserver.MockWebServer;
13 | import java.io.IOException;
14 | import java.util.Arrays;
15 | import java.util.List;
16 | import java.util.Objects;
17 | import java.util.concurrent.LinkedBlockingQueue;
18 | import java.util.concurrent.ThreadPoolExecutor;
19 | import java.util.concurrent.TimeUnit;
20 | import java.util.logging.LogManager;
21 | import java.util.logging.Logger;
22 | import okhttp3.ConnectionPool;
23 | import okhttp3.Dispatcher;
24 | import okhttp3.Interceptor;
25 | import okhttp3.MediaType;
26 | import okhttp3.OkHttpClient;
27 | import okhttp3.Request;
28 | import okhttp3.RequestBody;
29 | import org.apache.http.HttpEntity;
30 | import org.apache.http.client.HttpClient;
31 | import org.apache.http.client.methods.HttpGet;
32 | import org.apache.http.client.methods.HttpPut;
33 | import org.apache.http.client.methods.HttpUriRequest;
34 | import org.apache.http.entity.ContentType;
35 | import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
36 | import org.apache.http.impl.client.HttpClientBuilder;
37 | import org.apache.http.message.BasicHeader;
38 | import org.junit.BeforeClass;
39 | import org.junit.Rule;
40 |
41 | public abstract class BaseTest {
42 |
43 | private static final ConnectionPool connectionPool = new ConnectionPool();
44 | private static final Dispatcher dispatcher = new Dispatcher();
45 | private static final int MAX_IDLE_CONNECTIONS = 10;
46 | private static final int KEEP_ALIVE_DURATION_MS = 60 * 1000;
47 | private final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager
48 | .getLogger(Log4j2LoggerTest.class);
49 |
50 | @Rule
51 | public MockWebServer server = new MockWebServer();
52 |
53 | @BeforeClass
54 | public static void cleanAnyExistingJavaUtilityLoggingConfigurations() {
55 | LogManager.getLogManager().reset();
56 | Logger globalLogger = Logger.getLogger(java.util.logging.Logger.GLOBAL_LOGGER_NAME);
57 | globalLogger.setLevel(java.util.logging.Level.OFF);
58 | }
59 |
60 | /**
61 | * Returns default OkHttp request for use in tests.
62 | */
63 | Request defaultOkhttp3Request() {
64 | return new Request.Builder()
65 | .url(String.valueOf(server.url("/")))
66 | .build();
67 | }
68 |
69 | HttpUriRequest defaultApacheHttpRequest() {
70 | return new HttpGet(server.url("/").uri());
71 | }
72 |
73 | com.squareup.okhttp.Request defaultOkhttpRequest() {
74 | return new com.squareup.okhttp.Request.Builder()
75 | .url(String.valueOf(server.url("/")))
76 | .build();
77 | }
78 |
79 | /**
80 | * Returns OkHttpClient for all interceptor tests to use as a starting point.
81 | *
82 | * The shared instance allows all tests to share a single connection pool, which prevents
83 | * idle connections from consuming unnecessary resources while connections wait to be evicted.
84 | */
85 | OkHttpClient defaultOkhttp3ClientWithInterceptor(Interceptor interceptor) {
86 | return new OkHttpClient.Builder()
87 | .connectionPool(connectionPool)
88 | .dispatcher(dispatcher)
89 | .addNetworkInterceptor(interceptor)
90 | .build();
91 | }
92 |
93 | HttpClient defaultApacheClientWithInterceptors(ApacheHttpRequestInterceptor requestInterceptor,
94 | ApacheHttpResponseInterceptor responseInterceptor) {
95 | return HttpClientBuilder
96 | .create()
97 | .addInterceptorFirst(requestInterceptor)
98 | .addInterceptorFirst(responseInterceptor)
99 | .setMaxConnTotal(MAX_IDLE_CONNECTIONS)
100 | .setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy())
101 | .build();
102 | }
103 |
104 | com.squareup.okhttp.OkHttpClient defaultOkhttpClientWithInterceptor(
105 | com.squareup.okhttp.Interceptor interceptor) {
106 | final com.squareup.okhttp.OkHttpClient okHttpClient = new com.squareup.okhttp.OkHttpClient()
107 | .setConnectionPool(
108 | new com.squareup.okhttp.ConnectionPool(MAX_IDLE_CONNECTIONS,
109 | KEEP_ALIVE_DURATION_MS))
110 | .setDispatcher(new com.squareup.okhttp.Dispatcher());
111 | okHttpClient.interceptors().add(interceptor);
112 | return okHttpClient;
113 | }
114 |
115 | void attachLoggerToInterceptorWithDefaultRequest(String interceptorVersion,
116 | LogWriter log4j2Writer) throws IOException {
117 | if (interceptorVersion.equals(InterceptorVersion.OKHTTP3.getName())) {
118 | attachLoggerToOkttp3InterceptorWithDefaultRequest(log4j2Writer);
119 | } else if (interceptorVersion.equals(InterceptorVersion.OKHTTP.getName())) {
120 | attachLoggerToOkhttpInterceptorWithDefaultRequest(log4j2Writer);
121 | } else if (interceptorVersion
122 | .equals(InterceptorVersion.APACHE_HTTPCLIENT_REQUEST.getName())) {
123 | attachLoggerToApacheRequestInterceptorWithDefaultRequest(log4j2Writer);
124 | } else {
125 | fail(String.format(
126 | "I couldn't recognize %s interceptor version. I currently support okhttp and okhttp3 versions",
127 | interceptorVersion));
128 | }
129 | }
130 |
131 | void attachLoggerToInterceptor(String interceptorVersion, LogWriter log4j2Writer,
132 | Request okhttp3Request, com.squareup.okhttp.Request okhttpRequest,
133 | HttpUriRequest apacheHttpRequest) throws IOException {
134 | if (interceptorVersion.equals(InterceptorVersion.OKHTTP3.getName())) {
135 | attachLoggerToOkhttp3Interceptor(log4j2Writer, okhttp3Request);
136 | } else if (interceptorVersion.equals(InterceptorVersion.OKHTTP.getName())) {
137 | attachLoggerToOkHttpInterceptor(log4j2Writer, okhttpRequest);
138 | } else if (interceptorVersion
139 | .equals(InterceptorVersion.APACHE_HTTPCLIENT_REQUEST.getName())) {
140 | attachLoggerToApacheRequestInterceptor(log4j2Writer, apacheHttpRequest);
141 | } else {
142 | fail(String.format(
143 | "I couldn't recognize %s interceptor version. I currently support okhttp and okhttp3 versions",
144 | interceptorVersion));
145 | }
146 | }
147 |
148 | private void attachLoggerToOkhttpInterceptorWithDefaultRequest(LogWriter logWriter)
149 | throws IOException {
150 | attachLoggerToOkHttpInterceptor(logWriter, defaultOkhttpRequest());
151 | }
152 |
153 | private void attachLoggerToOkHttpInterceptor(LogWriter logWriter,
154 | com.squareup.okhttp.Request request) throws IOException {
155 | OkhttpLoggingInterceptor interceptor = new LoggingInterceptor.Builder()
156 | .logger(logWriter)
157 | .buildForOkhttp();
158 | defaultOkhttpClientWithInterceptor(interceptor)
159 | .newCall(request)
160 | .execute();
161 | }
162 |
163 | private void attachLoggerToOkttp3InterceptorWithDefaultRequest(LogWriter logWriter)
164 | throws IOException {
165 | attachLoggerToOkhttp3Interceptor(logWriter, defaultOkhttp3Request());
166 | }
167 |
168 | private void attachLoggerToOkhttp3Interceptor(LogWriter logWriter, Request request)
169 | throws IOException {
170 | Okhttp3LoggingInterceptor interceptor = new LoggingInterceptor.Builder()
171 | .logger(logWriter)
172 | .buildForOkhttp3();
173 |
174 | log.debug("Sending request.");
175 | defaultOkhttp3ClientWithInterceptor(interceptor)
176 | .newCall(request)
177 | .execute();
178 | }
179 |
180 | private void attachLoggerToApacheRequestInterceptorWithDefaultRequest(LogWriter logWriter)
181 | throws IOException {
182 | attachLoggerToApacheRequestInterceptor(logWriter, defaultApacheHttpRequest());
183 | }
184 |
185 | private void attachLoggerToApacheRequestInterceptor(LogWriter logWriter, HttpUriRequest request)
186 | throws IOException {
187 | ApacheHttpRequestInterceptor requestInterceptor = new LoggingInterceptor.Builder()
188 | .logger(logWriter)
189 | .buildForApacheHttpClientRequest();
190 |
191 | final ApacheHttpResponseInterceptor responseInterceptor = new LoggingInterceptor.Builder()
192 | .logger(logWriter)
193 | .buildFordApacheHttpClientResponse();
194 | log.debug("Sending request.");
195 | defaultApacheClientWithInterceptors(requestInterceptor, responseInterceptor)
196 | .execute(request);
197 | }
198 |
199 | List interceptedRequest(RequestBody body, String loggerVersion,
200 | boolean provideExecutor, boolean preserveTrailingSpaces) throws IOException {
201 | return interceptedRequest(body, null, loggerVersion, provideExecutor,
202 | preserveTrailingSpaces);
203 | }
204 |
205 | List interceptedRequest(RequestBody body, Integer maxLineLength, String loggerVersion,
206 | boolean provideExecutor, boolean preserveTrailingSpaces) throws IOException {
207 | server.enqueue(new MockResponse().setResponseCode(200));
208 | final TestLogger testLogger = new TestLogger(LogFormatter.JUL_MESSAGE_ONLY);
209 |
210 | Request okhttp3Request = new Request.Builder()
211 | .url(String.valueOf(server.url("/")))
212 | .put(body)
213 | .build();
214 |
215 | final LoggingInterceptor.Builder builder = new LoggingInterceptor.Builder()
216 | .logger(testLogger);
217 |
218 | if (Objects.nonNull(maxLineLength)) {
219 | builder.maxLineLength(maxLineLength);
220 | }
221 |
222 | if (provideExecutor) {
223 | builder.executor(new ThreadPoolExecutor(1, 1,
224 | 50L, TimeUnit.MILLISECONDS,
225 | new LinkedBlockingQueue<>()));
226 | }
227 |
228 | InterceptorVersion interceptorVersion = InterceptorVersion.parse(loggerVersion);
229 | switch (interceptorVersion) {
230 | case OKHTTP:
231 | OkhttpLoggingInterceptor okhttpLoggingInterceptor = builder
232 | .buildForOkhttp();
233 |
234 | final com.squareup.okhttp.Request request = new com.squareup.okhttp.Request.Builder()
235 | .url(String.valueOf(server.url("/")))
236 | .put(convertOkhtt3pRequestBody(okhttp3Request))
237 | .build();
238 |
239 | defaultOkhttpClientWithInterceptor(okhttpLoggingInterceptor)
240 | .newCall(request)
241 | .execute();
242 |
243 | return testLogger.loggerOutput(preserveTrailingSpaces);
244 |
245 | case OKHTTP3:
246 | Okhttp3LoggingInterceptor okhttp3LoggingInterceptor = builder
247 | .buildForOkhttp3();
248 |
249 | defaultOkhttp3ClientWithInterceptor(okhttp3LoggingInterceptor)
250 | .newCall(okhttp3Request)
251 | .execute();
252 |
253 | return testLogger.loggerOutput(preserveTrailingSpaces);
254 |
255 | case APACHE_HTTPCLIENT_REQUEST:
256 | final ApacheHttpRequestInterceptor requestInterceptor = builder
257 | .buildForApacheHttpClientRequest();
258 |
259 | final ApacheHttpResponseInterceptor responseInterceptor = builder
260 | .buildFordApacheHttpClientResponse();
261 |
262 | final HttpPut httpPut = new HttpPut(server.url("/").uri());
263 | final MediaType mediaType =
264 | body.contentType() == null ? MediaType
265 | .parse(ContentType.APPLICATION_JSON.toString())
266 | : body.contentType();
267 |
268 | ContentType contentType = ContentType.create(
269 | String.format("%s/%s", Objects.requireNonNull(mediaType).type(),
270 | mediaType.subtype()));
271 |
272 | final HttpEntity entity = ToApacheHttpClientConverter
273 | .okhttp3RequestBodyToStringEntity(body, contentType);
274 |
275 | httpPut.setEntity(entity);
276 | httpPut.setHeader(new BasicHeader("Content-Type", mediaType.toString()));
277 | defaultApacheClientWithInterceptors(requestInterceptor, responseInterceptor)
278 | .execute(httpPut);
279 |
280 | return testLogger.loggerOutput(preserveTrailingSpaces);
281 |
282 | default:
283 | fail(String
284 | .format(
285 | "I didn't recognize %s version. I support 'okhttp' and 'okhttp3' versions",
286 | loggerVersion));
287 | return Arrays.asList(new String[1]);
288 | }
289 | }
290 |
291 | List interceptedResponse(String contentType, String body, String loggerVersion,
292 | boolean provideExecutors, boolean preserveTrailingSpaces) throws IOException {
293 | return interceptedResponse(contentType, body, null, loggerVersion,
294 | provideExecutors, preserveTrailingSpaces);
295 | }
296 |
297 | List interceptedResponse(String contentType, String body, Integer maxLineLength,
298 | String loggerVersion,
299 | boolean provideExecutors, boolean preserveTrailingSpaces)
300 | throws IOException {
301 |
302 | server.enqueue(new MockResponse()
303 | .setResponseCode(200)
304 | .setHeader("Content-Type", contentType)
305 | .setBody(body));
306 |
307 | TestLogger testLogger = new TestLogger(LogFormatter.JUL_MESSAGE_ONLY);
308 | final LoggingInterceptor.Builder builder = new LoggingInterceptor.Builder()
309 | .logger(testLogger);
310 |
311 | if (provideExecutors) {
312 | builder.executor(new ThreadPoolExecutor(1, 1,
313 | 50L, TimeUnit.MILLISECONDS,
314 | new LinkedBlockingQueue<>()));
315 | }
316 |
317 | if (Objects.nonNull(maxLineLength)) {
318 | builder.maxLineLength(maxLineLength);
319 | }
320 |
321 | InterceptorVersion interceptorVersion = InterceptorVersion.parse(loggerVersion);
322 | switch (interceptorVersion) {
323 | case OKHTTP:
324 | OkhttpLoggingInterceptor okhttpLoggingInterceptor = builder
325 | .buildForOkhttp();
326 | defaultOkhttpClientWithInterceptor(okhttpLoggingInterceptor)
327 | .newCall(defaultOkhttpRequest())
328 | .execute();
329 | break;
330 |
331 | case OKHTTP3:
332 | Okhttp3LoggingInterceptor okhttp3LoggingInterceptor = builder
333 | .buildForOkhttp3();
334 |
335 | defaultOkhttp3ClientWithInterceptor(okhttp3LoggingInterceptor)
336 | .newCall(defaultOkhttp3Request())
337 | .execute();
338 | break;
339 |
340 | case APACHE_HTTPCLIENT_REQUEST:
341 | final ApacheHttpRequestInterceptor requestInterceptor = builder
342 | .buildForApacheHttpClientRequest();
343 |
344 | final ApacheHttpResponseInterceptor responseInterceptor = builder
345 | .buildFordApacheHttpClientResponse();
346 |
347 | defaultApacheClientWithInterceptors(requestInterceptor, responseInterceptor)
348 | .execute(defaultApacheHttpRequest());
349 | break;
350 |
351 | default:
352 | fail(String.format(
353 | "I couldn't recognize %s interceptor version. I only support okhttp and okhttp3 versions at the moment",
354 | loggerVersion));
355 | return Arrays.asList(new String[1]);
356 |
357 | }
358 |
359 | return testLogger.loggerOutput(preserveTrailingSpaces);
360 | }
361 |
362 | }
363 |
--------------------------------------------------------------------------------
/lib/src/test/java/com/dkorobtsov/logging/ClientPrintingExecutorNegativeUnitTests.java:
--------------------------------------------------------------------------------
1 | package com.dkorobtsov.logging;
2 |
3 | import java.util.concurrent.Executors;
4 | import okhttp3.Request;
5 | import org.junit.Test;
6 |
7 | public class ClientPrintingExecutorNegativeUnitTests {
8 |
9 | @Test
10 | public void testInterruptingPrintingJsonRequestDoesntCrashProcess() {
11 | final Request request = new Request.Builder()
12 | .get()
13 | .url("http://google.com")
14 | .build();
15 |
16 | final LoggerConfig loggerConfig = LoggerConfig.builder()
17 | .executor(Executors.newCachedThreadPool()).build();
18 |
19 | Thread.currentThread().interrupt();
20 | ClientPrintingExecutor.printJsonRequest(request, loggerConfig);
21 | }
22 |
23 | @Test
24 | public void testInterruptingPrintingFileRequestDoesntCrashProcess() {
25 | final Request request = new Request.Builder()
26 | .get()
27 | .url("http://google.com")
28 | .build();
29 |
30 | final LoggerConfig loggerConfig = LoggerConfig.builder()
31 | .executor(Executors.newCachedThreadPool()).build();
32 |
33 | Thread.currentThread().interrupt();
34 | ClientPrintingExecutor.printFileRequest(request, loggerConfig);
35 | }
36 |
37 | @Test
38 | public void testInterruptingPrintingJsonResponseDoesntCrashProcess() {
39 | final ResponseDetails responseDetails = ResponseDetails.builder().build();
40 | final LoggerConfig loggerConfig = LoggerConfig.builder()
41 | .executor(Executors.newCachedThreadPool()).build();
42 |
43 | Thread.currentThread().interrupt();
44 | ClientPrintingExecutor.printFileResponse(responseDetails, loggerConfig);
45 | }
46 |
47 | @Test
48 | public void testInterruptingPrintingFileResponseDoesntCrashProcess() {
49 | final ResponseDetails responseDetails = ResponseDetails.builder().build();
50 | final LoggerConfig loggerConfig = LoggerConfig.builder()
51 | .executor(Executors.newCachedThreadPool()).build();
52 |
53 | Thread.currentThread().interrupt();
54 | ClientPrintingExecutor.printFileResponse(responseDetails, loggerConfig);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/lib/src/test/java/com/dkorobtsov/logging/FormatterTest.java:
--------------------------------------------------------------------------------
1 | package com.dkorobtsov.logging;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 |
6 | public class FormatterTest {
7 |
8 | private final static String TEST_MESSAGE = "Test";
9 |
10 | @Test
11 | public void formatterTest_messageOnly_containsOneElement() {
12 | final TestLogger testLogger = new TestLogger(LogFormatter.JUL_MESSAGE_ONLY);
13 |
14 | testLogger.log(TEST_MESSAGE);
15 |
16 | TestUtil.assertLogEntryElementsCount(
17 | testLogger.lastFormattedEvent(true), 1);
18 | }
19 |
20 | @Test
21 | public void formatterTest_messageOnly_containsOnlyMessage() {
22 | final TestLogger testLogger = new TestLogger(LogFormatter.JUL_MESSAGE_ONLY);
23 |
24 | testLogger.log(TEST_MESSAGE);
25 |
26 | Assert.assertEquals("Logger output should contain message only",
27 | TEST_MESSAGE, testLogger.lastFormattedEvent(false));
28 | }
29 |
30 | @Test
31 | public void formatterTest_full_containsFourElements() {
32 | final TestLogger testLogger = new TestLogger(LogFormatter.JUL_FULL);
33 |
34 | testLogger.log(TEST_MESSAGE);
35 |
36 | TestUtil.assertLogEntryElementsCount(
37 | testLogger.lastFormattedEvent(true), 4);
38 | }
39 |
40 | @Test
41 | public void formatterTest_full_includesThreadName() {
42 | final TestLogger testLogger = new TestLogger(LogFormatter.JUL_FULL);
43 |
44 | testLogger.log(TEST_MESSAGE);
45 |
46 | Assert.assertTrue("Logger output should include thread name.",
47 | testLogger.lastFormattedEvent(true)
48 | .contains(Thread.currentThread().getName()));
49 | }
50 |
51 | @Test
52 | public void formatterTest_full_includesMessage() {
53 | final TestLogger testLogger = new TestLogger(LogFormatter.JUL_FULL);
54 |
55 | testLogger.log(TEST_MESSAGE);
56 |
57 | Assert.assertTrue("Logger output should include message text.",
58 | testLogger.lastFormattedEvent(true)
59 | .contains(TEST_MESSAGE));
60 | }
61 |
62 | @Test
63 | public void formatterTest_full_includesLevel() {
64 | final TestLogger testLogger = new TestLogger(LogFormatter.JUL_FULL);
65 |
66 | testLogger.log(TEST_MESSAGE);
67 |
68 | Assert.assertTrue("Logger output should include logging level.",
69 | testLogger.lastFormattedEvent(true)
70 | .contains("INFO"));
71 | }
72 |
73 | @Test
74 | public void formatterTest_full_startsWithDate() {
75 | final TestLogger testLogger = new TestLogger(LogFormatter.JUL_FULL);
76 |
77 | testLogger.log(TEST_MESSAGE);
78 |
79 | TestUtil.assertEntryStartsWithParsableDate(
80 | testLogger.lastFormattedEvent(true));
81 | }
82 |
83 |
84 | @Test
85 | public void formatterTest_dateMessage_containsTwoElements() {
86 | final TestLogger testLogger = new TestLogger(LogFormatter.JUL_DATE_MESSAGE);
87 |
88 | testLogger.log(TEST_MESSAGE);
89 |
90 | TestUtil.assertLogEntryElementsCount(
91 | testLogger.lastFormattedEvent(true), 2);
92 | }
93 |
94 | @Test
95 | public void formatterTest_dateMessage_includesMessage() {
96 | final TestLogger testLogger = new TestLogger(LogFormatter.JUL_DATE_MESSAGE);
97 |
98 | testLogger.log(TEST_MESSAGE);
99 |
100 | Assert.assertTrue("Logger output should include message text.",
101 | testLogger.lastFormattedEvent(true)
102 | .contains(TEST_MESSAGE));
103 | }
104 |
105 | @Test
106 | public void formatterTest_dateMessage_startsWithDate() {
107 | final TestLogger testLogger = new TestLogger(LogFormatter.JUL_DATE_MESSAGE);
108 |
109 | testLogger.log(TEST_MESSAGE);
110 |
111 | TestUtil.assertEntryStartsWithParsableDate(
112 | testLogger.lastFormattedEvent(true));
113 | }
114 |
115 | @Test
116 | public void formatterTest_dateLevelMessage_containsThreeElements() {
117 | final TestLogger testLogger = new TestLogger(LogFormatter.JUL_DATE_LEVEL_MESSAGE);
118 |
119 | testLogger.log(TEST_MESSAGE);
120 |
121 | TestUtil.assertLogEntryElementsCount(testLogger
122 | .lastFormattedEvent(true), 3);
123 | }
124 |
125 | @Test
126 | public void formatterTest_dateLevelMessage_includesMessage() {
127 | final TestLogger testLogger = new TestLogger(LogFormatter.JUL_DATE_LEVEL_MESSAGE);
128 |
129 | testLogger.log(TEST_MESSAGE);
130 |
131 | Assert.assertTrue("Logger output should include message text.",
132 | testLogger.lastFormattedEvent(true)
133 | .contains(TEST_MESSAGE));
134 | }
135 |
136 | @Test
137 | public void formatterTest_dateLevelMessage_includesLevel() {
138 | final TestLogger testLogger = new TestLogger(LogFormatter.JUL_DATE_LEVEL_MESSAGE);
139 |
140 | testLogger.log(TEST_MESSAGE);
141 |
142 | Assert.assertTrue("Logger output should include logging level.",
143 | testLogger.lastFormattedEvent(true)
144 | .contains("INFO"));
145 | }
146 |
147 | @Test
148 | public void formatterTest_dateLevelMessage_startsWithDate() {
149 | final TestLogger testLogger = new TestLogger(LogFormatter.JUL_DATE_LEVEL_MESSAGE);
150 |
151 | testLogger.log(TEST_MESSAGE);
152 |
153 | TestUtil.assertEntryStartsWithParsableDate(
154 | testLogger.lastFormattedEvent(true));
155 | }
156 |
157 | @Test
158 | public void formatterTest_levelMessage_containsTwoElements() {
159 | final TestLogger testLogger = new TestLogger(LogFormatter.JUL_LEVEL_MESSAGE);
160 |
161 | testLogger.log(TEST_MESSAGE);
162 |
163 | TestUtil.assertLogEntryElementsCount(
164 | testLogger.lastFormattedEvent(true), 2);
165 | }
166 |
167 | @Test
168 | public void formatterTest_levelMessage_includesMessage() {
169 | final TestLogger testLogger = new TestLogger(LogFormatter.JUL_LEVEL_MESSAGE);
170 |
171 | testLogger.log(TEST_MESSAGE);
172 |
173 | Assert.assertTrue("Logger output should include message text.",
174 | testLogger.lastFormattedEvent(true)
175 | .contains(TEST_MESSAGE));
176 | }
177 |
178 | @Test
179 | public void formatterTest_levelMessage_containsLevel() {
180 | final TestLogger testLogger = new TestLogger(LogFormatter.JUL_LEVEL_MESSAGE);
181 |
182 | testLogger.log(TEST_MESSAGE);
183 |
184 | Assert.assertTrue("Logger output should include logging level.",
185 | testLogger.lastFormattedEvent(true)
186 | .contains("INFO"));
187 | }
188 |
189 | @Test
190 | public void formatterTest_threadMessage_containsTwoElements() {
191 | final TestLogger testLogger = new TestLogger(LogFormatter.JUL_LEVEL_MESSAGE);
192 |
193 | testLogger.log(TEST_MESSAGE);
194 |
195 | TestUtil.assertLogEntryElementsCount(
196 | testLogger.lastFormattedEvent(true), 2);
197 | }
198 |
199 | @Test
200 | public void formatterTest_threadMessage_includesMessage() {
201 | final TestLogger testLogger = new TestLogger(LogFormatter.JUL_THREAD_MESSAGE);
202 |
203 | testLogger.log(TEST_MESSAGE);
204 |
205 | Assert.assertTrue("Logger output should include message text.",
206 | testLogger.lastFormattedEvent(true)
207 | .contains(TEST_MESSAGE));
208 | }
209 |
210 | @Test
211 | public void formatterTest_threadMessage_containsThreadName() {
212 | final TestLogger testLogger = new TestLogger(LogFormatter.JUL_THREAD_MESSAGE);
213 |
214 | testLogger.log(TEST_MESSAGE);
215 |
216 | Assert.assertTrue("Logger output should include thread name.",
217 | testLogger.lastFormattedEvent(true)
218 | .contains(Thread.currentThread().getName()));
219 | }
220 |
221 | }
222 |
--------------------------------------------------------------------------------
/lib/src/test/java/com/dkorobtsov/logging/InterceptorBodyHandlingTest.java:
--------------------------------------------------------------------------------
1 | package com.dkorobtsov.logging;
2 |
3 | import static org.assertj.core.api.Assertions.assertThat;
4 |
5 | import java.io.ByteArrayInputStream;
6 | import java.io.File;
7 | import java.io.IOException;
8 | import java.nio.charset.StandardCharsets;
9 | import java.util.List;
10 | import junitparams.JUnitParamsRunner;
11 | import junitparams.Parameters;
12 | import okhttp3.MediaType;
13 | import okhttp3.RequestBody;
14 | import okio.BufferedSink;
15 | import okio.Okio;
16 | import okio.Source;
17 | import org.junit.Rule;
18 | import org.junit.Test;
19 | import org.junit.rules.TemporaryFolder;
20 | import org.junit.runner.RunWith;
21 |
22 | @RunWith(JUnitParamsRunner.class)
23 | public class InterceptorBodyHandlingTest extends BaseTest {
24 |
25 | private static final String SIMPLE_JSON = "{name: \"John\", age: 31, city: \"New York\"}";
26 |
27 | private static final String PREFORMATTED_JSON_BODY = ""
28 | + " {\n"
29 | + " \"id\": 431169,\n"
30 | + " \"category\": {\n"
31 | + " \"id\": 0,\n"
32 | + " \"name\": \"string\"\n"
33 | + " },\n"
34 | + " \"name\": \"doggie\",\n"
35 | + " \"photoUrls\": [\n"
36 | + " \"string\"\n"
37 | + " ],\n"
38 | + " \"tags\": [\n"
39 | + " {\n"
40 | + " \"id\": 0,\n"
41 | + " \"name\": \"string\"\n"
42 | + " }\n"
43 | + " ],\n"
44 | + " \"status\": \"available\"\n"
45 | + " }";
46 |
47 | private static final String MALFORMED_JSON_BODY = ""
48 | + " {\n"
49 | + " \"id\": 431169,\n"
50 | + " \"category\": {\n"
51 | + " \"id\": 0,\n"
52 | + " \"name\": \"string\"\n"
53 | + " \"name\": \"doggie\",\n"
54 | + " \"photoUrls\": [\n"
55 | + " \"string\"\n"
56 | + " \"tags\": [\n"
57 | + " {\n"
58 | + " \"id\": 0,\n"
59 | + " \"name\": \"string\"\n"
60 | + " }\n"
61 | + " ],\n"
62 | + " \"status\": \"available\"\n"
63 | + " }";
64 |
65 | private static final String XML_BODY =
66 | ""
67 | + ""
68 | + "Goat"
69 | + "Leopard"
70 | + "Zebra "
71 | + "";
72 |
73 | private static final String MALFORMED_XML_BODY =
74 | ""
75 | + ""
76 | + "Goat"
77 | + "animal id=\"1\" species=\"Panthera pardus\">Leopard"
78 | + "Zebra "
79 | + "";
80 |
81 | private static final String HTML_BODY = ""
82 | + ""
83 | + "Error 404 Not Found"
84 | + "HTTP ERROR 404
"
85 | + "
Not Found
| | | |
";
86 |
87 | private static final String MALFORMED_HTML_BODY = ""
88 | + ""
89 | + "Error 404 Not Found"
90 | + "HTTP ERROR 404
"
91 | + "
Not Found
| | | |
";
92 |
93 | @Rule
94 | public TemporaryFolder temporaryFolder = new TemporaryFolder();
95 |
96 | @Test
97 | @Parameters({
98 | "okhttp, true", "okhttp, false",
99 | "okhttp3, true", "okhttp3, false",
100 | "apacheHttpclientRequest, true", "apacheHttpclientRequest, false"
101 | })
102 | public void interceptorAbleToHandleBody_simpleJsonRequest(String loggerVersion,
103 | boolean provideExecutor)
104 | throws IOException {
105 | final List loggerOutput = interceptedRequest(RequestBody
106 | .create(MediaType.parse("application/json"), SIMPLE_JSON),
107 | loggerVersion, provideExecutor, true);
108 |
109 | assertThat(loggerOutput).contains(" \"city\": \"New York\", ");
110 | }
111 |
112 | @Test
113 | @Parameters({
114 | "okhttp, true", "okhttp, false",
115 | "okhttp3, true", "okhttp3, false",
116 | "apacheHttpclientRequest, true", "apacheHttpclientRequest, false"
117 | })
118 | public void interceptorAbleToHandleBody_simpleJsonResponse(String loggerVersion,
119 | boolean provideExecutor) throws IOException {
120 | final List loggerOutput = interceptedResponse("application/json", SIMPLE_JSON,
121 | loggerVersion, provideExecutor, true);
122 |
123 | assertThat(loggerOutput).contains(" \"city\": \"New York\", ");
124 | }
125 |
126 | @Test
127 | @Parameters({
128 | "okhttp, true", "okhttp, false",
129 | "okhttp3, true", "okhttp3, false",
130 | "apacheHttpclientRequest, true", "apacheHttpclientRequest, false"
131 | })
132 | public void interceptorAbleToHandleBody_preformattedJsonRequest(String loggerVersion,
133 | boolean provideExecutor)
134 | throws IOException {
135 | final List loggerOutput = interceptedRequest(RequestBody
136 | .create(MediaType.parse("application/json"), PREFORMATTED_JSON_BODY),
137 | loggerVersion, provideExecutor, true);
138 |
139 | assertThat(loggerOutput).containsSequence(" \"name\": \"doggie\", ");
140 | }
141 |
142 | @Test
143 | @Parameters({
144 | "okhttp, true", "okhttp, false",
145 | "okhttp3, true", "okhttp3, false",
146 | "apacheHttpclientRequest, true", "apacheHttpclientRequest, false"
147 | })
148 | public void interceptorAbleToHandleBody_preformattedJsonResponse(String loggerVersion,
149 | boolean provideExecutor) throws IOException {
150 | final List loggerOutput = interceptedResponse("application/json",
151 | PREFORMATTED_JSON_BODY,
152 | loggerVersion, provideExecutor, true);
153 |
154 | assertThat(loggerOutput).containsSequence(" \"name\": \"doggie\", ");
155 | }
156 |
157 | @Test
158 | @Parameters({
159 | "okhttp, true", "okhttp, false",
160 | "okhttp3, true", "okhttp3, false",
161 | "apacheHttpclientRequest, true", "apacheHttpclientRequest, false"
162 | })
163 | public void interceptorAbleToHandleBody_malformedJsonRequest(String loggerVersion,
164 | boolean provideExecutor) throws IOException {
165 | final List loggerOutput = interceptedRequest(RequestBody
166 | .create(MediaType.parse("application/json"), MALFORMED_JSON_BODY), loggerVersion,
167 | provideExecutor, false);
168 |
169 | loggerOutput
170 | .stream()
171 | .filter(it ->
172 | it.startsWith("\"status\": \"available\""))
173 | .findFirst()
174 | .orElseThrow(() ->
175 | new AssertionError("Interceptor should be able to handle xml response body."));
176 | }
177 |
178 | @Test
179 | @Parameters({
180 | "okhttp, true", "okhttp, false",
181 | "okhttp3, true", "okhttp3, false",
182 | "apacheHttpclientRequest, true", "apacheHttpclientRequest, false"
183 | })
184 | public void interceptorAbleToHandleBody_malformedJsonResponse(String loggerVersion,
185 | boolean provideExecutor) throws IOException {
186 | final List loggerOutput = interceptedResponse(
187 | "application/json", MALFORMED_JSON_BODY, loggerVersion, provideExecutor, false);
188 |
189 | loggerOutput
190 | .stream()
191 | .filter(it ->
192 | it.startsWith("\"status\": \"available\""))
193 | .findFirst()
194 | .orElseThrow(() ->
195 | new AssertionError("Interceptor should be able to handle xml response body."));
196 | }
197 |
198 | @Test
199 | @Parameters({
200 | "okhttp, true", "okhttp, false",
201 | "okhttp3, true", "okhttp3, false",
202 | "apacheHttpclientRequest, true", "apacheHttpclientRequest, false"
203 | })
204 | public void interceptorAbleToHandleBody_htmlRequest(String loggerVersion,
205 | boolean provideExecutor)
206 | throws IOException {
207 | final List loggerOutput = interceptedRequest(RequestBody
208 | .create(MediaType.parse("text/html"), HTML_BODY),
209 | loggerVersion, provideExecutor, false);
210 |
211 | assertThat(loggerOutput).contains("Error 404 Not Found");
212 | }
213 |
214 | @Test
215 | @Parameters({
216 | "okhttp, true", "okhttp, false",
217 | "okhttp3, true", "okhttp3, false",
218 | "apacheHttpclientRequest, true", "apacheHttpclientRequest, false"
219 | })
220 | public void interceptorAbleToHandleBody_htmlResponse(String loggerVersion,
221 | boolean provideExecutor)
222 | throws IOException {
223 | final List loggerOutput = interceptedResponse(
224 | "text/html", HTML_BODY, loggerVersion, provideExecutor, false);
225 |
226 | assertThat(loggerOutput).contains("Error 404 Not Found");
227 | }
228 |
229 | @Test
230 | @Parameters({
231 | "okhttp, true", "okhttp, false",
232 | "okhttp3, true", "okhttp3, false",
233 | "apacheHttpclientRequest, true", "apacheHttpclientRequest, false"
234 | })
235 | public void interceptorAbleToHandleBody_malformedHtmlRequest(String loggerVersion,
236 | boolean provideExecutor) throws IOException {
237 | final List loggerOutput = interceptedRequest(RequestBody
238 | .create(MediaType.parse("text/html"), MALFORMED_HTML_BODY), loggerVersion,
239 | provideExecutor, false);
240 |
241 | loggerOutput
242 | .stream()
243 | .filter(it ->
244 | it.startsWith(
245 | ""))
246 | .findFirst()
247 | .orElseThrow(() ->
248 | new AssertionError("Interceptor should be able to handle html request body."));
249 | }
250 |
251 | @Test
252 | @Parameters({
253 | "okhttp, true", "okhttp, false",
254 | "okhttp3, true", "okhttp3, false",
255 | "apacheHttpclientRequest, true", "apacheHttpclientRequest, false"
256 | })
257 | public void interceptorAbleToHandleBody_malformedHtmlResponse(String loggerVersion,
258 | boolean provideExecutor) throws IOException {
259 | final List loggerOutput = interceptedResponse(
260 | "text/html", MALFORMED_HTML_BODY, loggerVersion, provideExecutor, false);
261 |
262 | loggerOutput
263 | .stream()
264 | .filter(it ->
265 | it.startsWith(
266 | ""))
267 | .findFirst()
268 | .orElseThrow(() ->
269 | new AssertionError("Interceptor should be able to handle html response body."));
270 | }
271 |
272 | @Test
273 | @Parameters({
274 | "okhttp, true", "okhttp, false",
275 | "okhttp3, true", "okhttp3, false",
276 | "apacheHttpclientRequest, true", "apacheHttpclientRequest, false"
277 | })
278 | public void interceptorAbleToHandleBody_xmlRequest(String loggerVersion,
279 | boolean provideExecutor)
280 | throws IOException {
281 | final List loggerOutput = interceptedRequest(RequestBody
282 | .create(MediaType.parse("application/xml"), XML_BODY),
283 | loggerVersion, provideExecutor, false);
284 |
285 | assertThat(loggerOutput).contains("");
286 | assertThat(loggerOutput).contains("");
287 | }
288 |
289 | @Test
290 | @Parameters({
291 | "okhttp, true", "okhttp, false",
292 | "okhttp3, true", "okhttp3, false",
293 | "apacheHttpclientRequest, true", "apacheHttpclientRequest, false"
294 | })
295 | public void interceptorAbleToHandleBody_xmlResponse(String loggerVersion,
296 | boolean provideExecutor)
297 | throws IOException {
298 | final List loggerOutput = interceptedResponse("application/xml", XML_BODY,
299 | loggerVersion,
300 | provideExecutor, false);
301 |
302 | assertThat(loggerOutput).contains("");
303 | assertThat(loggerOutput).contains("");
304 | }
305 |
306 | @Test
307 | @Parameters({
308 | "okhttp, true", "okhttp, false",
309 | "okhttp3, true", "okhttp3, false",
310 | "apacheHttpclientRequest, true", "apacheHttpclientRequest, false"
311 | })
312 | public void interceptorAbleToHandleBody_malformedXmlRequest(String loggerVersion,
313 | boolean provideExecutor) throws IOException {
314 | final List loggerOutput = interceptedRequest(RequestBody
315 | .create(MediaType.parse("application/xml"), MALFORMED_XML_BODY), loggerVersion,
316 | provideExecutor, false);
317 |
318 | loggerOutput
319 | .stream()
320 | .filter(it ->
321 | it.startsWith(
322 | ""))
323 | .findFirst()
324 | .orElseThrow(() ->
325 | new AssertionError("Interceptor should be able to handle xml request body."));
326 | }
327 |
328 | @Test
329 | @Parameters({
330 | "okhttp, true", "okhttp, false",
331 | "okhttp3, true", "okhttp3, false",
332 | "apacheHttpclientRequest, true", "apacheHttpclientRequest, false"
333 | })
334 | public void interceptorAbleToHandleBody_malformedXmlResponse(String loggerVersion,
335 | boolean provideExecutor) throws IOException {
336 | final List loggerOutput = interceptedResponse("application/xml", MALFORMED_XML_BODY,
337 | loggerVersion, provideExecutor, false);
338 |
339 | loggerOutput
340 | .stream()
341 | .filter(it ->
342 | it.startsWith(
343 | ""))
344 | .findFirst()
345 | .orElseThrow(() ->
346 | new AssertionError("Interceptor should be able to handle xml response body."));
347 | }
348 |
349 | @Test
350 | @Parameters({
351 | "okhttp, true", "okhttp, false",
352 | "okhttp3, true", "okhttp3, false",
353 | "apacheHttpclientRequest, true", "apacheHttpclientRequest, false"
354 | })
355 | public void interceptorAbleToHandleBody_fileRequest(String loggerVersion,
356 | boolean provideExecutor)
357 | throws IOException {
358 | RequestBody body = RequestBody.create(MediaType.parse("application/zip"),
359 | createFileFromString(PREFORMATTED_JSON_BODY));
360 |
361 | final List loggerOutput = interceptedRequest(body, loggerVersion, provideExecutor,
362 | true);
363 |
364 | assertThat(loggerOutput).contains(" Omitted response body ");
365 | }
366 |
367 | @Test
368 | @Parameters({
369 | "okhttp, true", "okhttp, false",
370 | "okhttp3, true", "okhttp3, false",
371 | "apacheHttpclientRequest, true", "apacheHttpclientRequest, false"
372 | })
373 | public void interceptorAbleToHandleBody_fileResponse(String loggerVersion,
374 | boolean provideExecutor) throws IOException {
375 | final List loggerOutput = interceptedResponse("application/zip",
376 | String.valueOf(createFileFromString(PREFORMATTED_JSON_BODY)), loggerVersion,
377 | provideExecutor, true);
378 |
379 | assertThat(loggerOutput).contains(" Omitted response body ");
380 | }
381 |
382 | @SuppressWarnings("SameParameterValue")
383 | private File createFileFromString(String val) throws IOException {
384 | File file = temporaryFolder.newFile();
385 | byte[] bytes = val.getBytes(StandardCharsets.UTF_8);
386 | Source source = Okio.source(new ByteArrayInputStream(bytes));
387 | try (BufferedSink b = Okio.buffer(Okio.sink(file))) {
388 | b.writeAll(source);
389 | }
390 | return file;
391 | }
392 |
393 |
394 | }
395 |
--------------------------------------------------------------------------------
/lib/src/test/java/com/dkorobtsov/logging/Log4j2LoggerTest.java:
--------------------------------------------------------------------------------
1 | package com.dkorobtsov.logging;
2 |
3 | import static org.junit.Assert.assertFalse;
4 | import static org.junit.Assert.assertTrue;
5 |
6 | import com.squareup.okhttp.mockwebserver.MockResponse;
7 | import java.io.IOException;
8 | import java.io.StringWriter;
9 | import java.io.Writer;
10 | import junitparams.JUnitParamsRunner;
11 | import junitparams.Parameters;
12 | import org.apache.logging.log4j.Level;
13 | import org.apache.logging.log4j.LogManager;
14 | import org.apache.logging.log4j.Logger;
15 | import org.apache.logging.log4j.core.Appender;
16 | import org.apache.logging.log4j.core.Filter;
17 | import org.apache.logging.log4j.core.LoggerContext;
18 | import org.apache.logging.log4j.core.appender.ConsoleAppender;
19 | import org.apache.logging.log4j.core.appender.WriterAppender;
20 | import org.apache.logging.log4j.core.config.Configuration;
21 | import org.apache.logging.log4j.core.config.Configurator;
22 | import org.apache.logging.log4j.core.config.LoggerConfig;
23 | import org.apache.logging.log4j.core.config.builder.api.AppenderComponentBuilder;
24 | import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder;
25 | import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory;
26 | import org.apache.logging.log4j.core.config.builder.api.LayoutComponentBuilder;
27 | import org.apache.logging.log4j.core.config.builder.api.RootLoggerComponentBuilder;
28 | import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration;
29 | import org.apache.logging.log4j.core.layout.PatternLayout;
30 | import org.junit.BeforeClass;
31 | import org.junit.Test;
32 | import org.junit.runner.RunWith;
33 |
34 | @RunWith(JUnitParamsRunner.class)
35 | public class Log4j2LoggerTest extends BaseTest {
36 |
37 | private final Logger log = LogManager.getLogger(Log4j2LoggerTest.class);
38 |
39 | private static final String ROOT_LOG_PATTERN = "%d{HH:mm:ss.SSS} [%t] %-5level %c{0}:%L - %msg%n";
40 | private static final StringWriter logWriter = new StringWriter();
41 |
42 | @BeforeClass
43 | public static void configureLogger() throws IOException {
44 | initializeBaseLog4j2Configuration();
45 | }
46 |
47 | @Test
48 | @Parameters({
49 | "okhttp", "okhttp3"
50 | })
51 | public void interceptorCanBeConfiguredToPrintLogWithLog4j2(String interceptorVersion)
52 | throws IOException {
53 | server.enqueue(new MockResponse().setResponseCode(200));
54 | final String OK_HTTP_LOG_PATTERN = "[OkHTTP] %msg%n";
55 |
56 | log.debug("Configuring custom Log4j2 logger for intercepted OkHttp traffic.");
57 | LogWriter log4j2Writer = new LogWriter() {
58 |
59 | final Logger log = LogManager.getLogger("OkHttpLogger");
60 |
61 | {
62 | final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
63 | final Configuration config = ctx.getConfiguration();
64 |
65 | LoggerConfig loggerConfig = new LoggerConfig("OkHttpLogger", Level.TRACE, false);
66 | PatternLayout layout = PatternLayout
67 | .newBuilder()
68 | .withPattern(OK_HTTP_LOG_PATTERN)
69 | .build();
70 |
71 | final Appender appender = ConsoleAppender
72 | .newBuilder()
73 | .withName("OkHttpConsoleAppender")
74 | .withLayout(layout)
75 | .build();
76 |
77 | appender.start();
78 |
79 | loggerConfig.addAppender(appender, Level.TRACE, null);
80 | config.addLogger("OkHttpLogger", loggerConfig);
81 | ctx.updateLoggers();
82 | }
83 |
84 | @Override
85 | public void log(String msg) {
86 | log.debug(msg);
87 | }
88 | };
89 |
90 | log.debug("Adding test double appender for output validation.");
91 | addAppender(logWriter, "TestWriter", OK_HTTP_LOG_PATTERN);
92 |
93 | log.debug("Attaching custom logger to interceptor.");
94 | attachLoggerToInterceptorWithDefaultRequest(interceptorVersion, log4j2Writer);
95 |
96 | log.debug("Retrieving logger output for validation.");
97 | final String logOutput = logWriter.toString();
98 |
99 | assertFalse("Severity tag should not be present in custom OkHTTP logger output.",
100 | logOutput.contains("DEBUG"));
101 |
102 | assertTrue("Logger name should be present as defined by logging pattern.",
103 | logOutput.contains("OkHTTP"));
104 |
105 | assertTrue("Request section should be present in logger output.",
106 | logOutput.contains("Request"));
107 |
108 | assertTrue("Response section should be present in logger output.",
109 | logOutput.contains("Response"));
110 |
111 | }
112 |
113 | private static void initializeBaseLog4j2Configuration() throws IOException {
114 | ConfigurationBuilder builder
115 | = ConfigurationBuilderFactory.newConfigurationBuilder();
116 |
117 | AppenderComponentBuilder console = builder.newAppender("stdout", "Console");
118 | LayoutComponentBuilder layout = builder.newLayout("PatternLayout");
119 | layout.addAttribute("pattern", ROOT_LOG_PATTERN);
120 | console.add(layout);
121 | builder.add(console);
122 |
123 | RootLoggerComponentBuilder rootLogger = builder.newRootLogger(Level.DEBUG);
124 | rootLogger.add(builder.newAppenderRef("stdout"));
125 | builder.add(rootLogger);
126 |
127 | builder.writeXmlConfiguration(System.out);
128 | Configurator.initialize(builder.build());
129 | }
130 |
131 | private static void addAppender(final Writer writer, final String writerName, String pattern) {
132 | final LoggerContext context = LoggerContext.getContext(false);
133 | final Configuration config = context.getConfiguration();
134 |
135 | PatternLayout layout = PatternLayout.newBuilder().withPattern(pattern).build();
136 |
137 | final Appender appender = WriterAppender
138 | .createAppender(layout, null, writer, writerName, false, true);
139 | appender.start();
140 | config.addAppender(appender);
141 | updateLoggers(appender, config);
142 | }
143 |
144 | private static void updateLoggers(final Appender appender, final Configuration config) {
145 | final Level level = null;
146 | final Filter filter = null;
147 | for (final LoggerConfig loggerConfig : config.getLoggers().values()) {
148 | loggerConfig.addAppender(appender, level, filter);
149 | }
150 | config.getRootLogger().addAppender(appender, level, filter);
151 | }
152 |
153 | }
154 |
--------------------------------------------------------------------------------
/lib/src/test/java/com/dkorobtsov/logging/LoggingInterceptorUnitTests.java:
--------------------------------------------------------------------------------
1 | package com.dkorobtsov.logging;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 |
6 | public class LoggingInterceptorUnitTests {
7 |
8 | @Test
9 | public void testDefaultLogFormatterIsMessageOnly() {
10 | final LoggingInterceptor.Builder builder = new LoggingInterceptor.Builder();
11 | Assert
12 | .assertEquals("Default logger", LogFormatter.JUL_MESSAGE_ONLY, builder.getFormatter());
13 | }
14 |
15 | @Test
16 | public void testSettingFormatForLoggingInterceptor() {
17 | final LoggingInterceptor.Builder builder = new LoggingInterceptor
18 | .Builder();
19 | final LogFormatter format = LogFormatter.JUL_DATE_LEVEL_MESSAGE;
20 | builder.format(format);
21 | Assert.assertEquals("Log Formatter", format, builder.getFormatter());
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/lib/src/test/java/com/dkorobtsov/logging/LoggingInterceptorsTests.java:
--------------------------------------------------------------------------------
1 | package com.dkorobtsov.logging;
2 |
3 | import static org.junit.Assert.assertEquals;
4 | import static org.junit.Assert.assertFalse;
5 | import static org.junit.Assert.assertTrue;
6 | import static org.junit.Assert.fail;
7 |
8 | import com.dkorobtsov.logging.interceptors.ApacheHttpRequestInterceptor;
9 | import com.dkorobtsov.logging.interceptors.ApacheHttpResponseInterceptor;
10 | import com.dkorobtsov.logging.interceptors.Okhttp3LoggingInterceptor;
11 | import com.dkorobtsov.logging.interceptors.OkhttpLoggingInterceptor;
12 | import com.squareup.okhttp.mockwebserver.MockResponse;
13 | import java.io.IOException;
14 | import java.util.concurrent.Executors;
15 | import junitparams.JUnitParamsRunner;
16 | import junitparams.Parameters;
17 | import org.junit.Test;
18 | import org.junit.runner.RunWith;
19 |
20 | @RunWith(JUnitParamsRunner.class)
21 | public class LoggingInterceptorsTests extends BaseTest {
22 |
23 | @Test
24 | @Parameters({
25 | "okhttp", "okhttp3", "apacheHttpclientRequest"
26 | })
27 | public void loggerShouldWorkWithoutAnyAdditionalConfiguration(String interceptorVersion)
28 | throws IOException {
29 | server.enqueue(new MockResponse().setResponseCode(200));
30 | TestLogger testLogger = new TestLogger(LogFormatter.JUL_MESSAGE_ONLY);
31 | intercepWithSimpleInterceptor(interceptorVersion, testLogger);
32 |
33 | assertTrue("Logger should publish events using only default configuration",
34 | testLogger.firstFormattedEvent(true)
35 | .contains("Request"));
36 | }
37 |
38 | @Test
39 | @Parameters({
40 | "okhttp", "okhttp3", "apacheHttpclientRequest"
41 | })
42 | public void loggerWithDefaultFormatterShouldPrintMessageOnly(String interceptorVersion)
43 | throws IOException {
44 | server.enqueue(new MockResponse().setResponseCode(200));
45 | TestLogger testLogger = new TestLogger(LogFormatter.JUL_MESSAGE_ONLY);
46 | intercepWithSimpleInterceptor(interceptorVersion, testLogger);
47 |
48 | //Comparing message by length since on Gradle runner characters may be different
49 | //unless GradleVM executes with -Dfile.encoding=utf-8 option
50 | assertEquals("Logger with default formatter should publish message only",
51 | testLogger.firstRawEvent().length(),
52 | testLogger.firstFormattedEvent(false).length());
53 | }
54 |
55 | private void intercepWithSimpleInterceptor(String interceptorVersion, TestLogger testLogger)
56 | throws IOException {
57 | if (interceptorVersion.equals(InterceptorVersion.OKHTTP3.getName())) {
58 | Okhttp3LoggingInterceptor interceptor = new LoggingInterceptor.Builder()
59 | .logger(testLogger)
60 | .buildForOkhttp3();
61 |
62 | defaultOkhttp3ClientWithInterceptor(interceptor)
63 | .newCall(defaultOkhttp3Request())
64 | .execute();
65 | } else if (interceptorVersion.equals(InterceptorVersion.OKHTTP.getName())) {
66 | final OkhttpLoggingInterceptor interceptor = new LoggingInterceptor.Builder()
67 | .logger(testLogger)
68 | .buildForOkhttp();
69 | defaultOkhttpClientWithInterceptor(interceptor)
70 | .newCall(defaultOkhttpRequest())
71 | .execute();
72 | } else if (interceptorVersion
73 | .equals(InterceptorVersion.APACHE_HTTPCLIENT_REQUEST.getName())) {
74 | final ApacheHttpRequestInterceptor requestInterceptor = new LoggingInterceptor.Builder()
75 | .logger(testLogger)
76 | .buildForApacheHttpClientRequest();
77 | final ApacheHttpResponseInterceptor responseInterceptor = new LoggingInterceptor.Builder()
78 | .logger(testLogger)
79 | .buildFordApacheHttpClientResponse();
80 | defaultApacheClientWithInterceptors(requestInterceptor, responseInterceptor)
81 | .execute(defaultApacheHttpRequest());
82 | } else {
83 | fail("Only okhttp and okhttp3 versions are supported");
84 | }
85 | }
86 |
87 | @Test
88 | @Parameters({
89 | "okhttp", "okhttp3", "apacheHttpclientRequest"
90 | })
91 | public void loggerShouldBeDisabledWhenDebugModeSetToFalse(String interceptorVersion)
92 | throws IOException {
93 | server.enqueue(new MockResponse().setResponseCode(200));
94 | TestLogger testLogger = new TestLogger(LogFormatter.JUL_MESSAGE_ONLY);
95 | interceptWithSimpleLoggableInterceptor(interceptorVersion, testLogger, false);
96 |
97 | assertTrue("Logger output should be empty if debug mode is off.",
98 | testLogger.formattedOutput().isEmpty());
99 | }
100 |
101 | @Test
102 | @Parameters({
103 | "okhttp", "okhttp3", "apacheHttpclientRequest"
104 | })
105 | public void loggerShouldBeEnabledWhenDebugModeSetToTrue(String interceptorVersion)
106 | throws IOException {
107 | server.enqueue(new MockResponse().setResponseCode(200));
108 | TestLogger testLogger = new TestLogger(LogFormatter.JUL_MESSAGE_ONLY);
109 | interceptWithSimpleLoggableInterceptor(interceptorVersion, testLogger, true);
110 |
111 | assertTrue("Logger should publish intercepted events if debug mode is on.",
112 | testLogger.firstFormattedEvent(true)
113 | .contains("Request"));
114 | }
115 |
116 | @Test
117 | @Parameters({
118 | "okhttp", "okhttp3", "apacheHttpclientRequest"
119 | })
120 | public void defaultLoggerFormatCanBeModified(String interceptorVersion) throws IOException {
121 | server.enqueue(new MockResponse().setResponseCode(200));
122 | TestLogger testLogger = new TestLogger(LogFormatter.JUL_DATE_LEVEL_MESSAGE);
123 | interceptWithSimpleLoggableInterceptor(interceptorVersion, testLogger, true);
124 |
125 | String logEntry = testLogger.lastFormattedEvent(true);
126 |
127 | TestUtil.assertLogEntryElementsCount(logEntry, 3);
128 | TestUtil.assertEntryStartsWithParsableDate(logEntry);
129 | }
130 |
131 | private void interceptWithSimpleLoggableInterceptor(String interceptorVersion,
132 | TestLogger testLogger, boolean loggable) throws IOException {
133 | if (interceptorVersion.equals(InterceptorVersion.OKHTTP3.getName())) {
134 | Okhttp3LoggingInterceptor interceptor = new LoggingInterceptor.Builder()
135 | .loggable(loggable)
136 | .logger(testLogger)
137 | .buildForOkhttp3();
138 |
139 | defaultOkhttp3ClientWithInterceptor(interceptor)
140 | .newCall(defaultOkhttp3Request())
141 | .execute();
142 | } else if (interceptorVersion.equals(InterceptorVersion.OKHTTP.getName())) {
143 | final OkhttpLoggingInterceptor interceptor = new LoggingInterceptor.Builder()
144 | .logger(testLogger)
145 | .loggable(loggable)
146 | .buildForOkhttp();
147 | defaultOkhttpClientWithInterceptor(interceptor)
148 | .newCall(defaultOkhttpRequest())
149 | .execute();
150 | } else if (interceptorVersion
151 | .equals(InterceptorVersion.APACHE_HTTPCLIENT_REQUEST.getName())) {
152 | final ApacheHttpRequestInterceptor requestInterceptor = new LoggingInterceptor.Builder()
153 | .logger(testLogger)
154 | .loggable(loggable)
155 | .buildForApacheHttpClientRequest();
156 | final ApacheHttpResponseInterceptor responseInterceptor = new LoggingInterceptor.Builder()
157 | .logger(testLogger)
158 | .loggable(loggable)
159 | .buildFordApacheHttpClientResponse();
160 | defaultApacheClientWithInterceptors(requestInterceptor, responseInterceptor)
161 | .execute(defaultApacheHttpRequest());
162 | } else {
163 | fail("Only okhttp and okhttp3 versions are supported");
164 | }
165 | }
166 |
167 | @Test
168 | @Parameters({
169 | "okhttp", "okhttp3", "apacheHttpclientRequest"
170 | })
171 | public void loggerShouldBeDisabledWhenLevelSetToNone(String interceptorVersion)
172 | throws IOException {
173 | server.enqueue(new MockResponse().setResponseCode(200));
174 | TestLogger testLogger = new TestLogger(LogFormatter.JUL_THREAD_MESSAGE);
175 | interceptWithLogLevelInterceptor(interceptorVersion, testLogger, Level.NONE);
176 |
177 | assertTrue("Logger output should be empty if debug mode is off.",
178 | testLogger.formattedOutput().isEmpty());
179 | }
180 |
181 | @Test
182 | @Parameters({
183 | "okhttp", "okhttp3", "apacheHttpclientRequest"
184 | })
185 | public void headersShouldNotBeLoggedWhenLevelSetToBody(String interceptorVersion)
186 | throws IOException {
187 | server.enqueue(new MockResponse().setResponseCode(200));
188 | TestLogger testLogger = new TestLogger(LogFormatter.JUL_THREAD_MESSAGE);
189 | interceptWithLogLevelInterceptor(interceptorVersion, testLogger, Level.BODY);
190 |
191 | assertFalse("Headers should not be logged when level set to Body.",
192 | testLogger.formattedOutput().contains("Headers"));
193 | }
194 |
195 | @Test
196 | @Parameters({
197 | "okhttp", "okhttp3", "apacheHttpclientRequest"
198 | })
199 | public void bodyShouldNotBeLoggedWhenLevelSetToHeaders(String interceptorVersion)
200 | throws IOException {
201 | server.enqueue(new MockResponse().setResponseCode(200));
202 | TestLogger testLogger = new TestLogger(LogFormatter.JUL_THREAD_MESSAGE);
203 | interceptWithLogLevelInterceptor(interceptorVersion, testLogger, Level.HEADERS);
204 |
205 | assertFalse("Body should not be logged when level set to Headers.",
206 | testLogger.formattedOutput().contains("body"));
207 | }
208 |
209 | @Test
210 | @Parameters({
211 | "okhttp", "okhttp3", "apacheHttpclientRequest"
212 | })
213 | public void allDetailsShouldBePrintedIfLevelSetToBasic(String interceptorVersion)
214 | throws IOException {
215 | server.enqueue(new MockResponse().setResponseCode(200));
216 | TestLogger testLogger = new TestLogger(LogFormatter.JUL_THREAD_MESSAGE);
217 | interceptWithLogLevelInterceptor(interceptorVersion, testLogger, Level.BASIC);
218 |
219 | assertTrue("Request section should be present in logger output.",
220 | testLogger.formattedOutput().contains("Request"));
221 |
222 | assertTrue("Response section should be present in logger output.",
223 | testLogger.formattedOutput().contains("Response"));
224 |
225 | assertTrue("Url should be logged when level set to Basic.",
226 | testLogger.formattedOutput().contains("URL"));
227 |
228 | assertTrue("Method should be logged when level set to Basic.",
229 | testLogger.formattedOutput().contains("Method"));
230 |
231 | assertTrue("Headers should be logged when level set to Basic.",
232 | testLogger.formattedOutput().contains("Headers"));
233 |
234 | assertTrue("Status code should be logged when level set to Basic.",
235 | testLogger.formattedOutput().contains("Status Code:"));
236 |
237 | assertTrue("Body should be logged when level set to Basic.",
238 | testLogger.formattedOutput().contains("body"));
239 | }
240 |
241 | private void interceptWithLogLevelInterceptor(String interceptorVersion, TestLogger testLogger,
242 | Level level) throws IOException {
243 | if (interceptorVersion.equals(InterceptorVersion.OKHTTP3.getName())) {
244 | Okhttp3LoggingInterceptor interceptor = new LoggingInterceptor.Builder()
245 | .level(level)
246 | .logger(testLogger)
247 | .buildForOkhttp3();
248 |
249 | defaultOkhttp3ClientWithInterceptor(interceptor)
250 | .newCall(defaultOkhttp3Request())
251 | .execute();
252 | } else if (interceptorVersion.equals(InterceptorVersion.OKHTTP.getName())) {
253 | final OkhttpLoggingInterceptor interceptor = new LoggingInterceptor.Builder()
254 | .logger(testLogger)
255 | .level(level)
256 | .buildForOkhttp();
257 | defaultOkhttpClientWithInterceptor(interceptor)
258 | .newCall(defaultOkhttpRequest())
259 | .execute();
260 | } else if (interceptorVersion
261 | .equals(InterceptorVersion.APACHE_HTTPCLIENT_REQUEST.getName())) {
262 | final ApacheHttpRequestInterceptor requestInterceptor = new LoggingInterceptor.Builder()
263 | .logger(testLogger)
264 | .level(level)
265 | .buildForApacheHttpClientRequest();
266 | final ApacheHttpResponseInterceptor responseInterceptor = new LoggingInterceptor.Builder()
267 | .logger(testLogger)
268 | .level(level)
269 | .buildFordApacheHttpClientResponse();
270 | defaultApacheClientWithInterceptors(requestInterceptor, responseInterceptor)
271 | .execute(defaultApacheHttpRequest());
272 | } else {
273 | fail("Only okhttp and okhttp3 versions are supported");
274 | }
275 | }
276 |
277 | @Test
278 | @Parameters({
279 | "okhttp", "okhttp3", "apacheHttpclientRequest"
280 | })
281 | public void userShouldBeAbleToSupplyExecutor(String interceptorVersion) throws IOException {
282 | server.enqueue(new MockResponse().setResponseCode(200));
283 | TestLogger testLogger = new TestLogger(LogFormatter.JUL_THREAD_MESSAGE);
284 | if (interceptorVersion.equals(InterceptorVersion.OKHTTP3.getName())) {
285 | Okhttp3LoggingInterceptor interceptor = new LoggingInterceptor.Builder()
286 | .level(Level.BASIC)
287 | .executor(Executors.newSingleThreadExecutor())
288 | .logger(testLogger)
289 | .buildForOkhttp3();
290 |
291 | defaultOkhttp3ClientWithInterceptor(interceptor)
292 | .newCall(defaultOkhttp3Request())
293 | .execute();
294 | } else if (interceptorVersion.equals(InterceptorVersion.OKHTTP.getName())) {
295 | final OkhttpLoggingInterceptor interceptor = new LoggingInterceptor.Builder()
296 | .logger(testLogger)
297 | .level(Level.BASIC)
298 | .executor(Executors.newSingleThreadExecutor())
299 | .buildForOkhttp();
300 | defaultOkhttpClientWithInterceptor(interceptor)
301 | .newCall(defaultOkhttpRequest())
302 | .execute();
303 | } else if (interceptorVersion
304 | .equals(InterceptorVersion.APACHE_HTTPCLIENT_REQUEST.getName())) {
305 | final ApacheHttpRequestInterceptor requestInterceptor = new LoggingInterceptor.Builder()
306 | .logger(testLogger)
307 | .level(Level.BASIC)
308 | .executor(Executors.newSingleThreadExecutor())
309 | .buildForApacheHttpClientRequest();
310 | final ApacheHttpResponseInterceptor responseInterceptor = new LoggingInterceptor.Builder()
311 | .logger(testLogger)
312 | .level(Level.BASIC)
313 | .executor(Executors.newSingleThreadExecutor())
314 | .buildFordApacheHttpClientResponse();
315 | defaultApacheClientWithInterceptors(requestInterceptor, responseInterceptor)
316 | .execute(defaultApacheHttpRequest());
317 | } else {
318 | fail("Only okhttp and okhttp3 versions are supported");
319 | }
320 |
321 | assertTrue("User should be able to supply executor.",
322 | testLogger.formattedOutput().contains("thread"));
323 | }
324 |
325 | @Test
326 | @Parameters({
327 | "okhttp", "okhttp3", "apacheHttpclientRequest"
328 | })
329 | public void userShouldBeAbleToUseDefaultLogger(String interceptorVersion) throws IOException {
330 | server.enqueue(new MockResponse().setResponseCode(200));
331 | if (interceptorVersion.equals(InterceptorVersion.OKHTTP3.getName())) {
332 | Okhttp3LoggingInterceptor interceptor = new LoggingInterceptor.Builder()
333 | .level(Level.BASIC)
334 | .executor(Executors.newSingleThreadExecutor())
335 | .buildForOkhttp3();
336 |
337 | defaultOkhttp3ClientWithInterceptor(interceptor)
338 | .newCall(defaultOkhttp3Request())
339 | .execute();
340 | } else if (interceptorVersion.equals(InterceptorVersion.OKHTTP.getName())) {
341 | final OkhttpLoggingInterceptor interceptor = new LoggingInterceptor.Builder()
342 | .level(Level.BASIC)
343 | .executor(Executors.newSingleThreadExecutor())
344 | .buildForOkhttp();
345 | defaultOkhttpClientWithInterceptor(interceptor)
346 | .newCall(defaultOkhttpRequest())
347 | .execute();
348 | } else if (interceptorVersion
349 | .equals(InterceptorVersion.APACHE_HTTPCLIENT_REQUEST.getName())) {
350 | final ApacheHttpRequestInterceptor requestInterceptor = new LoggingInterceptor.Builder()
351 | .level(Level.BASIC)
352 | .executor(Executors.newSingleThreadExecutor())
353 | .buildForApacheHttpClientRequest();
354 | final ApacheHttpResponseInterceptor responseInterceptor = new LoggingInterceptor.Builder()
355 | .level(Level.BASIC)
356 | .executor(Executors.newSingleThreadExecutor())
357 | .buildFordApacheHttpClientResponse();
358 | defaultApacheClientWithInterceptors(requestInterceptor, responseInterceptor)
359 | .execute(defaultApacheHttpRequest());
360 | } else {
361 | fail("Only okhttp and okhttp3 versions are supported");
362 | }
363 | }
364 |
365 |
366 | }
367 |
--------------------------------------------------------------------------------
/lib/src/test/java/com/dkorobtsov/logging/MalformedJsonHandlingTest.java:
--------------------------------------------------------------------------------
1 | package com.dkorobtsov.logging;
2 |
3 | import static org.junit.Assert.assertTrue;
4 |
5 | import com.squareup.okhttp.mockwebserver.MockResponse;
6 | import java.io.IOException;
7 | import junitparams.JUnitParamsRunner;
8 | import junitparams.Parameters;
9 | import okhttp3.MediaType;
10 | import okhttp3.Request;
11 | import okhttp3.RequestBody;
12 | import org.apache.http.client.methods.HttpPut;
13 | import org.apache.http.entity.StringEntity;
14 | import org.apache.http.message.BasicHeader;
15 | import org.junit.Test;
16 | import org.junit.runner.RunWith;
17 |
18 | @RunWith(JUnitParamsRunner.class)
19 | public class MalformedJsonHandlingTest extends BaseTest {
20 |
21 | @Test
22 | @Parameters({
23 | "okhttp", "okhttp3", "apacheHttpclientRequest"
24 | })
25 | public void interceptorAbleToHandleBody_malformedJsonResponse(String interceptorVersion)
26 | throws IOException {
27 | server.enqueue(new MockResponse()
28 | .setResponseCode(200)
29 | .setHeader("Content-Type", "application/json")
30 | .setBody("? \"test\" : \"test1\"}"));
31 |
32 | TestLogger testLogger = new TestLogger(LogFormatter.JUL_MESSAGE_ONLY);
33 | attachLoggerToInterceptorWithDefaultRequest(interceptorVersion, testLogger);
34 |
35 | assertTrue("Interceptor should be able to log malformed json body.",
36 | testLogger.formattedOutput().contains("? \"test\" : \"test1\"}"));
37 | }
38 |
39 | @Test
40 | @Parameters({
41 | "okhttp", "okhttp3", "apacheHttpclientRequest"
42 | })
43 | public void interceptorAbleToHandleBody_malformedJsonRequest(String interceptorVersion)
44 | throws IOException {
45 | server.enqueue(new MockResponse().setResponseCode(200));
46 | final TestLogger testLogger = new TestLogger(LogFormatter.JUL_MESSAGE_ONLY);
47 | final String content = "? \"test\" : \"test1\"}";
48 | if (interceptorVersion.equals(InterceptorVersion.OKHTTP3.getName())) {
49 | Request okhttp3Request = new Request.Builder()
50 | .url(String.valueOf(server.url("/")))
51 | .put(RequestBody.create(MediaType.parse("application/json"),
52 | content))
53 | .build();
54 | attachLoggerToInterceptor(interceptorVersion, testLogger, okhttp3Request, null, null);
55 | } else if (interceptorVersion.equals(InterceptorVersion.OKHTTP.getName())) {
56 | com.squareup.okhttp.Request okhttpRequest = new com.squareup.okhttp.Request.Builder()
57 | .url(String.valueOf(server.url("/")))
58 | .put(com.squareup.okhttp.RequestBody
59 | .create(com.squareup.okhttp.MediaType.parse("application/json"), content))
60 | .build();
61 | attachLoggerToInterceptor(interceptorVersion, testLogger, null, okhttpRequest, null);
62 | } else {
63 | final HttpPut httpPut = new HttpPut(server.url("/").uri());
64 | httpPut.setEntity(new StringEntity(content));
65 | httpPut.setHeader(new BasicHeader("Content-Type", "application/json"));
66 | attachLoggerToInterceptor(interceptorVersion, testLogger, null, null, httpPut);
67 | }
68 | assertTrue("Interceptor should be able to log malformed json body.",
69 | testLogger.formattedOutput().contains(content));
70 | }
71 |
72 | @Test
73 | @Parameters({
74 | "okhttp", "okhttp3", "apacheHttpclientRequest"
75 | })
76 | public void interceptorAbleToHandleBody_jsonArrayResponse(String interceptorVersion)
77 | throws IOException {
78 | server.enqueue(new MockResponse()
79 | .setResponseCode(200)
80 | .setHeader("Content-Type", "application/json")
81 | .setBody("[{\"test1\": \"test1\"}, {\"test2\": \"test2\"}]"));
82 |
83 | TestLogger testLogger = new TestLogger(LogFormatter.JUL_MESSAGE_ONLY);
84 | attachLoggerToInterceptorWithDefaultRequest(interceptorVersion, testLogger);
85 |
86 | assertTrue("Interceptor should be able to log malformed json body.",
87 | testLogger.formattedOutput()
88 | .contains("{\"test1\": \"test1\"},"));
89 | assertTrue("Interceptor should be able to log malformed json body.",
90 | testLogger.formattedOutput()
91 | .contains("{\"test2\": \"test2\"}"));
92 | }
93 |
94 | @Test
95 | @Parameters({
96 | "okhttp", "okhttp3", "apacheHttpclientRequest"
97 | })
98 | public void interceptorAbleToHandleBody_jsonArrayRequest(String interceptorVersion)
99 | throws IOException {
100 | server.enqueue(new MockResponse().setResponseCode(200));
101 | final TestLogger testLogger = new TestLogger(LogFormatter.JUL_MESSAGE_ONLY);
102 |
103 | final String content = "[{\"test1\": \"test1\"}, {\"test2\": \"test2\"}]";
104 | if (interceptorVersion.equals(InterceptorVersion.OKHTTP3.getName())) {
105 | Request okhttp3Request = new Request.Builder()
106 | .url(String.valueOf(server.url("/")))
107 | .put(RequestBody.create(MediaType.parse("application/json"),
108 | content))
109 | .build();
110 | attachLoggerToInterceptor(interceptorVersion, testLogger, okhttp3Request, null, null);
111 | } else if (interceptorVersion.equals(InterceptorVersion.OKHTTP.getName())) {
112 | com.squareup.okhttp.Request okhttpRequest = new com.squareup.okhttp.Request.Builder()
113 | .url(String.valueOf(server.url("/")))
114 | .put(com.squareup.okhttp.RequestBody
115 | .create(com.squareup.okhttp.MediaType.parse("application/json"),
116 | content))
117 | .build();
118 | attachLoggerToInterceptor(interceptorVersion, testLogger, null, okhttpRequest, null);
119 | } else {
120 | final HttpPut httpPut = new HttpPut(server.url("/").uri());
121 | httpPut.setEntity(new StringEntity(content));
122 | httpPut.setHeader(new BasicHeader("Contety-Tyoe", "application/json"));
123 | attachLoggerToInterceptor(interceptorVersion, testLogger, null, null, httpPut);
124 | }
125 |
126 | assertTrue("Interceptor should be able to log malformed json body.",
127 | testLogger.formattedOutput()
128 | .contains("{\"test1\": \"test1\"},"));
129 | assertTrue("Interceptor should be able to log malformed json body.",
130 | testLogger.formattedOutput()
131 | .contains("{\"test2\": \"test2\"}"));
132 | }
133 |
134 | }
135 |
--------------------------------------------------------------------------------
/lib/src/test/java/com/dkorobtsov/logging/OutputResizingTest.java:
--------------------------------------------------------------------------------
1 | package com.dkorobtsov.logging;
2 |
3 | import static org.junit.Assert.assertTrue;
4 |
5 | import com.dkorobtsov.logging.interceptors.Okhttp3LoggingInterceptor;
6 | import java.io.IOException;
7 | import java.util.List;
8 | import junitparams.JUnitParamsRunner;
9 | import junitparams.Parameters;
10 | import okhttp3.MediaType;
11 | import okhttp3.RequestBody;
12 | import org.junit.Assert;
13 | import org.junit.Test;
14 | import org.junit.runner.RunWith;
15 |
16 | @RunWith(JUnitParamsRunner.class)
17 | public class OutputResizingTest extends BaseTest {
18 |
19 | private static final String TEST_JSON = "{name: \"John\", age: 31, city: \"New York\"}";
20 |
21 | @Test
22 | @Parameters({
23 | "okhttp, false",
24 | "okhttp3, false",
25 | "apacheHttpclientRequest, false"
26 | })
27 | public void printerOutputResizingValidation(String loggerVersion,
28 | boolean provideExecutor) throws IOException {
29 | final List loggerOutput = interceptedRequest(RequestBody
30 | .create(MediaType.parse("application/json"), TEST_JSON),
31 | 10, loggerVersion, provideExecutor, false);
32 |
33 | assertTrue("Interceptor should be able to log simple json body.",
34 | loggerOutput.contains("Method: @P"));
35 | }
36 |
37 | @Test(expected = IllegalArgumentException.class)
38 | @Parameters({
39 | "9", "501"
40 | })
41 | public void invalidOutputLengthHandling(String maxLineLength) {
42 | LoggingInterceptor.builder()
43 | .maxLineLength(Integer.parseInt(maxLineLength))
44 | .buildForOkhttp3();
45 | }
46 |
47 | @Test
48 | @Parameters({
49 | "10", "500"
50 | })
51 | public void validOutputLengthHandling(String maxLineLength) {
52 | Okhttp3LoggingInterceptor interceptor = LoggingInterceptor.builder()
53 | .maxLineLength(Integer.parseInt(maxLineLength))
54 | .buildForOkhttp3();
55 |
56 | Assert.assertEquals(Integer.parseInt(maxLineLength),
57 | interceptor.loggerConfig().maxLineLength);
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/lib/src/test/java/com/dkorobtsov/logging/RequestDetailsUnitTests.java:
--------------------------------------------------------------------------------
1 | package com.dkorobtsov.logging;
2 |
3 | import com.squareup.okhttp.Request;
4 | import org.apache.http.client.methods.HttpGet;
5 | import org.junit.Assert;
6 | import org.junit.Test;
7 |
8 | public class RequestDetailsUnitTests {
9 |
10 | @Test(expected = IllegalArgumentException.class)
11 | public void testBuildingWith0ClientsSpecified() {
12 | new RequestDetails.Builder().build();
13 | }
14 |
15 | @Test(expected = IllegalArgumentException.class)
16 | public void testBuildingWithMoreThenOneClientsSpecified() {
17 | new RequestDetails.Builder()
18 | .from(new com.squareup.okhttp.Request.Builder().url("https://google.com").build())
19 | .from(new HttpGet("https://google.com"))
20 | .build();
21 | }
22 |
23 | @Test
24 | public void testBuildingOkhttpClientWithHeaders() {
25 | final String contentType = "application/json";
26 | final String authorizationHeader = "Bearer bla";
27 | final Request request = new Request
28 | .Builder()
29 | .url("https://google.com")
30 | .header("Content-Type", contentType)
31 | .header("Authorization", authorizationHeader)
32 | .build();
33 | final okhttp3.Request builtRequest = new RequestDetails.Builder()
34 | .from(request)
35 | .build();
36 | Assert.assertEquals("Content-Type header", request.headers().get("Content-Type"),
37 | builtRequest.headers().get("Content-Type"));
38 | Assert.assertEquals("Authorization header", request.headers().get("Authorization"),
39 | builtRequest.headers().get("Authorization"));
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/lib/src/test/java/com/dkorobtsov/logging/StatusCodeTest.java:
--------------------------------------------------------------------------------
1 | package com.dkorobtsov.logging;
2 |
3 | import org.junit.Test;
4 |
5 | public class StatusCodeTest {
6 |
7 | @Test(expected = IllegalArgumentException.class)
8 | public void unknownStatusCodeThrowsIllegalArgumentException() {
9 | HttpStatusCodes.findMessage(999);
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/lib/src/test/java/com/dkorobtsov/logging/TestLogger.java:
--------------------------------------------------------------------------------
1 | package com.dkorobtsov.logging;
2 |
3 | import java.io.ByteArrayOutputStream;
4 | import java.io.OutputStream;
5 | import java.util.ArrayList;
6 | import java.util.Arrays;
7 | import java.util.Collections;
8 | import java.util.List;
9 | import java.util.logging.ConsoleHandler;
10 | import java.util.logging.Level;
11 | import java.util.logging.Logger;
12 | import java.util.logging.StreamHandler;
13 | import java.util.stream.Collectors;
14 |
15 | /**
16 | * DefaultLogger double with additional methods for testing purposes. All published events are
17 | * registered and can be retrieved for validation.
18 | */
19 | public class TestLogger implements LogWriter {
20 |
21 | private static final Logger logger = Logger.getLogger(TestLogger.class.getName());
22 |
23 | private final List events = new ArrayList<>(Collections.emptyList());
24 | private StreamHandler logOutputHandler;
25 | private OutputStream logOut;
26 | private Logger testLogger = Logger.getLogger("TestLogger");
27 |
28 | TestLogger(LogFormatter logFormatter) {
29 | testLogger.setUseParentHandlers(false);
30 |
31 | // Removing existing handlers for new instance
32 | Arrays.stream(testLogger.getHandlers()).forEach(testLogger::removeHandler);
33 |
34 | // Configuring output to console
35 | ConsoleHandler consoleHandler = new ConsoleHandler();
36 | consoleHandler.setFormatter(logFormatter.formatter);
37 | testLogger.addHandler(consoleHandler);
38 |
39 | // Configuring output to stream
40 | logOut = new ByteArrayOutputStream();
41 | logOutputHandler = new StreamHandler(logOut, logFormatter.formatter);
42 |
43 | testLogger.addHandler(logOutputHandler);
44 | }
45 |
46 | @Override
47 | public void log(String msg) {
48 | testLogger.log(Level.INFO, msg);
49 | events.add(msg);
50 | }
51 |
52 | /**
53 | * @return Returns raw messages (in case we want to check content only and don't care about
54 | * format)
55 | */
56 | private List rawMessages() {
57 | return events;
58 | }
59 |
60 | /**
61 | * @return Returns first formatted event published by current logger
62 | */
63 | String firstRawEvent() {
64 | return rawMessages().get(0).trim();
65 | }
66 |
67 | /**
68 | * @return Returns last formatted event published by current logger
69 | */
70 | String lastRawEvent() {
71 | return rawMessages().get(rawMessages().size() - 1).trim();
72 | }
73 |
74 | /**
75 | * @return Returns all formatted events published by current logger as String
76 | */
77 | String formattedOutput() {
78 | try {
79 | // Don't like this solution, but without this wait tests verifying
80 | // logger output with manually added executor are randomly failing
81 | // (part of output is missing). Suppose root cause is that we are
82 | // flashing output before all lines get in buffer
83 | // NB: random failures occur when value < 16
84 | Thread.sleep(20);
85 | } catch (InterruptedException e) {
86 | logger.log(Level.SEVERE, e.getMessage(), e);
87 | }
88 | logOutputHandler.flush();
89 | return logOut.toString();
90 | }
91 |
92 | /**
93 | * @return Returns all formatted events published by current logger as String array
94 | */
95 | List loggerOutput(boolean preserveTrailingSpaces) {
96 | if (preserveTrailingSpaces) {
97 | return Arrays.asList(formattedOutput().split("\r?\n"));
98 | }
99 | return Arrays.stream(formattedOutput()
100 | .split("\r?\n"))
101 | .map(String::trim).collect(Collectors.toList());
102 | }
103 |
104 | /**
105 | * @return Returns first formatted event published by current logger
106 | */
107 | String firstFormattedEvent(boolean preserveTrailingSpaces) {
108 | return loggerOutput(preserveTrailingSpaces).get(0);
109 | }
110 |
111 | /**
112 | * @return Returns last formatted event published by current logger
113 | */
114 | String lastFormattedEvent(boolean preserveTrailingSpaces) {
115 | return loggerOutput(preserveTrailingSpaces)
116 | .get(loggerOutput(preserveTrailingSpaces).size() - 1);
117 | }
118 |
119 | }
120 |
--------------------------------------------------------------------------------
/lib/src/test/java/com/dkorobtsov/logging/TestUtil.java:
--------------------------------------------------------------------------------
1 | package com.dkorobtsov.logging;
2 |
3 | import static org.junit.Assert.fail;
4 |
5 | import java.text.ParseException;
6 | import java.text.SimpleDateFormat;
7 | import java.util.Arrays;
8 | import org.junit.Assert;
9 |
10 | final class TestUtil {
11 |
12 | static void assertEntryStartsWithParsableDate(String rawEntry) {
13 | String[] entryElements = TestUtil
14 | .extractTextFromLogEntrySeparatedByBrackets(rawEntry);
15 |
16 | try {
17 | new SimpleDateFormat("yyyy-MM-ddd kk:mm:ss").parse(entryElements[0]);
18 | } catch (ParseException e) {
19 | fail("Log entry expected to start with parsable date stamp. But was: \n" + rawEntry);
20 | }
21 | }
22 |
23 | @SuppressWarnings({"RegExpRedundantEscape", "RegExpSingleCharAlternation"})
24 | static String[] extractTextFromLogEntrySeparatedByBrackets(String logEntry) {
25 | return Arrays
26 | .stream(logEntry.split("\\[|\\]"))
27 | .filter(s -> s.trim().length() > 0)
28 | .map(String::trim)
29 | .toArray(String[]::new);
30 | }
31 |
32 | static void assertLogEntryElementsCount(String entrySeparatedByBrackets, int expectedCount) {
33 | String[] entryElements = TestUtil
34 | .extractTextFromLogEntrySeparatedByBrackets(entrySeparatedByBrackets);
35 |
36 | Assert.assertEquals(
37 | "Log event expected to contain " + expectedCount + " of elements. But was: \n"
38 | + entryElements.length, expectedCount, entryElements.length);
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/lib/src/test/java/com/dkorobtsov/logging/ToApacheHttpClientConverterUnitTests.java:
--------------------------------------------------------------------------------
1 | package com.dkorobtsov.logging;
2 |
3 | import com.dkorobtsov.logging.converters.ToApacheHttpClientConverter;
4 | import java.io.BufferedReader;
5 | import java.io.IOException;
6 | import java.io.InputStream;
7 | import java.io.InputStreamReader;
8 | import java.nio.charset.Charset;
9 | import org.apache.http.entity.ContentType;
10 | import org.apache.http.entity.StringEntity;
11 | import org.junit.Assert;
12 | import org.junit.Test;
13 |
14 | public class ToApacheHttpClientConverterUnitTests {
15 |
16 | @Test
17 | public void testOkhtt3WithEmptyBodyConversion() throws IOException {
18 | final StringEntity httpEntity = (StringEntity) ToApacheHttpClientConverter
19 | .okhttp3RequestBodyToStringEntity(null, ContentType.APPLICATION_JSON);
20 | final InputStream content = httpEntity.getContent();
21 | StringBuilder stringBuilder = new StringBuilder();
22 | String line;
23 |
24 | try (BufferedReader bufferedReader = new BufferedReader(
25 | new InputStreamReader(content, Charset.defaultCharset()))) {
26 | while ((line = bufferedReader.readLine()) != null) {
27 | stringBuilder.append(line);
28 | }
29 | }
30 | Assert.assertEquals("body", "", stringBuilder.toString());
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/lib/src/test/resources/log4j2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | %d{HH:mm:ss.SSS} [%t] %-5level %c{0}:%L - %msg%n
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':lib'
2 |
--------------------------------------------------------------------------------
/wercker.yml:
--------------------------------------------------------------------------------
1 | # docker box definition
2 | box:
3 | id: openjdk:8
4 |
5 | # defining the dev pipeline
6 | dev:
7 | steps:
8 | - script:
9 | name: gradle check
10 | code: |
11 | ./gradlew check
12 |
13 | - internal/watch:
14 | code: |
15 | ./gradlew check
16 | reload: true
17 |
18 | build:
19 | steps:
20 | - script:
21 | name: quality check
22 | code: |
23 | ./gradlew sonarqube --full-stacktrace --project-cache-dir=$WERCKER_CACHE_DIR -Dsonar.organization=dkorobtsov-github -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONARCUBE_TOKEN
24 |
25 | deploy:
26 | steps:
27 | - handijk/github-merge@1.0.3:
28 | token: $GITHUB_TOKEN
29 | base: master
30 |
--------------------------------------------------------------------------------