Skip to content

Commit

Permalink
feat: wiremock 3.9.1
Browse files Browse the repository at this point in the history
Update to WireMock 3.9.1
  • Loading branch information
holomekc authored Jul 25, 2024
1 parent bcf93e6 commit aa37bad
Show file tree
Hide file tree
Showing 53 changed files with 1,808 additions and 158 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/docker-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
PLATFORMS: linux/amd64,linux/arm64,linux/arm/v7
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3

- name: Checkout sources
uses: actions/checkout@v4
Expand Down
18 changes: 9 additions & 9 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,21 @@ plugins {
id "org.sonarqube" version "5.0.0.4638"
id 'jacoco'
id "me.champeau.jmh" version "0.7.2"
id 'com.dorongold.task-tree' version '3.0.0'
id 'com.dorongold.task-tree' version '4.0.0'
id 'com.github.node-gradle.node' version '7.0.2'
}

group = 'org.wiremock'

project.ext {
versions = [
handlebars : '4.3.1',
jetty : '11.0.20',
guava : '33.2.1-jre',
jackson : '2.17.1',
xmlUnit : '2.10.0',
jsonUnit : '2.38.0',
junitJupiter: '5.10.3'
handlebars : '4.3.1',
jetty : '11.0.20',
guava : '33.2.1-jre',
jackson : '2.17.2',
xmlUnit : '2.10.0',
jsonUnit : '2.40.0',
junitJupiter : '5.10.3'
]
}

