Skip to content

Commit 91b058b

Browse files
authored
Merge pull request wiremock#2334 from bharatnpti/MappingsSourceExtension
Exposing MappingsSource for extension point
2 parents f9d1a78 + ea0f72c commit 91b058b

File tree

5 files changed

+198
-0
lines changed

5 files changed

+198
-0
lines changed

src/main/java/com/github/tomakehurst/wiremock/core/WireMockApp.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ public class WireMockApp implements StubServer, Admin {
6161
private final NearMissCalculator nearMissCalculator;
6262
private final Recorder recorder;
6363
private final List<GlobalSettingsListener> globalSettingsListeners;
64+
private final Map<String, MappingsLoaderExtension> mappingsLoaderExtensions;
6465

6566
private Options options;
6667

@@ -116,6 +117,7 @@ public WireMockApp(Options options, Container container) {
116117
recorder =
117118
new Recorder(this, extensions, stores.getFilesBlobStore(), stores.getRecorderStateStore());
118119
globalSettingsListeners = List.copyOf(extensions.ofType(GlobalSettingsListener.class).values());
120+
this.mappingsLoaderExtensions = extensions.ofType(MappingsLoaderExtension.class);
119121

120122
this.container = container;
121123
loadDefaultMappings();
@@ -124,6 +126,7 @@ public WireMockApp(Options options, Container container) {
124126
public WireMockApp(
125127
boolean browserProxyingEnabled,
126128
MappingsLoader defaultMappingsLoader,
129+
Map<String, MappingsLoaderExtension> mappingsLoaderExtensions,
127130
MappingsSaver mappingsSaver,
128131
boolean requestJournalDisabled,
129132
Integer maxRequestJournalEntries,
@@ -137,6 +140,7 @@ public WireMockApp(
137140

138141
this.browserProxyingEnabled = browserProxyingEnabled;
139142
this.defaultMappingsLoader = defaultMappingsLoader;
143+
this.mappingsLoaderExtensions = mappingsLoaderExtensions;
140144
this.mappingsSaver = mappingsSaver;
141145
this.settingsStore = stores.getSettingsStore();
142146
requestJournal =
@@ -236,6 +240,8 @@ private List<RequestFilterV2> getV2StubRequestFilters() {
236240

237241
private void loadDefaultMappings() {
238242
loadMappingsUsing(defaultMappingsLoader);
243+
if (mappingsLoaderExtensions != null)
244+
mappingsLoaderExtensions.values().forEach(e -> loadMappingsUsing(e));
239245
}
240246

241247
public void loadMappingsUsing(final MappingsLoader mappingsLoader) {
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Copyright (C) 2023 Thomas Akehurst
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.github.tomakehurst.wiremock.extension;
17+
18+
import com.github.tomakehurst.wiremock.standalone.MappingsLoader;
19+
20+
public interface MappingsLoaderExtension extends MappingsLoader, Extension {}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright (C) 2023 Thomas Akehurst
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.github.tomakehurst.wiremock.extension.mappingssource;
17+
18+
import static com.github.tomakehurst.wiremock.common.AbstractFileSource.byFileExtension;
19+
20+
import com.github.tomakehurst.wiremock.common.FileSource;
21+
import com.github.tomakehurst.wiremock.common.Json;
22+
import com.github.tomakehurst.wiremock.common.JsonException;
23+
import com.github.tomakehurst.wiremock.common.TextFile;
24+
import com.github.tomakehurst.wiremock.common.filemaker.FilenameMaker;
25+
import com.github.tomakehurst.wiremock.extension.MappingsLoaderExtension;
26+
import com.github.tomakehurst.wiremock.standalone.MappingFileException;
27+
import com.github.tomakehurst.wiremock.stubbing.StubMapping;
28+
import com.github.tomakehurst.wiremock.stubbing.StubMappingCollection;
29+
import com.github.tomakehurst.wiremock.stubbing.StubMappings;
30+
import java.util.*;
31+
import java.util.stream.Collectors;
32+
33+
public class DummyMappingsLoaderExtension implements MappingsLoaderExtension {
34+
35+
private final FileSource mappingsFileSource;
36+
private final Map<UUID, StubMappingFileMetadata> fileNameMap;
37+
private final FilenameMaker filenameMaker;
38+
39+
public DummyMappingsLoaderExtension(FileSource mappingsFileSource, FilenameMaker filenameMaker) {
40+
this.mappingsFileSource = mappingsFileSource;
41+
this.filenameMaker = Objects.requireNonNullElseGet(filenameMaker, FilenameMaker::new);
42+
fileNameMap = new HashMap<>();
43+
}
44+
45+
@Override
46+
public String getName() {
47+
return null;
48+
}
49+
50+
@Override
51+
public void loadMappingsInto(StubMappings stubMappings) {
52+
{
53+
if (!mappingsFileSource.exists()) {
54+
return;
55+
}
56+
57+
List<TextFile> mappingFiles =
58+
mappingsFileSource.listFilesRecursively().stream()
59+
.filter(byFileExtension("json"))
60+
.collect(Collectors.toList());
61+
for (TextFile mappingFile : mappingFiles) {
62+
try {
63+
StubMappingCollection stubCollection =
64+
Json.read(mappingFile.readContentsAsString(), StubMappingCollection.class);
65+
for (StubMapping mapping : stubCollection.getMappingOrMappings()) {
66+
mapping.setDirty(false);
67+
stubMappings.addMapping(mapping);
68+
StubMappingFileMetadata fileMetadata =
69+
new StubMappingFileMetadata(mappingFile.getPath(), stubCollection.isMulti());
70+
fileNameMap.put(mapping.getId(), fileMetadata);
71+
}
72+
} catch (JsonException e) {
73+
throw new MappingFileException(mappingFile.getPath(), e.getErrors().first().getDetail());
74+
}
75+
}
76+
}
77+
}
78+
79+
private static class StubMappingFileMetadata {
80+
final String path;
81+
final boolean multi;
82+
83+
public StubMappingFileMetadata(String path, boolean multi) {
84+
this.path = path;
85+
this.multi = multi;
86+
}
87+
}
88+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright (C) 2023 Thomas Akehurst
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.github.tomakehurst.wiremock.extension.mappingssource;
17+
18+
import static com.github.tomakehurst.wiremock.common.Exceptions.throwUnchecked;
19+
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
20+
import static org.hamcrest.MatcherAssert.assertThat;
21+
import static org.hamcrest.Matchers.is;
22+
23+
import com.github.tomakehurst.wiremock.WireMockServer;
24+
import com.github.tomakehurst.wiremock.common.FileSource;
25+
import com.github.tomakehurst.wiremock.common.SingleRootFileSource;
26+
import com.github.tomakehurst.wiremock.common.filemaker.FilenameMaker;
27+
import com.github.tomakehurst.wiremock.core.Options;
28+
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
29+
import com.github.tomakehurst.wiremock.testsupport.WireMockResponse;
30+
import com.github.tomakehurst.wiremock.testsupport.WireMockTestClient;
31+
import com.google.common.io.Resources;
32+
import java.io.File;
33+
import java.net.URISyntaxException;
34+
import org.junit.jupiter.api.AfterEach;
35+
import org.junit.jupiter.api.BeforeEach;
36+
import org.junit.jupiter.api.Test;
37+
38+
public class MappingsLoaderExtensionTest {
39+
40+
private WireMockConfiguration configuration;
41+
private WireMockServer wireMockServer;
42+
private WireMockTestClient testClient;
43+
44+
@BeforeEach
45+
public void init() {
46+
configuration = wireMockConfig().dynamicPort();
47+
}
48+
49+
@AfterEach
50+
public void stopWireMock() {
51+
wireMockServer.stop();
52+
}
53+
54+
private void buildWireMock(Options options) {
55+
wireMockServer = new WireMockServer(options);
56+
wireMockServer.start();
57+
testClient = new WireMockTestClient(wireMockServer.port());
58+
}
59+
60+
@Test
61+
public void mappingsLoadedFromJsonFilesWithMultipleMappingsSource() {
62+
FileSource filesRoot = new SingleRootFileSource(filePath("extension-test-request"));
63+
buildWireMock(
64+
configuration.extensions(new DummyMappingsLoaderExtension(filesRoot, new FilenameMaker())));
65+
66+
WireMockResponse response = testClient.get("/extension/resource/1");
67+
assertThat(response.statusCode(), is(200));
68+
}
69+
70+
public static String filePath(String path) {
71+
try {
72+
return new File(Resources.getResource(path).toURI()).getAbsolutePath();
73+
} catch (URISyntaxException e) {
74+
return throwUnchecked(e, String.class);
75+
}
76+
}
77+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"request": {
3+
"method": "GET",
4+
"url": "/extension/resource/1"
5+
},
6+
"response": {"status": 200}
7+
}

0 commit comments

Comments
 (0)