diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/BatchStubRunner.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/BatchStubRunner.java index d2a5e2be07..62bf60bb15 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/BatchStubRunner.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/BatchStubRunner.java @@ -52,24 +52,21 @@ public class BatchStubRunner implements StubRunning { @Override public URL findStubUrl(String groupId, String artifactId) { for (StubRunner stubRunner : this.stubRunners) { - URL url = stubRunner.findStubUrl(groupId, artifactId); - if (url != null) { - return url; - } + try { + return stubRunner.findStubUrl(groupId, artifactId); + } catch (StubNotFoundException e) {} } - return null; + throw new StubNotFoundException(groupId, artifactId); } @Override public URL findStubUrl(String ivyNotation) { - String[] splitString = ivyNotation.split(":"); - if (splitString.length > 3) { - throw new IllegalArgumentException(ivyNotation + " is invalid"); + for (StubRunner stubRunner : this.stubRunners) { + try { + return stubRunner.findStubUrl(ivyNotation); + } catch (StubNotFoundException e) {} } - else if (splitString.length == 2) { - return findStubUrl(splitString[0], splitString[1]); - } - return findStubUrl(null, splitString[0]); + throw new StubNotFoundException(ivyNotation); } @Override diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubConfiguration.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubConfiguration.java index 23a6caccfd..d6b68643fb 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubConfiguration.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubConfiguration.java @@ -20,7 +20,7 @@ import org.springframework.util.StringUtils; /** * Represents a configuration of a single stub. The stub can be described by - * groupId:artifactId:classifier notation + * groupId:artifactId:version:classifier notation */ public class StubConfiguration { private static final String STUB_COLON_DELIMITER = ":"; diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubFinder.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubFinder.java index 1fb77f8403..8d7a473b91 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubFinder.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubFinder.java @@ -28,18 +28,18 @@ public interface StubFinder extends StubTrigger { * URL of the running stub. * * @param groupId - might be null. In that case a search only via artifactId takes place - * @return URL of a running stub or null if not found + * @return URL of a running stub or throws exception if not found */ - URL findStubUrl(String groupId, String artifactId); + URL findStubUrl(String groupId, String artifactId) throws StubNotFoundException; /** - * For the given Ivy notation {@code groupId:artifactId} tries to find the matching - * URL of the running stub. You can also pass only {@code artifactId}. + * For the given Ivy notation {@code [groupId]:artifactId:[version]:[classifier]} tries to + * find the matching URL of the running stub. You can also pass only {@code artifactId}. * * @param ivyNotation - Ivy representation of the Maven artifact - * @return URL of a running stub or null if not found + * @return URL of a running stub or throws exception if not found */ - URL findStubUrl(String ivyNotation); + URL findStubUrl(String ivyNotation) throws StubNotFoundException; /** * Returns all running stubs diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubNotFoundException.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubNotFoundException.java new file mode 100644 index 0000000000..4835d2be0e --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubNotFoundException.java @@ -0,0 +1,18 @@ +package org.springframework.cloud.contract.stubrunner; + +/** + * Exception thrown when a stub was not found + * + * @author Marcin Grzejszczak + * @since 1.0.1 + */ +public class StubNotFoundException extends RuntimeException { + + public StubNotFoundException(String groupId, String artifactId) { + super("Stub not found for groupid [" + groupId + "] and artifactid [" + artifactId + "]"); + } + + public StubNotFoundException(String ivyNotation) { + super("Stub not found for stub with notation [" + ivyNotation + "]"); + } +} diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunner.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunner.java index c3ed9fa5fd..c2c2f7cf0c 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunner.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunner.java @@ -75,12 +75,7 @@ public class StubRunner implements StubRunning { @Override public URL findStubUrl(String ivyNotation) { - String[] splitString = ivyNotation.split(":"); - if (splitString.length == 1) { - // assuming that ivy notation represents artifactId only - return findStubUrl(null, splitString[0]); - } - return findStubUrl(splitString[0], splitString[1]); + return this.localStubRunner.findStubUrl(ivyNotation); } @Override diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.java index d66c1e87b1..2f36d99428 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.java @@ -85,22 +85,48 @@ class StubRunnerExecutor implements StubFinder { @Override public URL findStubUrl(String groupId, String artifactId) { + URL url = null; if (groupId == null) { - return returnStubUrlIfMatches( - artifactId.equals(this.stubServer.stubConfiguration.artifactId)); + url = findStubUrl( + this.stubServer.stubConfiguration.artifactId.equals(artifactId)); } - return returnStubUrlIfMatches( - artifactId.equals(this.stubServer.stubConfiguration.artifactId) - && groupId.equals(this.stubServer.stubConfiguration.groupId)); + if (url == null) { + url = findStubUrl(this.stubServer.stubConfiguration.artifactId.equals(artifactId) + && this.stubServer.stubConfiguration.groupId.equals(groupId)); + } + if (url == null) { + throw new StubNotFoundException(groupId, artifactId); + } + return url; } @Override public URL findStubUrl(String ivyNotation) { String[] splitString = ivyNotation.split(":"); - if (splitString.length == 1) { - throw new IllegalArgumentException("$ivyNotation is invalid"); + if (splitString.length > 4) { + throw new IllegalArgumentException("[" + ivyNotation + "] is an invalid notation. Pass [groupId]:artifactId[:version][:classifier]."); + } else if (splitString.length == 1) { + return findStubUrl(null, splitString[0]); + } else if (splitString.length == 2) { + return findStubUrl(splitString[0], splitString[1]); + } else if (splitString.length == 3) { + return findStubUrl(groupIdArtifactVersionMatches(splitString)); } - return findStubUrl(splitString[0], splitString[1]); + return findStubUrl(groupIdArtifactVersionMatches(splitString) && classifierMatches(splitString)); + } + + private boolean classifierMatches(String[] splitString) { + return this.stubServer.stubConfiguration.classifier.equals(splitString[3]); + } + + private boolean groupIdArtifactVersionMatches(String[] splitString) { + return this.stubServer.stubConfiguration.artifactId.equals(splitString[0]) + && this.stubServer.stubConfiguration.groupId.equals(splitString[1]) + && this.stubServer.stubConfiguration.version.equals(splitString[2]); + } + + private URL findStubUrl(boolean condition) { + return returnStubUrlIfMatches(condition); } @Override diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/AutoConfigureStubRunner.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/AutoConfigureStubRunner.java index d414ad2b19..85ee3b05d2 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/AutoConfigureStubRunner.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/AutoConfigureStubRunner.java @@ -60,7 +60,8 @@ public @interface AutoConfigureStubRunner { String repositoryRoot() default ""; /** - * The ids of the stubs to run in "ivy" notation (groupId:artifactId[:classifier]:version[:port]). + * The ids of the stubs to run in "ivy" notation ([groupId]:artifactId:[classifier]:[version][:port]). + * {@code groupId}, {@code classifier}, {@code version} and {@code port} can be optional. */ String[] ids() default {}; diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerProperties.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerProperties.java index be9feded2f..7f195bb5d1 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerProperties.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerProperties.java @@ -50,7 +50,8 @@ public class StubRunnerProperties { private Resource repositoryRoot; /** - * The ids of the stubs to run in "ivy" notation (groupId:artifactId[:classifier]:version[:port]). + * The ids of the stubs to run in "ivy" notation ([groupId]:artifactId:[classifier]:[version][:port]). + * {@code groupId}, {@code classifier}, {@code version} and {@code port} can be optional. */ private String[] ids = new String[0]; diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/util/StubsParser.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/util/StubsParser.java index f0baf4f416..8638a0b702 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/util/StubsParser.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/util/StubsParser.java @@ -34,7 +34,9 @@ public class StubsParser { * that contains a list of Strings in the format * *