Skip to content

Commit fb73ad1

Browse files
authored
Add Solr container implementation under org.testcontainers.solr (#11104)
1 parent 11881bf commit fb73ad1

File tree

4 files changed

+161
-3
lines changed

4 files changed

+161
-3
lines changed

docs/modules/solr.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Note that it's based on the [official Docker image](https://hub.docker.com/_/sol
99
You can start a solr container instance from any Java application by using:
1010

1111
<!--codeinclude-->
12-
[Using a Solr container](../../modules/solr/src/test/java/org/testcontainers/containers/SolrContainerTest.java) inside_block:solrContainerUsage
12+
[Using a Solr container](../../modules/solr/src/test/java/org/testcontainers/solr/SolrContainerTest.java) inside_block:solrContainerUsage
1313
<!--/codeinclude-->
1414

1515
## Adding this module to your project dependencies

modules/solr/src/main/java/org/testcontainers/containers/SolrContainer.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
* <li>Solr: 8983</li>
2424
* <li>Zookeeper: 9983</li>
2525
* </ul>
26+
*
27+
* @deprecated use {@link org.testcontainers.solr.SolrContainer} instead.
2628
*/
2729
public class SolrContainer extends GenericContainer<SolrContainer> {
2830

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
package org.testcontainers.solr;
2+
3+
import com.github.dockerjava.api.command.InspectContainerResponse;
4+
import lombok.SneakyThrows;
5+
import org.apache.commons.lang3.StringUtils;
6+
import org.testcontainers.containers.GenericContainer;
7+
import org.testcontainers.containers.SolrClientUtils;
8+
import org.testcontainers.containers.SolrContainerConfiguration;
9+
import org.testcontainers.containers.wait.strategy.Wait;
10+
import org.testcontainers.utility.ComparableVersion;
11+
import org.testcontainers.utility.DockerImageName;
12+
13+
import java.net.URL;
14+
import java.time.Duration;
15+
import java.util.HashSet;
16+
import java.util.Set;
17+
18+
/**
19+
* Testcontainers implementation for Solr.
20+
* <p>
21+
* Supported image: {@code solr}
22+
* <p>
23+
* Exposed ports:
24+
* <ul>
25+
* <li>Solr: 8983</li>
26+
* <li>Zookeeper: 9983</li>
27+
* </ul>
28+
*/
29+
public class SolrContainer extends GenericContainer<SolrContainer> {
30+
31+
private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("solr");
32+
33+
public static final Integer ZOOKEEPER_PORT = 9983;
34+
35+
public static final Integer SOLR_PORT = 8983;
36+
37+
private SolrContainerConfiguration configuration;
38+
39+
private final ComparableVersion imageVersion;
40+
41+
public SolrContainer(final String dockerImageName) {
42+
this(DockerImageName.parse(dockerImageName));
43+
}
44+
45+
public SolrContainer(final DockerImageName dockerImageName) {
46+
super(dockerImageName);
47+
dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME);
48+
49+
waitingFor(
50+
Wait.forLogMessage(".*o\\.e\\.j\\.s\\.Server Started.*", 1).withStartupTimeout(Duration.ofMinutes(1))
51+
);
52+
this.configuration = new SolrContainerConfiguration();
53+
this.imageVersion = new ComparableVersion(dockerImageName.getVersionPart());
54+
}
55+
56+
public SolrContainer withZookeeper(boolean zookeeper) {
57+
configuration.setZookeeper(zookeeper);
58+
return self();
59+
}
60+
61+
public SolrContainer withCollection(String collection) {
62+
if (StringUtils.isEmpty(collection)) {
63+
throw new IllegalArgumentException("Collection name must not be empty");
64+
}
65+
configuration.setCollectionName(collection);
66+
return self();
67+
}
68+
69+
public SolrContainer withConfiguration(String name, URL solrConfig) {
70+
if (StringUtils.isEmpty(name) || solrConfig == null) {
71+
throw new IllegalArgumentException();
72+
}
73+
configuration.setConfigurationName(name);
74+
configuration.setSolrConfiguration(solrConfig);
75+
return self();
76+
}
77+
78+
public SolrContainer withSchema(URL schema) {
79+
configuration.setSolrSchema(schema);
80+
return self();
81+
}
82+
83+
public int getSolrPort() {
84+
return getMappedPort(SOLR_PORT);
85+
}
86+
87+
public int getZookeeperPort() {
88+
return getMappedPort(ZOOKEEPER_PORT);
89+
}
90+
91+
@Override
92+
@SneakyThrows
93+
protected void configure() {
94+
if (configuration.getSolrSchema() != null && configuration.getSolrConfiguration() == null) {
95+
throw new IllegalStateException("Solr needs to have a configuration if you want to use a schema");
96+
}
97+
// Generate Command Builder
98+
String command = "solr start -f";
99+
// Add Default Ports
100+
addExposedPort(SOLR_PORT);
101+
102+
// Configure Zookeeper
103+
if (configuration.isZookeeper()) {
104+
addExposedPort(ZOOKEEPER_PORT);
105+
if (this.imageVersion.isGreaterThanOrEqualTo("9.7.0")) {
106+
command = "-DzkRun --host localhost";
107+
} else {
108+
command = "-DzkRun -h localhost";
109+
}
110+
}
111+
112+
// Apply generated Command
113+
setCommand(command);
114+
}
115+
116+
@Override
117+
public Set<Integer> getLivenessCheckPortNumbers() {
118+
return new HashSet<>(getSolrPort());
119+
}
120+
121+
@Override
122+
protected void waitUntilContainerStarted() {
123+
getWaitStrategy().waitUntilReady(this);
124+
}
125+
126+
@Override
127+
@SneakyThrows
128+
protected void containerIsStarted(InspectContainerResponse containerInfo) {
129+
if (!configuration.isZookeeper()) {
130+
ExecResult result = execInContainer("solr", "create", "-c", configuration.getCollectionName());
131+
if (result.getExitCode() != 0) {
132+
throw new IllegalStateException(
133+
"Unable to create solr core:\nStdout: " + result.getStdout() + "\nStderr:" + result.getStderr()
134+
);
135+
}
136+
return;
137+
}
138+
139+
if (StringUtils.isNotEmpty(configuration.getConfigurationName())) {
140+
SolrClientUtils.uploadConfiguration(
141+
getHost(),
142+
getSolrPort(),
143+
configuration.getConfigurationName(),
144+
configuration.getSolrConfiguration(),
145+
configuration.getSolrSchema()
146+
);
147+
}
148+
149+
SolrClientUtils.createCollection(
150+
getHost(),
151+
getSolrPort(),
152+
configuration.getCollectionName(),
153+
configuration.getConfigurationName()
154+
);
155+
}
156+
}

modules/solr/src/test/java/org/testcontainers/containers/SolrContainerTest.java renamed to modules/solr/src/test/java/org/testcontainers/solr/SolrContainerTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package org.testcontainers.containers;
1+
package org.testcontainers.solr;
22

33
import org.apache.solr.client.solrj.SolrClient;
44
import org.apache.solr.client.solrj.SolrServerException;
@@ -12,7 +12,7 @@
1212

1313
import static org.assertj.core.api.Assertions.assertThat;
1414

15-
public class SolrContainerTest {
15+
class SolrContainerTest {
1616

1717
private SolrClient client = null;
1818

0 commit comments

Comments
 (0)