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

Issue 2443: karate mock server interceptor #2445

Merged
merged 1 commit into from
Nov 15, 2023
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -77,20 +77,23 @@ public class MockHandler implements ServerHandler {
protected static final ThreadLocal<Request> LOCAL_REQUEST = new ThreadLocal<>();
private final String prefix;

private final MockInterceptor mockInterceptor;

public MockHandler(Feature feature) {
this(feature, null);
}

public MockHandler(Feature feature, Map<String, Object> args) {
this(null, Collections.singletonList(feature), args);
this(null, Collections.singletonList(feature), args, null);
}

public MockHandler(List<Feature> features) {
this(null, features, null);
this(null, features, null, null);
}

public MockHandler(String prefix, List<Feature> features, Map<String, Object> args) {
public MockHandler(String prefix, List<Feature> features, Map<String, Object> args, MockInterceptor interceptor) {
this.prefix = "/".equals(prefix) ? null : prefix;
this.mockInterceptor = interceptor;
features.forEach(feature -> {
ScenarioRuntime runtime = initRuntime(feature, args);
corsEnabled = corsEnabled || runtime.engine.getConfig().isCorsEnabled();
Expand Down Expand Up @@ -225,6 +228,9 @@ public synchronized Response handle(Request req) { // note the [synchronized]
if (prevEngine != null) {
ScenarioEngine.set(prevEngine);
}
if (mockInterceptor != null) {
mockInterceptor.intercept(req, res, scenario);
}
return res;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.intuit.karate.core;

import com.intuit.karate.http.Request;
import com.intuit.karate.http.Response;

@FunctionalInterface
public interface MockInterceptor {

void intercept(Request req, Response res, Scenario scenario);

}
16 changes: 12 additions & 4 deletions karate-core/src/main/java/com/intuit/karate/core/MockServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ public static class Builder {
File keyFile;
Map<String, Object> args;
String prefix = null;
MockInterceptor interceptor = null;

public Builder watch(boolean value) {
watch = value;
Expand Down Expand Up @@ -116,6 +117,11 @@ public Builder arg(String name, Object value) {
return this;
}

public Builder interceptor(MockInterceptor value) {
interceptor = value;
return this;
}

public MockServer build() {
ServerBuilder sb = Server.builder();
sb.requestTimeoutMillis(0);
Expand All @@ -129,7 +135,7 @@ public MockServer build() {
} else {
sb.http(port);
}
ServerHandler handler = watch ? new ReloadingMockHandler(features, args, prefix) : new MockHandler(prefix, features, args);
ServerHandler handler = watch ? new ReloadingMockHandler(features, args, prefix, interceptor) : new MockHandler(prefix, features, args, interceptor);
HttpService service = new HttpServerHandler(handler);
sb.service("prefix:" + (prefix == null ? "/" : prefix), service);
return new MockServer(sb);
Expand All @@ -143,23 +149,25 @@ private static class ReloadingMockHandler implements ServerHandler {
private MockHandler handler;
private final LinkedHashMap<File, Long> files = new LinkedHashMap<>();
private final String prefix;
private final MockInterceptor interceptor;

public ReloadingMockHandler(List<Feature> features, Map<String, Object> args, String prefix) {
public ReloadingMockHandler(List<Feature> features, Map<String, Object> args, String prefix, MockInterceptor interceptor) {
this.args = args;
this.prefix = prefix;
this.interceptor = interceptor;
for (Feature f : features) {
this.files.put(f.getResource().getFile(), f.getResource().getFile().lastModified());
}
logger.debug("watch mode init - {}", files);
handler = new MockHandler(prefix, features, args);
handler = new MockHandler(prefix, features, args, this.interceptor);
}

@Override
public Response handle(Request request) {
boolean reload = files.entrySet().stream().reduce(false, (modified, entry) -> entry.getKey().lastModified() > entry.getValue(), (a, b) -> a || b);
if (reload) {
List<Feature> features = files.keySet().stream().map(f -> Feature.read(f)).collect(Collectors.toList());
handler = new MockHandler(prefix, features, args);
handler = new MockHandler(prefix, features, args, interceptor);
}
return handler.handle(request);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package com.intuit.karate.core.mock;

import com.intuit.karate.http.HttpServer;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import com.intuit.karate.Results;
import com.intuit.karate.Runner;
import com.intuit.karate.core.MockServer;
import static org.junit.jupiter.api.Assertions.*;
import com.intuit.karate.http.HttpServer;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
Expand All @@ -18,11 +21,16 @@ class MockTest {

static final Logger logger = LoggerFactory.getLogger(MockTest.class);

static final AtomicInteger count = new AtomicInteger(0);

static HttpServer startMockServer() {
MockServer server = MockServer.featurePaths(
"classpath:com/intuit/karate/core/mock/_simple.feature",
"classpath:com/intuit/karate/core/mock/_mock.feature")
.pathPrefix("/") // ensure cli default works
.interceptor((req, res, scenario) ->
logger.debug("interceptor has been called %s times"
.formatted(count.incrementAndGet())))
.build();
System.setProperty("karate.server.port", server.getPort() + "");
return server;
Expand All @@ -39,6 +47,7 @@ void testMock() {
.configDir("classpath:com/intuit/karate/core/mock")
.parallel(1);
assertEquals(0, results.getFailCount(), results.getErrorMessages());
assertTrue(count.get() > 0);
}

}