-
Notifications
You must be signed in to change notification settings - Fork 264
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
adds LogbookClientHttpRequestInterceptor for spring RestTemplate (#917)
* adds `LogbookClientHttpRequestInterceptor` for spring `RestTemplate` users * adds documentation for LogbookClientHttpRequestInterceptor * fixes * imports * removes dependency on spring annotations * maintains spring4 compatibility * creates new module: logbook-spring * exclude spring-jcl and make spring-web provided scope * exclude spring-jcl from spring-test * excludes commons-logging * removes dependency on httpclient * spring4 compatibility * boost coverage * polish * new section for spring * simplify constructors * move bean definition * add autoconfiguration docs
- Loading branch information
Showing
12 changed files
with
688 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<parent> | ||
<groupId>org.zalando</groupId> | ||
<artifactId>logbook-parent</artifactId> | ||
<version>2.5.0-SNAPSHOT</version> | ||
</parent> | ||
|
||
<artifactId>logbook-spring</artifactId> | ||
<version>2.5.0-SNAPSHOT</version> | ||
<description>Spring implementations for request and response logging</description> | ||
<scm> | ||
<url>https://github.com/zalando/logbook</url> | ||
<connection>scm:git:git@github.com:zalando/logbook.git</connection> | ||
<developerConnection>scm:git:git@github.com:zalando/logbook.git</developerConnection> | ||
</scm> | ||
|
||
<dependencyManagement> | ||
<dependencies> | ||
<!-- Because spring-security would pull in the wrong version otherwise --> | ||
<dependency> | ||
<groupId>org.springframework</groupId> | ||
<artifactId>spring-framework-bom</artifactId> | ||
<version>${spring.version}</version> | ||
<type>pom</type> | ||
<scope>import</scope> | ||
</dependency> | ||
</dependencies> | ||
</dependencyManagement> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.zalando</groupId> | ||
<artifactId>logbook-core</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework</groupId> | ||
<artifactId>spring-web</artifactId> | ||
<scope>provided</scope> | ||
<exclusions> | ||
<exclusion> | ||
<groupId>org.springframework</groupId> | ||
<artifactId>spring-jcl</artifactId> | ||
</exclusion> | ||
<exclusion> | ||
<groupId>commons-logging</groupId> | ||
<artifactId>commons-logging</artifactId> | ||
</exclusion> | ||
</exclusions> | ||
</dependency> | ||
<!-- test dependencies --> | ||
<dependency> | ||
<groupId>org.zalando</groupId> | ||
<artifactId>logbook-test</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework</groupId> | ||
<artifactId>spring-test</artifactId> | ||
<scope>test</scope> | ||
<exclusions> | ||
<exclusion> | ||
<groupId>org.springframework</groupId> | ||
<artifactId>spring-jcl</artifactId> | ||
</exclusion> | ||
</exclusions> | ||
</dependency> | ||
</dependencies> | ||
</project> |
31 changes: 31 additions & 0 deletions
31
logbook-spring/src/main/java/org/zalando/logbook/spring/ByteStreams.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package org.zalando.logbook.spring; | ||
|
||
import java.io.ByteArrayOutputStream; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.io.OutputStream; | ||
|
||
final class ByteStreams { | ||
|
||
private ByteStreams() { | ||
|
||
} | ||
|
||
static byte[] toByteArray(final InputStream in) throws IOException { | ||
final ByteArrayOutputStream out = new ByteArrayOutputStream(); | ||
copy(in, out); | ||
return out.toByteArray(); | ||
} | ||
|
||
static void copy(final InputStream from, final OutputStream to) throws IOException { | ||
final byte[] buf = new byte[4096]; | ||
while (true) { | ||
final int r = from.read(buf); | ||
if (r == -1) { | ||
break; | ||
} | ||
to.write(buf, 0, r); | ||
} | ||
} | ||
|
||
} |
116 changes: 116 additions & 0 deletions
116
logbook-spring/src/main/java/org/zalando/logbook/spring/LocalRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package org.zalando.logbook.spring; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.MediaType; | ||
import org.zalando.logbook.HttpHeaders; | ||
import org.zalando.logbook.HttpRequest; | ||
import org.zalando.logbook.Origin; | ||
|
||
import javax.annotation.Nullable; | ||
import java.io.IOException; | ||
import java.net.URI; | ||
import java.nio.charset.Charset; | ||
import java.util.Optional; | ||
|
||
import static java.nio.charset.StandardCharsets.UTF_8; | ||
|
||
@RequiredArgsConstructor | ||
final class LocalRequest implements HttpRequest { | ||
|
||
private final org.springframework.http.HttpRequest request; | ||
private final byte[] body; | ||
|
||
private boolean withBody = false; | ||
|
||
@Override | ||
public String getRemote() { | ||
return "localhost"; | ||
} | ||
|
||
@Override | ||
public String getMethod() { | ||
return request.getMethod().name(); | ||
} | ||
|
||
@Override | ||
public String getScheme() { | ||
return Optional.of(request.getURI()) | ||
.map(URI::getScheme) | ||
.orElse(""); | ||
} | ||
|
||
@Override | ||
public String getHost() { | ||
return Optional.of(request.getURI()) | ||
.map(URI::getHost) | ||
.orElse(""); | ||
} | ||
|
||
@Override | ||
public Optional<Integer> getPort() { | ||
return Optional.of(request.getURI().getPort()) | ||
.filter(p -> p != -1); | ||
} | ||
|
||
@Override | ||
public String getPath() { | ||
return Optional.of(request.getURI()) | ||
.map(URI::getPath) | ||
.orElse(""); | ||
} | ||
|
||
@Override | ||
public String getQuery() { | ||
return Optional.of(request.getURI()) | ||
.map(URI::getQuery) | ||
.orElse(""); | ||
} | ||
|
||
@Override | ||
public HttpRequest withBody() throws IOException { | ||
withBody = true; | ||
return this; | ||
} | ||
|
||
@Override | ||
public HttpRequest withoutBody() { | ||
withBody = false; | ||
return this; | ||
} | ||
|
||
@Override | ||
public String getProtocolVersion() { | ||
// TODO find the real thing | ||
return "HTTP/1.1"; | ||
} | ||
|
||
@Override | ||
public Origin getOrigin() { | ||
return Origin.LOCAL; | ||
} | ||
|
||
@Override | ||
public HttpHeaders getHeaders() { | ||
return HttpHeaders.of(request.getHeaders()); | ||
} | ||
|
||
@Nullable | ||
@Override | ||
public String getContentType() { | ||
return Optional | ||
.ofNullable(request.getHeaders().getFirst("Content-Type")) | ||
.orElse(null); | ||
} | ||
|
||
@Override | ||
public Charset getCharset() { | ||
return Optional.ofNullable(getContentType()) | ||
.map(ct -> MediaType.parseMediaType(ct).getCharset()) | ||
.orElse(UTF_8); | ||
} | ||
|
||
@Override | ||
public byte[] getBody() throws IOException { | ||
return withBody ? body : new byte[0]; | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
...-spring/src/main/java/org/zalando/logbook/spring/LogbookClientHttpRequestInterceptor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package org.zalando.logbook.spring; | ||
|
||
import lombok.AllArgsConstructor; | ||
import org.apiguardian.api.API; | ||
import org.springframework.http.HttpRequest; | ||
import org.springframework.http.client.ClientHttpRequestExecution; | ||
import org.springframework.http.client.ClientHttpRequestInterceptor; | ||
import org.springframework.http.client.ClientHttpResponse; | ||
import org.zalando.logbook.HttpResponse; | ||
import org.zalando.logbook.Logbook; | ||
|
||
import java.io.IOException; | ||
|
||
@API(status = API.Status.EXPERIMENTAL) | ||
@AllArgsConstructor | ||
public final class LogbookClientHttpRequestInterceptor implements ClientHttpRequestInterceptor { | ||
|
||
private final Logbook logbook; | ||
|
||
@Override | ||
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { | ||
final org.zalando.logbook.HttpRequest httpRequest = new LocalRequest(request, body); | ||
final Logbook.ResponseProcessingStage stage = logbook.process(httpRequest).write(); | ||
|
||
ClientHttpResponse response = execution.execute(request, body); | ||
|
||
final HttpResponse httpResponse = new RemoteResponse(response); | ||
stage.process(httpResponse).write(); | ||
|
||
return response; | ||
} | ||
} |
Oops, something went wrong.