Expand Down Expand Up @@ -108,7 +108,7 @@ dependencies {

api 'commons-fileupload:commons-fileupload:1.5'

api 'com.networknt:json-schema-validator:1.4.3'
api 'com.networknt:json-schema-validator:1.5.0'

testFixturesApi("org.junit.jupiter:junit-jupiter:$versions.junitJupiter")
testFixturesApi("org.junit.platform:junit-platform-testkit")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import static com.github.tomakehurst.wiremock.common.Strings.isNotBlank;
import static com.github.tomakehurst.wiremock.security.NoClientAuthenticator.noClientAuthenticator;
import static java.util.Objects.requireNonNull;
import static org.apache.hc.core5.http.HttpHeaders.CONTENT_TYPE;
import static org.apache.hc.core5.http.HttpHeaders.HOST;

import com.github.tomakehurst.wiremock.admin.*;
Expand Down Expand Up @@ -462,12 +463,14 @@ private ProxySettings createProxySettings(String proxyHost, int proxyPort) {

private String postJsonAssertOkAndReturnBody(String url, String json) {
HttpPost post = new HttpPost(url);
post.addHeader(CONTENT_TYPE, "application/json");
post.setEntity(jsonStringEntity(Optional.ofNullable(json).orElse("")));
return safelyExecuteRequest(url, post);
}

private String putJsonAssertOkAndReturnBody(String url, String json) {
HttpPut put = new HttpPut(url);
put.addHeader(CONTENT_TYPE, "application/json");
put.setEntity(jsonStringEntity(Optional.ofNullable(json).orElse("")));
return safelyExecuteRequest(url, put);
}
Expand Down Expand Up @@ -518,6 +521,7 @@ private <B, R> R executeRequest(
if (requestSpec.method().hasEntity()) {
requestBuilder.setEntity(
jsonStringEntity(Optional.ofNullable(requestBody).map(Json::write).orElse("")));
requestBuilder.addHeader(CONTENT_TYPE, "application/json");
}

String responseBodyString = safelyExecuteRequest(url, requestBuilder.build());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Thomas Akehurst
* Copyright (C) 2021-2024 Thomas Akehurst
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -116,6 +116,22 @@ public LocalDate parseLocalDate(String dateTimeString) {
return null;
}

public YearMonth parseYearMonth(String dateTimeString) {
if (dateTimeFormatter != null) {
return YearMonth.parse(dateTimeString, dateTimeFormatter);
}

return null;
}

public Year parseYear(String dateTimeString) {
if (dateTimeFormatter != null) {
return Year.parse(dateTimeString, dateTimeFormatter);
}

return null;
}

public RenderableDate parseDate(String dateTimeString) {
if (isUnix || isEpoch) {
return new RenderableDate(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Thomas Akehurst
* Copyright (C) 2020-2024 Thomas Akehurst
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,9 +17,7 @@

import com.github.jknack.handlebars.Options;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

public class PickRandomHelper extends HandlebarsHelper<Object> {
Expand All @@ -40,7 +38,16 @@ public Object apply(Object context, Options options) throws IOException {
valueList.addAll(Arrays.asList(options.params));
}

Integer count = (Integer) options.hash.get("count");
if (count != null && count > 0) {
int desiredLength = Math.min(valueList.size(), count);
for (int i = 0; i < desiredLength; i++) {
Collections.swap(valueList, i, ThreadLocalRandom.current().nextInt(i, valueList.size()));
}
return valueList.subList(0, desiredLength);
}

int index = ThreadLocalRandom.current().nextInt(valueList.size());
return valueList.get(index).toString();
return valueList.get(index);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2022 Thomas Akehurst
* Copyright (C) 2021-2024 Thomas Akehurst
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -22,9 +22,7 @@
import com.github.tomakehurst.wiremock.common.DateTimeParser;
import com.github.tomakehurst.wiremock.common.DateTimeTruncation;
import com.github.tomakehurst.wiremock.common.DateTimeUnit;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.*;
import java.time.format.DateTimeParseException;
import java.util.List;

Expand Down Expand Up @@ -271,7 +269,21 @@ private static LocalDateTime parseLocalOrNull(String dateTimeString, DateTimePar
: LocalDate.parse(dateTimeString))
.atStartOfDay();
} catch (DateTimeParseException ignored2) {
return null;
try {
return (parser != null
? parser.parseYearMonth(dateTimeString)
: YearMonth.parse(dateTimeString))
.atDay(1)
.atStartOfDay();
} catch (DateTimeParseException ignored3) {
try {
return (parser != null ? parser.parseYear(dateTimeString) : Year.parse(dateTimeString))
.atDay(1)
.atStartOfDay();
} catch (DateTimeParseException ignored4) {
return null;
}
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.TextNode;
import com.github.tomakehurst.wiremock.client.WireMock;
import com.github.tomakehurst.wiremock.common.ClientError;
import com.github.tomakehurst.wiremock.common.Errors;
import com.github.tomakehurst.wiremock.common.Json;
import com.github.tomakehurst.wiremock.common.JsonException;
import com.github.tomakehurst.wiremock.stubbing.SubEvent;
import com.networknt.schema.JsonSchema;
import com.networknt.schema.JsonSchemaFactory;
import com.networknt.schema.SchemaValidatorsConfig;
Expand All @@ -32,6 +35,7 @@ public class MatchesJsonSchemaPattern extends StringValuePattern {
private final JsonSchema schema;
private final WireMock.JsonSchemaVersion schemaVersion;
private final int schemaPropertyCount;
private final Errors invalidSchemaErrors;

public MatchesJsonSchemaPattern(String schemaJson) {
this(schemaJson, WireMock.JsonSchemaVersion.V202012);
Expand All @@ -48,10 +52,24 @@ public MatchesJsonSchemaPattern(

final JsonSchemaFactory schemaFactory =
JsonSchemaFactory.getInstance(schemaVersion.toVersionFlag());
schema = schemaFactory.getSchema(schemaJson, config);
JsonSchema schema;
JsonNode schemaAsJson = Json.read(schemaJson, JsonNode.class);
int schemaPropertyCount;
Errors invalidSchemaErrors;
try {
schema = schemaFactory.getSchema(schemaAsJson, config);
schemaPropertyCount = Json.schemaPropertyCount(schemaAsJson);
invalidSchemaErrors = null;
} catch (Exception e) {
schema = null;
schemaPropertyCount = 0;
invalidSchemaErrors = getInvalidSchemaErrors(e);
}
this.schema = schema;
this.schemaVersion = schemaVersion;

schemaPropertyCount = Json.schemaPropertyCount(Json.read(schemaJson, JsonNode.class));
this.schemaPropertyCount = schemaPropertyCount;
this.invalidSchemaErrors = invalidSchemaErrors;
}

public MatchesJsonSchemaPattern(
Expand All @@ -74,6 +92,9 @@ public String getExpected() {

@Override
public MatchResult match(String json) {
if (schema == null) {
return MatchResult.noMatch(new SubEvent(SubEvent.ERROR, invalidSchemaErrors));
}
if (json == null) {
return MatchResult.noMatch();
}
Expand All @@ -85,7 +106,13 @@ public MatchResult match(String json) {
jsonNode = new TextNode(json);
}

final Set<ValidationMessage> validationMessages = validate(jsonNode, json);
final Set<ValidationMessage> validationMessages;
try {
validationMessages = validate(jsonNode, json);
} catch (Exception e) {
return MatchResult.noMatch(new SubEvent(SubEvent.ERROR, getInvalidSchemaErrors(e)));
}

if (validationMessages.isEmpty()) {
return MatchResult.exactMatch();
}
Expand All @@ -107,6 +134,30 @@ public double getDistance() {
};
}

private static Errors getInvalidSchemaErrors(Exception e) {
Errors invalidSchemaErrors;
if (e instanceof ClientError) {
Errors.Error error = ((ClientError) e).getErrors().first();
invalidSchemaErrors =
Errors.single(
error.getCode(),
error.getSource().getPointer(),
"Invalid JSON Schema",
error.getDetail());
} else {
invalidSchemaErrors =
Errors.singleWithDetail(10, "Invalid JSON Schema", getRootCause(e).getMessage());
}
return invalidSchemaErrors;
}

private static Throwable getRootCause(Throwable e) {
if (e.getCause() != null) {
return getRootCause(e.getCause());
}
return e;
}

private Set<ValidationMessage> validate(JsonNode jsonNode, String originalJson) {
final Set<ValidationMessage> validationMessages = schema.validate(jsonNode);
if (validationMessages.isEmpty() || jsonNode.isTextual() || jsonNode.isContainerNode()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,25 @@
*/
package com.github.tomakehurst.wiremock.store;

import static com.github.tomakehurst.wiremock.common.LocalNotifier.notifier;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;

public class InMemoryObjectStore implements ObjectStore {
public class InMemoryObjectStore implements ObjectStore, StoreEventEmitter<String, Object> {

private final ConcurrentHashMap<String, Object> cache;
private final Queue<String> keyUseOrder = new ConcurrentLinkedQueue<>();
private final int maxItems;
private final List<Consumer<? super StoreEvent<String, Object>>> listeners = new ArrayList<>();

public InMemoryObjectStore(int maxItems) {
this.cache = new ConcurrentHashMap<>();
Expand Down Expand Up @@ -54,23 +61,39 @@ public Stream<String> getAllKeys() {

@Override
public void put(String key, Object content) {
cache.put(key, content);
Object previousValue = cache.put(key, content);
touchAndResize(key);
handleEvent(StoreEvent.set(key, previousValue, content));
}

@Override
@SuppressWarnings("unchecked")
public <T> T compute(String key, Function<T, T> valueFunction) {
final AtomicReference<T> previousValue = new AtomicReference<>();
final T result =
(T) cache.compute(key, (k, currentValue) -> valueFunction.apply((T) currentValue));
touchAndResize(key);
(T)
cache.compute(
key,
(k, currentValue) -> {
previousValue.set((T) currentValue);
return valueFunction.apply((T) currentValue);
});
if (result != null) {
touchAndResize(key);
} else {
keyUseOrder.remove(key);
}
handleEvent(StoreEvent.set(key, previousValue.get(), result));
return result;
}

@Override
public void remove(String key) {
cache.remove(key);
Object previousValue = cache.remove(key);
keyUseOrder.remove(key);
if (previousValue != null) {
handleEvent(StoreEvent.remove(key, previousValue));
}
}

@Override
Expand All @@ -79,6 +102,21 @@ public void clear() {
keyUseOrder.clear();
}

@Override
public void registerEventListener(Consumer<? super StoreEvent<String, Object>> handler) {
listeners.add(handler);
}

private void handleEvent(StoreEvent<String, Object> event) {
for (Consumer<? super StoreEvent<String, Object>> listener : listeners) {
try {
listener.accept(event);
} catch (Exception e) {
notifier().error("Error handling store event", e);
}
}
}

private void touchAndResize(String key) {
touch(key);
resize();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2023 Thomas Akehurst
* Copyright (C) 2022-2024 Thomas Akehurst
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Loading

0 comments on commit aa37bad

Please sign in to comment.