@@ -68,12 +68,13 @@ You can provide the stubs to download via the `stubrunner.stubs.ids` system prop
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
groupId:artifactId:classifier:port
|
||||
groupId:artifactId:version:classifier:port
|
||||
----
|
||||
|
||||
`classifier` and `port` are optional.
|
||||
`version`, `classifier` and `port` are optional.
|
||||
|
||||
* If you don't provide the `classifier` then the default one will be taken.
|
||||
* If you don't provide the `port` then a random one will be picked
|
||||
* If you don't provide the `classifier` then the default one will be taken.
|
||||
* If you don't provide the `version` then the `+` will be passed and the latest one will be downloaded
|
||||
|
||||
Where `port` means the port of the WireMock server.
|
||||
@@ -26,12 +26,12 @@ class StubRunnerBootSpec extends Specification {
|
||||
new TriggerController(stubRunning))
|
||||
}
|
||||
|
||||
def 'should return a list of running stub servers in "ivy:port" notation'() {
|
||||
def 'should return a list of running stub servers in "full ivy:port" notation'() {
|
||||
when:
|
||||
String response = RestAssuredMockMvc.get('/stubs').body.asString()
|
||||
then:
|
||||
def root = new JsonSlurper().parseText(response)
|
||||
root.'io.codearte.accurest.stubs:streamService:stubs' instanceof Integer
|
||||
root.'io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs' instanceof Integer
|
||||
}
|
||||
|
||||
def 'should return a port on which a [#stubId] stub is running'() {
|
||||
@@ -41,7 +41,11 @@ class StubRunnerBootSpec extends Specification {
|
||||
response.statusCode == 200
|
||||
response.body.as(Integer) > 0
|
||||
where:
|
||||
stubId << ['io.codearte.accurest.stubs:streamService:stubs', 'io.codearte.accurest.stubs:streamService', 'streamService']
|
||||
stubId << ['io.codearte.accurest.stubs:streamService:+:stubs',
|
||||
'io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs',
|
||||
'io.codearte.accurest.stubs:streamService:+',
|
||||
'io.codearte.accurest.stubs:streamService',
|
||||
'streamService']
|
||||
}
|
||||
|
||||
def 'should return 404 when missing stub was called'() {
|
||||
@@ -51,12 +55,12 @@ class StubRunnerBootSpec extends Specification {
|
||||
response.statusCode == 404
|
||||
}
|
||||
|
||||
def 'should return a list of messaging labels that can be triggered'() {
|
||||
def 'should return a list of messaging labels that can be triggered when version and classifier are passed'() {
|
||||
when:
|
||||
String response = RestAssuredMockMvc.get('/triggers').body.asString()
|
||||
then:
|
||||
def root = new JsonSlurper().parseText(response)
|
||||
root.'io.codearte.accurest.stubs:streamService:stubs'.containsAll(["delete_book","return_book_1","return_book_2"])
|
||||
root.'io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs'?.containsAll(["delete_book","return_book_1","return_book_2"])
|
||||
}
|
||||
|
||||
def 'should trigger a messaging label'() {
|
||||
@@ -91,7 +95,7 @@ class StubRunnerBootSpec extends Specification {
|
||||
then:
|
||||
response.statusCode == 404
|
||||
def root = new JsonSlurper().parseText(response.body.asString())
|
||||
root.'io.codearte.accurest.stubs:streamService:stubs'.containsAll(["delete_book","return_book_1","return_book_2"])
|
||||
root.'io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs'?.containsAll(["delete_book","return_book_1","return_book_2"])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import io.codearte.accurest.stubrunner.util.StubsParser;
|
||||
*/
|
||||
public class AccurestRule implements TestRule, StubFinder {
|
||||
private static final String DELIMITER = ":";
|
||||
public static final String LATEST_VERSION = "+";
|
||||
|
||||
private LinkedList<String> stubs = new LinkedList<>();
|
||||
private StubRunnerOptions stubRunnerOptions = defaultStubRunnerOptions();
|
||||
@@ -109,10 +110,26 @@ public class AccurestRule implements TestRule, StubFinder {
|
||||
}
|
||||
|
||||
/**
|
||||
* Group Id, artifact Id and classifier of a single stub to download
|
||||
* Group Id, artifact Id, version and classifier of a single stub to download
|
||||
*/
|
||||
public AccurestRule downloadStub(String groupId, String artifactId, String classifier) {
|
||||
addStub(groupId + DELIMITER + artifactId + DELIMITER + classifier);
|
||||
public AccurestRule downloadStub(String groupId, String artifactId, String version, String classifier) {
|
||||
addStub(groupId + DELIMITER + artifactId + DELIMITER + version + DELIMITER + classifier);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Group Id, artifact Id and classifier of a single stub to download in the latest version
|
||||
*/
|
||||
public AccurestRule downloadLatestStub(String groupId, String artifactId, String classifier) {
|
||||
addStub(groupId + DELIMITER + artifactId + DELIMITER + LATEST_VERSION + DELIMITER + classifier);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Group Id, artifact Id and version of a single stub to download
|
||||
*/
|
||||
public AccurestRule downloadStub(String groupId, String artifactId, String version) {
|
||||
addStub(groupId + DELIMITER + artifactId + DELIMITER + version);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
package io.codearte.accurest.stubrunner.junit
|
||||
|
||||
import org.junit.AfterClass
|
||||
import org.junit.BeforeClass
|
||||
import org.junit.ClassRule
|
||||
import spock.lang.Shared
|
||||
import spock.lang.Specification
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
class AccurestRuleSysPropsSpec extends Specification {
|
||||
|
||||
@BeforeClass
|
||||
void setProps() {
|
||||
System.properties.setProperty("stubrunner.stubs.repository.root", AccurestRuleSysPropsSpec.getResource("/m2repo").toURI().toString())
|
||||
System.properties.setProperty("stubrunner.stubs.classifier", 'classifier that will be overridden')
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
void cleanupProps() {
|
||||
System.getProperties().setProperty("stubrunner.stubs.repository.root", "");
|
||||
System.getProperties().setProperty("stubrunner.stubs.classifier", "stubs");
|
||||
}
|
||||
|
||||
@ClassRule @Shared AccurestRule rule = new AccurestRule()
|
||||
.downloadStub("io.codearte.accurest.stubs", "loanIssuance", "stubs")
|
||||
.downloadStub("io.codearte.accurest.stubs:fraudDetectionServer:stubs")
|
||||
|
||||
def 'should start WireMock servers'() {
|
||||
expect: 'WireMocks are running'
|
||||
rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') != null
|
||||
rule.findStubUrl('loanIssuance') != null
|
||||
rule.findStubUrl('loanIssuance') == rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance')
|
||||
rule.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null
|
||||
and: 'Stubs were registered'
|
||||
"${rule.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance'
|
||||
"${rule.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer'
|
||||
cleanup:
|
||||
System.properties.setProperty("stubrunner.stubs.repository.root", "")
|
||||
System.properties.setProperty("stubrunner.stubs.classifier", 'stubs')
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1,2 @@
|
||||
stubrunner.stubs.repository.root: classpath:m2repo/repository/
|
||||
stubrunner.stubs.ids: io.codearte.accurest.stubs:integrationService
|
||||
stubrunner.stubs.ids: io.codearte.accurest.stubs:integrationService:0.0.1-SNAPSHOT
|
||||
@@ -1,5 +1,5 @@
|
||||
stubrunner.stubs.repository.root: classpath:m2repo/repository/
|
||||
stubrunner.stubs.ids: io.codearte.accurest.stubs:streamService
|
||||
stubrunner.stubs.ids: io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs
|
||||
|
||||
spring:
|
||||
cloud:
|
||||
|
||||
@@ -22,7 +22,7 @@ You can set the following options to the main class:
|
||||
(default: 10000)
|
||||
-s (--stubs) VAL : Comma separated list of Ivy representation of
|
||||
jars with stubs. Eg. groupid:artifactid1,group
|
||||
id2:artifactid2:classifier
|
||||
id2:artifactid2:version:classifier
|
||||
-sr (--stubRepositoryRoot) VAL : Location of a Jar containing server where you
|
||||
keep your stubs (e.g. http://nexus.net/content
|
||||
/repositories/repository)
|
||||
@@ -48,7 +48,7 @@ and inside the `build/lib` there will be a Fat Jar with classifier `fatJar` wait
|
||||
|
||||
[source,groovy,indent=0]
|
||||
----
|
||||
java -jar stub-runner/stub-runner/build/libs/stub-runner-1.0.1-SNAPSHOT-fatJar.jar -sr http://a.b.com -s a:b:c,d:e,f:g:h
|
||||
java -jar stub-runner/stub-runner/build/libs/stub-runner-1.0.1-SNAPSHOT-fatJar.jar -sr http://a.b.com -s a:b:c,d:e,f:g:h:i
|
||||
----
|
||||
|
||||
==== Stub runner configuration
|
||||
|
||||
@@ -12,19 +12,14 @@ import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory
|
||||
import org.eclipse.aether.impl.DefaultServiceLocator
|
||||
import org.eclipse.aether.repository.LocalRepository
|
||||
import org.eclipse.aether.repository.RemoteRepository
|
||||
import org.eclipse.aether.resolution.ArtifactRequest
|
||||
import org.eclipse.aether.resolution.ArtifactResult
|
||||
import org.eclipse.aether.resolution.VersionRangeRequest
|
||||
import org.eclipse.aether.resolution.VersionRangeResult
|
||||
import org.eclipse.aether.resolution.*
|
||||
import org.eclipse.aether.spi.connector.RepositoryConnectorFactory
|
||||
import org.eclipse.aether.spi.connector.transport.TransporterFactory
|
||||
import org.eclipse.aether.transport.file.FileTransporterFactory
|
||||
import org.eclipse.aether.transport.http.HttpTransporterFactory
|
||||
import org.eclipse.aether.version.Version
|
||||
|
||||
import static io.codearte.accurest.stubrunner.util.ZipCategory.unzipTo
|
||||
import static java.nio.file.Files.createTempDirectory
|
||||
|
||||
/**
|
||||
* @author Mariusz Smykula
|
||||
*/
|
||||
@@ -35,7 +30,8 @@ class AetherStubDownloader implements StubDownloader {
|
||||
private static final String MAVEN_LOCAL_REPOSITORY_LOCATION = 'maven.repo.local'
|
||||
private static final String ACCUREST_TEMP_DIR_PREFIX = 'accurest'
|
||||
private static final String ARTIFACT_EXTENSION = 'jar'
|
||||
private static final String ARTIFACT_VERSION = '(0,]'
|
||||
private static final String LATEST_ARTIFACT_VERSION = '(0,]'
|
||||
private static final String LATEST_VERSION_IN_IVY = "+"
|
||||
|
||||
private final List<RemoteRepository> remoteRepos
|
||||
private final RepositorySystem repositorySystem
|
||||
@@ -79,25 +75,63 @@ class AetherStubDownloader implements StubDownloader {
|
||||
|
||||
@Override
|
||||
public File downloadAndUnpackStubJar(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String stubsModule, String classifier) {
|
||||
Version highestVersion = resolveArtifactVersion(stubsGroup, stubsModule, classifier);
|
||||
log.info("Resolved highest version is $highestVersion")
|
||||
if (!highestVersion) {
|
||||
String version = getVersion(stubsGroup, stubsModule, LATEST_VERSION_IN_IVY, classifier)
|
||||
return unpackedJar(version, stubsGroup, stubsModule, classifier, stubRepositoryRoot)
|
||||
}
|
||||
|
||||
private File unpackedJar(String resolvedVersion, String stubsGroup, String stubsModule, String classifier, String stubRepositoryRoot) {
|
||||
log.info("Resolved version is $resolvedVersion")
|
||||
if (!resolvedVersion) {
|
||||
log.warn("Stub for group [$stubsGroup] module [$stubsModule] and classifier [$classifier] not found in [$stubRepositoryRoot]")
|
||||
return null
|
||||
}
|
||||
Artifact artifact = new DefaultArtifact(stubsGroup, stubsModule, classifier, ARTIFACT_EXTENSION, highestVersion.toString())
|
||||
Artifact artifact = new DefaultArtifact(stubsGroup, stubsModule, classifier, ARTIFACT_EXTENSION, resolvedVersion)
|
||||
ArtifactRequest request = new ArtifactRequest(artifact: artifact, repositories: remoteRepos)
|
||||
log.info("Resolving artifact $artifact from ${remoteRepos?:'local maven repo'}")
|
||||
ArtifactResult result = repositorySystem.resolveArtifact(session, request)
|
||||
log.info("Resolved artifact $artifact to ${result.artifact.file} from ${result.repository}")
|
||||
return unpackStubJarToATemporaryFolder(result.artifact.file.toURI())
|
||||
log.info("Resolving artifact $artifact from ${remoteRepos ?: 'local maven repo'}")
|
||||
try {
|
||||
ArtifactResult result = repositorySystem.resolveArtifact(session, request)
|
||||
log.info("Resolved artifact $artifact to ${result.artifact.file} from ${result.repository}")
|
||||
return unpackStubJarToATemporaryFolder(result.artifact.file.toURI())
|
||||
} catch (Exception e) {
|
||||
log.warn("Exception occured while trying to download a stub for group [$stubsGroup] module [$stubsModule] and classifier [$classifier] in [$stubRepositoryRoot]", e)
|
||||
return null
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Version resolveArtifactVersion(String stubsGroup, String stubsModule, String classifier) {
|
||||
Artifact artifact = new DefaultArtifact(stubsGroup, stubsModule, classifier, ARTIFACT_EXTENSION, ARTIFACT_VERSION)
|
||||
private String getVersion(String stubsGroup, String stubsModule, String version, String classifier) {
|
||||
if (!version || LATEST_VERSION_IN_IVY == version) {
|
||||
log.info("Desired version is [$version] - will try to resolve the latest version")
|
||||
return resolveHighestArtifactVersion(stubsGroup, stubsModule, classifier);
|
||||
}
|
||||
log.info("Will try to resolve version [$version]")
|
||||
return resolveArtifactVersion(stubsGroup, stubsModule, version, classifier)
|
||||
}
|
||||
|
||||
@Override
|
||||
Map.Entry<StubConfiguration,File> downloadAndUnpackStubJar(StubRunnerOptions options, StubConfiguration stubConfiguration) {
|
||||
String version = getVersion(stubConfiguration.groupId, stubConfiguration.artifactId, stubConfiguration.version, stubConfiguration.classifier)
|
||||
File unpackedJar = unpackedJar(version, stubConfiguration.groupId, stubConfiguration.artifactId,
|
||||
stubConfiguration.classifier, options.stubRepositoryRoot)
|
||||
if(!unpackedJar) {
|
||||
return null
|
||||
}
|
||||
return new AbstractMap.SimpleEntry(new StubConfiguration(stubConfiguration.groupId, stubConfiguration.artifactId, version, stubConfiguration.classifier),
|
||||
unpackedJar)
|
||||
}
|
||||
|
||||
private String resolveHighestArtifactVersion(String stubsGroup, String stubsModule, String classifier) {
|
||||
Artifact artifact = new DefaultArtifact(stubsGroup, stubsModule, classifier, ARTIFACT_EXTENSION, LATEST_ARTIFACT_VERSION)
|
||||
VersionRangeRequest versionRangeRequest = new VersionRangeRequest(artifact, remoteRepos, null);
|
||||
VersionRangeResult rangeResult = repositorySystem.resolveVersionRange(session, versionRangeRequest);
|
||||
return rangeResult.highestVersion;
|
||||
return rangeResult.highestVersion ?: ''
|
||||
}
|
||||
|
||||
private String resolveArtifactVersion(String stubsGroup, String stubsModule, String version, String classifier) {
|
||||
Artifact artifact = new DefaultArtifact(stubsGroup, stubsModule, classifier, ARTIFACT_EXTENSION, version)
|
||||
VersionRequest versionRequest = new VersionRequest(artifact, remoteRepos, null)
|
||||
VersionResult versionResult = repositorySystem.resolveVersion(session, versionRequest);
|
||||
return versionResult.version ?: ''
|
||||
}
|
||||
|
||||
private static File unpackStubJarToATemporaryFolder(URI stubJarUri) {
|
||||
|
||||
@@ -26,26 +26,14 @@ class RunningStubs {
|
||||
}
|
||||
|
||||
Map.Entry<StubConfiguration, Integer> getEntry(String artifactId) {
|
||||
def strings = artifactId.split(':')
|
||||
if (strings.length == 1) {
|
||||
return namesAndPorts.entrySet().find {
|
||||
it.key.artifactId == artifactId
|
||||
}
|
||||
} else if(strings.length == 2) {
|
||||
return namesAndPorts.entrySet().find {
|
||||
it.key.groupId == strings[0] && it.key.artifactId == strings[1]
|
||||
}
|
||||
}
|
||||
return namesAndPorts.entrySet().find {
|
||||
it.key.groupId == strings[0] &&
|
||||
it.key.artifactId == strings[1] &&
|
||||
it.key.classifier == strings[2]
|
||||
it.key.matchesIvyNotation(artifactId)
|
||||
}
|
||||
}
|
||||
|
||||
Integer getPort(String groupId, String artifactId) {
|
||||
return namesAndPorts.entrySet().find {
|
||||
it.key.artifactId == artifactId && it.key.groupId == groupId
|
||||
it.key.matchesIvyNotation("$groupId:$artifactId")
|
||||
}?.value
|
||||
}
|
||||
|
||||
@@ -55,7 +43,7 @@ class RunningStubs {
|
||||
|
||||
boolean isPresent(String groupId, String artifactId) {
|
||||
return namesAndPorts.entrySet().find {
|
||||
it.key.artifactId == artifactId && it.key.groupId == groupId
|
||||
it.key.matchesIvyNotation("$groupId:$artifactId")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,54 +12,72 @@ import io.codearte.accurest.stubrunner.util.StringUtils
|
||||
@EqualsAndHashCode
|
||||
public class StubConfiguration {
|
||||
private static final String STUB_COLON_DELIMITER = ":"
|
||||
private static final String DEFAULT_VERSION = "+"
|
||||
private static final String DEFAULT_CLASSIFIER = "stubs"
|
||||
|
||||
final String groupId
|
||||
final String artifactId
|
||||
final String version
|
||||
final String classifier
|
||||
|
||||
public StubConfiguration(String groupId, String artifactId, String classifier) {
|
||||
public StubConfiguration(String groupId, String artifactId, String version) {
|
||||
this.groupId = groupId
|
||||
this.artifactId = artifactId
|
||||
this.version = version
|
||||
this.classifier = DEFAULT_CLASSIFIER
|
||||
}
|
||||
|
||||
public StubConfiguration(String groupId, String artifactId, String version, String classifier) {
|
||||
this.groupId = groupId
|
||||
this.artifactId = artifactId
|
||||
this.version = version
|
||||
this.classifier = classifier
|
||||
}
|
||||
|
||||
public StubConfiguration(String stubPath, String defaultClassifier = "stubs") {
|
||||
public StubConfiguration(String stubPath, String defaultClassifier) {
|
||||
String[] parsedPath = parsedPathEmptyByDefault(stubPath, STUB_COLON_DELIMITER, defaultClassifier)
|
||||
this.groupId = parsedPath[0]
|
||||
this.artifactId = parsedPath[1]
|
||||
this.classifier = parsedPath[2]
|
||||
this.version = parsedPath[2]
|
||||
this.classifier = parsedPath[3]
|
||||
}
|
||||
|
||||
public StubConfiguration(String stubPath) {
|
||||
String[] parsedPath = parsedPathEmptyByDefault(stubPath, STUB_COLON_DELIMITER, DEFAULT_CLASSIFIER)
|
||||
this.groupId = parsedPath[0]
|
||||
this.artifactId = parsedPath[1]
|
||||
this.version = parsedPath[2]
|
||||
this.classifier = parsedPath[3]
|
||||
}
|
||||
|
||||
private List<String> parsedPathEmptyByDefault(String path, String delimiter, String defaultClassifier) {
|
||||
String[] splitPath = path.split(delimiter)
|
||||
String stubsGroupId = ""
|
||||
String stubsArtifactId = ""
|
||||
String stubsVersion = ""
|
||||
String stubsClassifier = ""
|
||||
if (splitPath.length >= 2) {
|
||||
stubsGroupId = splitPath[0]
|
||||
stubsArtifactId = splitPath[1]
|
||||
stubsClassifier = splitPath.length == 3 ? splitPath[2] : defaultClassifier
|
||||
stubsVersion = splitPath.length >= 3 ? splitPath[2] : DEFAULT_VERSION
|
||||
stubsClassifier = splitPath.length == 4 ? splitPath[3] : defaultClassifier
|
||||
}
|
||||
return [stubsGroupId, stubsArtifactId, stubsClassifier]
|
||||
return [stubsGroupId, stubsArtifactId, stubsVersion, stubsClassifier]
|
||||
}
|
||||
|
||||
private boolean isDefined() {
|
||||
return StringUtils.hasText(groupId) && StringUtils.hasText(this.artifactId)
|
||||
}
|
||||
|
||||
boolean hasClassifier() {
|
||||
return StringUtils.hasText(classifier)
|
||||
}
|
||||
|
||||
String toColonSeparatedDependencyNotation() {
|
||||
if(!isDefined()) {
|
||||
return ""
|
||||
}
|
||||
return [groupId, artifactId, classifier].join(STUB_COLON_DELIMITER)
|
||||
return [groupId, artifactId, version, classifier].join(STUB_COLON_DELIMITER)
|
||||
}
|
||||
|
||||
@CompileDynamic
|
||||
boolean matches(String ivyNotationAsString) {
|
||||
boolean groupIdAndArtifactMatches(String ivyNotationAsString) {
|
||||
def (String groupId, String artifactId) = ivyNotationFrom(ivyNotationAsString)
|
||||
if (!groupId) {
|
||||
return this.artifactId == artifactId
|
||||
@@ -67,6 +85,43 @@ public class StubConfiguration {
|
||||
return this.groupId == groupId && this.artifactId == artifactId
|
||||
}
|
||||
|
||||
boolean equals(o) {
|
||||
if (this.is(o)) return true
|
||||
if (getClass() != o.class) return false
|
||||
|
||||
StubConfiguration that = (StubConfiguration) o
|
||||
|
||||
if (artifactId != that.artifactId) return false
|
||||
if (groupId != that.groupId) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
int hashCode() {
|
||||
int result
|
||||
result = (groupId != null ? groupId.hashCode() : 0)
|
||||
result = 31 * result + (artifactId != null ? artifactId.hashCode() : 0)
|
||||
return result
|
||||
}
|
||||
|
||||
boolean matchesIvyNotation(String ivyNotationAsString) {
|
||||
def strings = ivyNotationAsString.split(':')
|
||||
if (strings.length == 1) {
|
||||
return artifactId == ivyNotationAsString
|
||||
} else if(strings.length == 2) {
|
||||
return groupId == strings[0] &&
|
||||
artifactId == strings[1]
|
||||
} else if(strings.length == 3) {
|
||||
return groupId == strings[0] &&
|
||||
artifactId == strings[1] &&
|
||||
(strings[2] == DEFAULT_VERSION || version == strings[2])
|
||||
}
|
||||
return groupId == strings[0] &&
|
||||
artifactId == strings[1] &&
|
||||
(strings[2] == DEFAULT_VERSION || version == strings[2]) &&
|
||||
classifier == strings[3]
|
||||
}
|
||||
|
||||
private String[] ivyNotationFrom(String ivyNotation) {
|
||||
String[] splitString = ivyNotation.split(":")
|
||||
if (splitString.length == 1) {
|
||||
|
||||
@@ -2,6 +2,15 @@ package io.codearte.accurest.stubrunner
|
||||
|
||||
interface StubDownloader {
|
||||
|
||||
@Deprecated
|
||||
File downloadAndUnpackStubJar(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String
|
||||
stubsModule, String classifier)
|
||||
|
||||
/**
|
||||
* Returns a mapping of updated StubConfiguration (it will contain the resolved version) and the location of the downloaded JAR.
|
||||
* If there was no artifact this method will return {@code null}.
|
||||
*/
|
||||
Map.Entry<StubConfiguration,File> downloadAndUnpackStubJar(StubRunnerOptions options, StubConfiguration stubConfiguration)
|
||||
|
||||
|
||||
}
|
||||
@@ -71,7 +71,7 @@ class StubRunnerExecutor implements StubFinder {
|
||||
@Override
|
||||
boolean trigger(String ivyNotationAsString, String labelName) {
|
||||
Collection<GroovyDsl> matchingContracts = getAccurestContracts().findAll {
|
||||
it.key.matches(ivyNotationAsString)
|
||||
it.key.groupIdAndArtifactMatches(ivyNotationAsString)
|
||||
}.values().flatten() as Collection<GroovyDsl>
|
||||
return triggerForDsls(matchingContracts, labelName)
|
||||
}
|
||||
|
||||
@@ -27,14 +27,15 @@ class StubRunnerFactory {
|
||||
|
||||
Collection<StubRunner> createStubsFromServiceConfiguration() {
|
||||
return collaborators.collect { StubConfiguration stubsConfiguration ->
|
||||
final File unzipedStubDir = stubDownloader.downloadAndUnpackStubJar(stubRunnerOptions.workOffline,
|
||||
stubRunnerOptions.stubRepositoryRoot,
|
||||
stubsConfiguration.groupId, stubsConfiguration.artifactId, stubsConfiguration.classifier)
|
||||
return createStubRunner(unzipedStubDir, stubsConfiguration)
|
||||
Map.Entry<StubConfiguration, File> entry = stubDownloader.downloadAndUnpackStubJar(stubRunnerOptions, stubsConfiguration)
|
||||
if (!entry) {
|
||||
return null
|
||||
}
|
||||
return createStubRunner(entry.key, entry.value)
|
||||
}.findAll { it != null }
|
||||
}
|
||||
|
||||
private StubRunner createStubRunner(File unzipedStubDir, StubConfiguration stubsConfiguration) {
|
||||
private StubRunner createStubRunner(StubConfiguration stubsConfiguration, File unzipedStubDir) {
|
||||
if (!unzipedStubDir) {
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -6,26 +6,31 @@ import spock.lang.Specification
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
class RunningStubsSpec extends Specification {
|
||||
RunningStubs runningStubs = new RunningStubs([(new StubConfiguration('a', 'b', 'c')) : 100])
|
||||
RunningStubs runningStubs = new RunningStubs([(new StubConfiguration('group', 'artifact', 'version', 'classifier')) : 100])
|
||||
|
||||
def "should get port by group and artifact id"() {
|
||||
expect:
|
||||
runningStubs.getPort('a', 'b') == 100
|
||||
runningStubs.getPort('group', 'artifact') == 100
|
||||
}
|
||||
|
||||
def "should get port by artifact id"() {
|
||||
expect:
|
||||
runningStubs.getPort('b') == 100
|
||||
runningStubs.getPort('artifact') == 100
|
||||
}
|
||||
|
||||
def "should get port by group and artifact id in Ivy notation"() {
|
||||
expect:
|
||||
runningStubs.getPort('a:b') == 100
|
||||
runningStubs.getPort('group:artifact') == 100
|
||||
}
|
||||
|
||||
def "should get port by group, artifact id and classifier in Ivy notation"() {
|
||||
def "should get port by group, artifact id and version in Ivy notation"() {
|
||||
expect:
|
||||
runningStubs.getPort('a:b:c') == 100
|
||||
runningStubs.getPort('group:artifact:version') == 100
|
||||
}
|
||||
|
||||
def "should get port by group, artifact id, version and classifier in Ivy notation"() {
|
||||
expect:
|
||||
runningStubs.getPort('group:artifact:version:classifier') == 100
|
||||
}
|
||||
|
||||
def "should return null if no stub has been found"() {
|
||||
@@ -35,22 +40,27 @@ class RunningStubsSpec extends Specification {
|
||||
|
||||
def "should find stub by group and artifact id"() {
|
||||
expect:
|
||||
runningStubs.isPresent('a', 'b')
|
||||
runningStubs.isPresent('group', 'artifact')
|
||||
}
|
||||
|
||||
def "should find stub by artifact id"() {
|
||||
expect:
|
||||
runningStubs.isPresent('b')
|
||||
runningStubs.isPresent('artifact')
|
||||
}
|
||||
|
||||
def "should find stub by group and artifact id in Ivy notation"() {
|
||||
expect:
|
||||
runningStubs.isPresent('a:b')
|
||||
runningStubs.isPresent('group:artifact')
|
||||
}
|
||||
|
||||
def "should find stub by group, artifact id and classifier in Ivy notation"() {
|
||||
def "should find stub by group, artifact id and version in Ivy notation"() {
|
||||
expect:
|
||||
runningStubs.isPresent('a:b:c')
|
||||
runningStubs.isPresent('group:artifact:version')
|
||||
}
|
||||
|
||||
def "should find stub by group, artifact id, version and classifier in Ivy notation"() {
|
||||
expect:
|
||||
runningStubs.isPresent('group:artifact:version:classifier')
|
||||
}
|
||||
|
||||
def "should return false if no stub has been found"() {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package io.codearte.accurest.stubrunner
|
||||
|
||||
import spock.lang.Specification
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
class StubConfigurationSpec extends Specification {
|
||||
|
||||
def 'should parse ivy notation'() {
|
||||
given:
|
||||
String ivy = 'group:artifact:version:classifier'
|
||||
when:
|
||||
StubConfiguration stubConfiguration = new StubConfiguration(ivy)
|
||||
then:
|
||||
stubConfiguration.artifactId == 'artifact'
|
||||
stubConfiguration.groupId == 'group'
|
||||
stubConfiguration.classifier == 'classifier'
|
||||
stubConfiguration.version == 'version'
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,8 @@ import spock.lang.Specification
|
||||
|
||||
class StubRunnerExecutorSpec extends Specification {
|
||||
|
||||
static final URL EXPECTED_STUB_URL = new URL('http://localhost:8999')
|
||||
static final int MIN_PORT = 8999
|
||||
static final int MAX_PORT = 8999
|
||||
static final int MAX_PORT = 9999
|
||||
|
||||
private AvailablePortScanner portScanner
|
||||
private StubRepository repository
|
||||
@@ -24,7 +23,9 @@ class StubRunnerExecutorSpec extends Specification {
|
||||
when:
|
||||
executor.runStubs(stubRunnerOptions, repository, stub)
|
||||
then:
|
||||
executor.findStubUrl("group", "artifact") == EXPECTED_STUB_URL
|
||||
URL url = executor.findStubUrl("group", "artifact")
|
||||
url.port >= MIN_PORT
|
||||
url.port <= MAX_PORT
|
||||
and:
|
||||
executor.findAllRunningStubs().isPresent('artifact')
|
||||
executor.findAllRunningStubs().isPresent('group', 'artifact')
|
||||
|
||||
@@ -18,7 +18,8 @@ class StubRunnerFactorySpec extends Specification {
|
||||
def "Should download stub definitions many times"() {
|
||||
given:
|
||||
folder.newFolder("mappings")
|
||||
2 * downloader.downloadAndUnpackStubJar(_, _, _, _, _) >> folder.root
|
||||
1 * downloader.downloadAndUnpackStubJar(_, _) >> new AbstractMap.SimpleEntry(new StubConfiguration('a:b'), folder.root)
|
||||
1 * downloader.downloadAndUnpackStubJar(_, _) >> new AbstractMap.SimpleEntry(new StubConfiguration('c:d'), folder.root)
|
||||
stubRunnerOptions.stubRepositoryRoot = folder.root.absolutePath
|
||||
when:
|
||||
Collection<StubRunner> stubRunners = collectOnlyPresentValues(factory.createStubsFromServiceConfiguration())
|
||||
|
||||
Reference in New Issue
Block a user