[[features-stub-runner-stubs-protocol]]
= Fetching Stubs or Contract Definitions From A Location

include::partial$_attributes.adoc[]

Instead of picking the stubs or contract definitions from
Artifactory, Nexus, or Git, you can point to
a location on a drive or the classpath. Doing so can be especially useful in a multi-module project, where one module wants
to reuse stubs or contracts from another module without
the need to actually install those in a local maven
repository to commit those changes to Git.

In order to achieve this, you can use the `stubs://`
protocol when the repository root parameter is set either
in Stub Runner or in a Spring Cloud Contract plugin.

In this example, the `producer` project has been successfully
built and stubs were generated under the `target/stubs` folder. As a consumer, one can set up the Stub Runner to pick the stubs from that location by using the `stubs://` protocol.

====
[source,java,indent=0,subs="verbatim",role="primary"]
.Annotation
----
@AutoConfigureStubRunner(
stubsMode = StubRunnerProperties.StubsMode.REMOTE,
		repositoryRoot = "stubs://file://location/to/the/producer/target/stubs/",
		ids = "com.example:some-producer")
----

[source,java,indent=0,subs="verbatim",role="secondary"]
.JUnit 4 Rule
----
@Rule
	public StubRunnerRule rule = new StubRunnerRule()
			.downloadStub("com.example:some-producer")
			.repoRoot("stubs://file://location/to/the/producer/target/stubs/")
			.stubsMode(StubRunnerProperties.StubsMode.REMOTE);
----

[source,java,indent=0,subs="verbatim",role="secondary"]
.JUnit 5 Extension
----
@RegisterExtension
	public StubRunnerExtension stubRunnerExtension = new StubRunnerExtension()
			.downloadStub("com.example:some-producer")
			.repoRoot("stubs://file://location/to/the/producer/target/stubs/")
			.stubsMode(StubRunnerProperties.StubsMode.REMOTE);
----
====

Contracts and stubs may be stored in a location, where each producer has its own, dedicated folder for contracts and stub mappings. Under that folder, each consumer can have its own setup. To make Stub Runner find the dedicated folder from the provided IDs, you can pass the `stubs.find-producer=true` property or the `stubrunner.stubs.find-producer=true` system property.
The following listing shows an arrangement of contracts and stubs:

====
[source,bash,indent=0]
----
└── com.example <1>
    ├── some-artifact-id <2>
    │   └── 0.0.1
    │       ├── contracts <3>
    │       │   └── shouldReturnStuffForArtifactId.groovy
    │       └── mappings <4>
    │           └── shouldReturnStuffForArtifactId.json
    └── some-other-artifact-id <5>
        ├── contracts
        │   └── shouldReturnStuffForOtherArtifactId.groovy
        └── mappings
            └── shouldReturnStuffForOtherArtifactId.json

----
<1> group ID of the consumers
<2> consumer with artifact id [some-artifact-id]
<3> contracts for the consumer with artifact id [some-artifact-id]
<4> mappings for the consumer with artifact id [some-artifact-id]
<5> consumer with artifact id [some-other-artifact-id]
====

====
[source,java,indent=0,subs="verbatim",role="primary"]
.Annotation
----
@AutoConfigureStubRunner(
stubsMode = StubRunnerProperties.StubsMode.REMOTE,
		repositoryRoot = "stubs://file://location/to/the/contracts/directory",
		ids = "com.example:some-producer",
		properties="stubs.find-producer=true")
----

[source,java,indent=0,subs="verbatim",role="secondary"]
.JUnit 4 Rule
----
	static Map<String, String> contractProperties() {
		Map<String, String> map = new HashMap<>();
		map.put("stubs.find-producer", "true");
		return map;
	}

@Rule
	public StubRunnerRule rule = new StubRunnerRule()
			.downloadStub("com.example:some-producer")
			.repoRoot("stubs://file://location/to/the/contracts/directory")
			.stubsMode(StubRunnerProperties.StubsMode.REMOTE)
			.properties(contractProperties());
----

[source,java,indent=0,subs="verbatim",role="secondary"]
.JUnit 5 Extension
----
	static Map<String, String> contractProperties() {
		Map<String, String> map = new HashMap<>();
		map.put("stubs.find-producer", "true");
		return map;
	}

@RegisterExtension
	public StubRunnerExtension stubRunnerExtension = new StubRunnerExtension()
			.downloadStub("com.example:some-producer")
			.repoRoot("stubs://file://location/to/the/contracts/directory")
			.stubsMode(StubRunnerProperties.StubsMode.REMOTE)
			.properties(contractProperties());
----
====

