Last active
December 29, 2022 19:51
-
-
Save dalegaspi/d6ce6d179fa6887fc76293839fe93ac6 to your computer and use it in GitHub Desktop.
WireMock with Maven, Reflection, and Clojure
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
<?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> | |
<groupId>com.acme</groupId> | |
<artifactId>programmatic-services-mock</artifactId> | |
<version>1.0-SNAPSHOT</version> | |
<dependencies> | |
<dependency> | |
<groupId>com.github.tomakehurst</groupId> | |
<artifactId>wiremock-jre8</artifactId> | |
<version>2.35.0</version> | |
</dependency> | |
<dependency> | |
<groupId>org.junit.jupiter</groupId> | |
<artifactId>junit-jupiter-engine</artifactId> | |
<version>5.9.0</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>ch.qos.logback</groupId> | |
<artifactId>logback-classic</artifactId> | |
<version>1.4.5</version> | |
</dependency> | |
<dependency> | |
<groupId>org.slf4j</groupId> | |
<artifactId>slf4j-api</artifactId> | |
<version>2.0.5</version> | |
</dependency> | |
<dependency> | |
<groupId>org.clojure</groupId> | |
<artifactId>clojure</artifactId> | |
<version>1.11.1</version> | |
</dependency> | |
<dependency> | |
<groupId>org.projectlombok</groupId> | |
<artifactId>lombok</artifactId> | |
<version>1.18.24</version> | |
<scope>provided</scope> | |
</dependency> | |
<dependency> | |
<groupId>io.vavr</groupId> | |
<artifactId>vavr</artifactId> | |
<version>0.10.4</version> | |
</dependency> | |
<dependency> | |
<groupId>org.clojure</groupId> | |
<artifactId>tools.logging</artifactId> | |
<version>1.2.4</version> | |
</dependency> | |
<dependency> | |
<groupId>clj-wiremock</groupId> | |
<artifactId>clj-wiremock</artifactId> | |
<version>0.3.0</version> | |
</dependency> | |
<dependency> | |
<groupId>cheshire</groupId> | |
<artifactId>cheshire</artifactId> | |
<version>5.11.0</version> | |
</dependency> | |
<dependency> | |
<groupId>clj-http</groupId> | |
<artifactId>clj-http</artifactId> | |
<version>3.12.3</version> | |
</dependency> | |
</dependencies> | |
<properties> | |
<maven.compiler.source>17</maven.compiler.source> | |
<maven.compiler.target>17</maven.compiler.target> | |
</properties> | |
<build> | |
<plugins> | |
<plugin> | |
<groupId>com.theoryinpractise</groupId> | |
<artifactId>clojure-maven-plugin</artifactId> | |
<version>1.8.3</version> | |
<extensions>true</extensions> | |
<executions> | |
<execution> | |
<id>compile</id> | |
<goals> | |
<goal>compile</goal> | |
</goals> | |
</execution> | |
</executions> | |
</plugin> | |
<plugin> | |
<groupId>org.codehaus.mojo</groupId> | |
<artifactId>exec-maven-plugin</artifactId> | |
<version>1.6.0</version> | |
<executions> | |
<execution> | |
<id>start-wiremock</id> | |
<phase>pre-integration-test</phase> | |
<goals> | |
<goal>java</goal> | |
</goals> | |
<configuration> | |
<mainClass>com.github.tomakehurst.wiremock.standalone.WireMockServerRunner</mainClass> | |
<arguments>--verbose</arguments> | |
</configuration> | |
</execution> | |
</executions> | |
</plugin> | |
</plugins> | |
</build> | |
<repositories> | |
<repository> | |
<id>clojars.org</id> | |
<url>https://clojars.org/repo</url> | |
</repository> | |
</repositories> | |
</project> |
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
package com.acme; | |
import clojure.java.api.Clojure; | |
import clojure.lang.IFn; | |
import clojure.lang.ISeq; | |
import clojure.lang.SeqIterator; | |
import io.vavr.control.Either; | |
import io.vavr.control.Try; | |
import lombok.extern.slf4j.Slf4j; | |
import java.io.BufferedReader; | |
import java.io.InputStreamReader; | |
import java.util.ArrayList; | |
import java.util.List; | |
/** | |
* @author Dexter Legaspi | |
*/ | |
@Slf4j | |
public class WireMockConfigurations { | |
/** | |
* Java WireMockConfigurers | |
* | |
* @see WireMockConfigurer | |
* @param packageName the package | |
* @return Either error or the list of WireMockConfigurers | |
*/ | |
@SuppressWarnings("unchecked") | |
public static List<Either<Throwable, WireMockConfigurer>> getJavaConfigurers(String packageName) { | |
// https://www.baeldung.com/java-find-all-classes-in-package#1-system-class-loader | |
var packagePath = packageName.replaceAll("[.]", "/"); | |
var classLoader = ClassLoader.getSystemClassLoader(); | |
var resources = Try.of(() -> classLoader.getResourceAsStream(packagePath)) | |
.map(i -> new BufferedReader(new InputStreamReader(i))) | |
.map(b -> b.lines().filter(line -> line.endsWith(".class")).map(Try::success)) | |
.get(); | |
return resources.map( | |
s -> s.mapTry(c -> (Class<? extends WireMockConfigurer>) Class | |
.forName(packageName + "." + c.substring(0, c.lastIndexOf('.')))) | |
.mapTry(c -> (WireMockConfigurer) c.getDeclaredConstructor().newInstance()) | |
.toEither()) | |
.toList(); | |
} | |
public static List<Either<Throwable, WireMockConfigurer>> getClojureConfigurers(String namespace) { | |
// Require the clojure.reflect library | |
IFn require = Clojure.var("clojure.core", "require"); | |
require.invoke(Clojure.read("clojure.repl")); | |
// List the functions in the namespace | |
require.invoke(Clojure.read(namespace)); | |
IFn dir = Clojure.var("clojure.repl", "dir-fn"); | |
var functions = (ISeq) dir.invoke(Clojure.read(namespace)); | |
var fnames = new ArrayList<String>(); | |
for (var iter = new SeqIterator(functions); iter.hasNext();) { | |
fnames.add(iter.next().toString()); | |
} | |
return fnames.stream() | |
// https://github.com/stuarthalloway/clojure-from-java | |
.map(fn -> Try.of(() -> (WireMockConfigurer) ((Clojure.var(namespace, fn)).call()))) | |
.filter(Try::isSuccess).map(Try::toEither) | |
.toList(); | |
} | |
public static final int WIREMOCK_PORT = Integer.parseInt(System.getProperty("PROGRAMMATIC_MOCK_PORT", "8080")); | |
public static String CONFIGURER_PACKAGE = "com.integralads.programmatic.mock.configurers"; | |
public static void main(String[] args) { | |
getJavaConfigurers(CONFIGURER_PACKAGE) | |
.forEach(configurers -> configurers.forEach(c -> { | |
log.info("Running Java configurer {}", c.getClass().getSimpleName()); | |
c.configure(WIREMOCK_PORT); | |
})); | |
getClojureConfigurers(CONFIGURER_PACKAGE) | |
.forEach(configurers -> configurers.forEach(c -> { | |
log.info("Running Clojure configurer {}", c.getClass().getSimpleName()); | |
c.configure(WIREMOCK_PORT); | |
})); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment