Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added caching support for headers #491

Merged
merged 1 commit into from Apr 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 19 additions & 0 deletions logbook-core/src/main/java/org/zalando/logbook/Cache.java
@@ -0,0 +1,19 @@
package org.zalando.logbook;

import lombok.AllArgsConstructor;

import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;

@AllArgsConstructor
final class Cache<T> {

private final AtomicReference<T> cache = new AtomicReference<>();
private final Supplier<T> supplier;

public T get() {
return cache.updateAndGet(cached ->
cached == null ? supplier.get() : cached);
}

}
@@ -0,0 +1,26 @@
package org.zalando.logbook;

import java.util.List;
import java.util.Map;

final class CachingHttpRequest implements ForwardingHttpRequest {

private final HttpRequest request;
private final Cache<Map<String, List<String>>> headers;

CachingHttpRequest(final HttpRequest request) {
this.request = request;
this.headers = new Cache<>(request::getHeaders);
}

@Override
public HttpRequest delegate() {
return request;
}

@Override
public Map<String, List<String>> getHeaders() {
return headers.get();
}

}
@@ -0,0 +1,26 @@
package org.zalando.logbook;

import java.util.List;
import java.util.Map;

final class CachingHttpResponse implements ForwardingHttpResponse {

private final HttpResponse response;
private final Cache<Map<String, List<String>>> headers;

CachingHttpResponse(final HttpResponse response) {
this.response = response;
this.headers = new Cache<>(response::getHeaders);
}

@Override
public HttpResponse delegate() {
return response;
}

@Override
public Map<String, List<String>> getHeaders() {
return headers.get();
}

}
Expand Up @@ -26,15 +26,18 @@ public RequestWritingStage process(final HttpRequest originalRequest) throws IOE

@Override
public RequestWritingStage process(final HttpRequest originalRequest, final Strategy strategy) throws IOException {
if (sink.isActive() && predicate.test(originalRequest)) {
final HttpRequest request = new CachingHttpRequest(originalRequest);

if (sink.isActive() && predicate.test(request)) {
final Precorrelation precorrelation = new SimplePrecorrelation(clock);
final HttpRequest processedRequest = strategy.process(originalRequest);
final HttpRequest processedRequest = strategy.process(request);

return () -> {
final HttpRequest filteredRequest = requestFilter.filter(processedRequest);
strategy.write(precorrelation, filteredRequest, sink);
return originalResponse -> {
final HttpResponse processedResponse = strategy.process(originalRequest, originalResponse);
final HttpResponse response = new CachingHttpResponse(originalResponse);
final HttpResponse processedResponse = strategy.process(request, response);
return () -> {
final HttpResponse filteredResponse = responseFilter.filter(processedResponse);
strategy.write(precorrelation.correlate(), filteredRequest, filteredResponse, sink);
Expand Down
@@ -0,0 +1,35 @@
package org.zalando.logbook;

import org.junit.jupiter.api.Test;

import static java.util.Collections.emptyMap;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.anEmptyMap;
import static org.hamcrest.Matchers.is;
import static org.mockito.Mockito.atMost;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

final class CachingHttpRequestTest {

@Test
void shouldDelegate() {
final CachingHttpRequest unit = new CachingHttpRequest(MockHttpRequest.create());
assertThat(unit.getHeaders(), is(anEmptyMap()));
}

@Test
void shouldCache() {
final HttpRequest delegate = mock(HttpRequest.class);
when(delegate.getHeaders()).thenReturn(emptyMap());

final CachingHttpRequest unit = new CachingHttpRequest(delegate);

unit.getHeaders();
unit.getHeaders();

verify(delegate, atMost(1)).getHeaders();
}

}
@@ -0,0 +1,35 @@
package org.zalando.logbook;

import org.junit.jupiter.api.Test;

import static java.util.Collections.emptyMap;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.anEmptyMap;
import static org.hamcrest.Matchers.is;
import static org.mockito.Mockito.atMost;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

final class CachingHttpResponseTest {

@Test
void shouldDelegate() {
final CachingHttpResponse unit = new CachingHttpResponse(MockHttpResponse.create());
assertThat(unit.getHeaders(), is(anEmptyMap()));
}

@Test
void shouldCache() {
final HttpResponse delegate = mock(HttpResponse.class);
when(delegate.getHeaders()).thenReturn(emptyMap());

final CachingHttpResponse unit = new CachingHttpResponse(delegate);

unit.getHeaders();
unit.getHeaders();

verify(delegate, atMost(1)).getHeaders();
}

}