Skip to content

Commit e450586

Browse files
authored
Enable Neo4j labs plugin definition. (#5035)
1 parent eea61bd commit e450586

File tree

4 files changed

+135
-2
lines changed

4 files changed

+135
-2
lines changed

docs/modules/databases/neo4j.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,21 @@ Whole directories work as well:
5252
[Plugin folder](../../../modules/neo4j/src/test/java/org/testcontainers/containers/Neo4jContainerTest.java) inside_block:registerPluginsPath
5353
<!--/codeinclude-->
5454

55+
### Add Neo4j Docker Labs plugins
56+
57+
Add any Neo4j Labs plugin from the [Neo4j Docker Labs plugin list](https://neo4j.com/docs/operations-manual/4.4/docker/operations/#docker-neo4jlabs-plugins).
58+
59+
!!! note
60+
At the moment only the plugins available from the list Neo4j Docker 4.4 are supported by type.
61+
If you want to register another supported Neo4j Labs plugin, you have to add it manually
62+
by using the method `withLabsPlugins(String... neo4jLabsPlugins)`.
63+
Please refer to the list of [supported Docker image plugins](https://neo4j.com/docs/operations-manual/current/docker/operations/#docker-neo4jlabs-plugins).
64+
65+
<!--codeinclude-->
66+
[Configure Neo4j Labs Plugins](../../../modules/neo4j/src/test/java/org/testcontainers/containers/Neo4jContainerTest.java) inside_block:configureLabsPlugins
67+
<!--/codeinclude-->
68+
69+
5570
### Start the container with a predefined database
5671

5772
If you have an existing database (`graph.db`) you want to work with, copy it over to the container like this:
@@ -61,7 +76,7 @@ If you have an existing database (`graph.db`) you want to work with, copy it ove
6176
<!--/codeinclude-->
6277

6378
!!! note
64-
The `withDatabase` method will only work with Neo4j 3.5 and throw an exception if used in combination with a newer version.
79+
The `withDatabase` method will only work with Neo4j 3.5 and throw an exception if used in combination with a newer version.
6580

6681
## Choose your Neo4j license
6782

modules/neo4j/src/main/java/org/testcontainers/containers/Neo4jContainer.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44
import static java.util.stream.Collectors.toSet;
55

66
import java.time.Duration;
7+
import java.util.Arrays;
8+
import java.util.HashSet;
9+
import java.util.List;
710
import java.util.Set;
11+
import java.util.stream.Collectors;
812
import java.util.stream.Stream;
913
import org.testcontainers.containers.wait.strategy.HttpWaitStrategy;
1014
import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy;
@@ -60,6 +64,8 @@ public class Neo4jContainer<S extends Neo4jContainer<S>> extends GenericContaine
6064

6165
private String adminPassword = DEFAULT_ADMIN_PASSWORD;
6266

67+
private final Set<String> labsPlugins = new HashSet<>();
68+
6369
/**
6470
* Creates a Neo4jContainer using the official Neo4j docker image.
6571
* @deprecated use {@link Neo4jContainer(DockerImageName)} instead
@@ -119,6 +125,15 @@ protected void configure() {
119125
boolean emptyAdminPassword = this.adminPassword == null || this.adminPassword.isEmpty();
120126
String neo4jAuth = emptyAdminPassword ? "none" : String.format(AUTH_FORMAT, this.adminPassword);
121127
addEnv("NEO4J_AUTH", neo4jAuth);
128+
129+
if (!this.labsPlugins.isEmpty()) {
130+
String enabledPlugins = this.labsPlugins.stream()
131+
.map(pluginName -> "\"" + pluginName + "\"")
132+
.collect(Collectors.joining(","));
133+
134+
addEnv("NEO4JLABS_PLUGINS", "[" + enabledPlugins + "]");
135+
}
136+
122137
}
123138

124139
/**
@@ -251,6 +266,32 @@ public String getAdminPassword() {
251266
return adminPassword;
252267
}
253268

269+
/**
270+
* Registers one or more {@link Neo4jLabsPlugin} for download and server startup.
271+
272+
* @param neo4jLabsPlugins The Neo4j plugins that should get started with the server.
273+
* @return This container.
274+
*/
275+
public S withLabsPlugins(Neo4jLabsPlugin... neo4jLabsPlugins) {
276+
List<String> pluginNames = Arrays.stream(neo4jLabsPlugins)
277+
.map(plugin -> plugin.pluginName)
278+
.collect(Collectors.toList());
279+
280+
this.labsPlugins.addAll(pluginNames);
281+
return self();
282+
}
283+
284+
/**
285+
* Registers one or more {@link Neo4jLabsPlugin} for download and server startup.
286+
287+
* @param neo4jLabsPlugins The Neo4j plugins that should get started with the server.
288+
* @return This container.
289+
*/
290+
public S withLabsPlugins(String... neo4jLabsPlugins) {
291+
this.labsPlugins.addAll(Arrays.asList(neo4jLabsPlugins));
292+
return self();
293+
}
294+
254295
private static String formatConfigurationKey(String plainConfigKey) {
255296
final String prefix = "NEO4J_";
256297

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package org.testcontainers.containers;
2+
3+
/**
4+
* Reflects a plugin from the official Neo4j 4.4.
5+
* <a href="https://neo4j.com/docs/operations-manual/4.4/docker/operations/#docker-neo4jlabs-plugins">Neo4j Labs Plugin list</a>.
6+
* There might be plugins not supported by your selected version of Neo4j.
7+
*/
8+
public enum Neo4jLabsPlugin {
9+
APOC("apoc"),
10+
APOC_CORE("apoc-core"),
11+
BLOOM("bloom"),
12+
STREAMS("streams"),
13+
GRAPH_DATA_SCIENCE("graph-data-science"),
14+
NEO_SEMANTICS("n10s");
15+
16+
final String pluginName;
17+
18+
Neo4jLabsPlugin(String pluginName) {
19+
this.pluginName = pluginName;
20+
}
21+
}

modules/neo4j/src/test/java/org/testcontainers/containers/Neo4jContainerTest.java

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import org.neo4j.driver.Record;
1010
import org.neo4j.driver.Result;
1111
import org.neo4j.driver.Session;
12-
import org.testcontainers.utility.DockerImageName;
1312
import org.testcontainers.utility.MountableFile;
1413

1514
import java.util.Collections;
@@ -183,6 +182,63 @@ public void shouldAddConfigToEnvironment() {
183182
.containsEntry("NEO4J_dbms_tx__log_rotation_size", "42M");
184183
}
185184

185+
@Test
186+
public void shouldConfigureSingleLabsPlugin() {
187+
try (Neo4jContainer<?> neo4jContainer = new Neo4jContainer<>("neo4j:4.4")
188+
.withLabsPlugins(Neo4jLabsPlugin.APOC)) {
189+
190+
191+
// needs to get called explicitly for setup
192+
neo4jContainer.configure();
193+
194+
assertThat(neo4jContainer.getEnvMap())
195+
.containsEntry("NEO4JLABS_PLUGINS", "[\"apoc\"]");
196+
}
197+
}
198+
199+
@Test
200+
public void shouldConfigureMultipleLabsPlugins() {
201+
try(
202+
// configureLabsPlugins {
203+
Neo4jContainer<?> neo4jContainer = new Neo4jContainer<>("neo4j:4.4")
204+
.withLabsPlugins(Neo4jLabsPlugin.APOC, Neo4jLabsPlugin.BLOOM);
205+
// }
206+
) {
207+
// needs to get called explicitly for setup
208+
neo4jContainer.configure();
209+
210+
assertThat(neo4jContainer.getEnvMap().get("NEO4JLABS_PLUGINS"))
211+
.containsAnyOf("[\"apoc\",\"bloom\"]", "[\"bloom\",\"apoc\"]");
212+
}
213+
}
214+
215+
@Test
216+
public void shouldConfigureSingleLabsPluginWithString() {
217+
try (Neo4jContainer<?> neo4jContainer = new Neo4jContainer<>("neo4j:4.4")
218+
.withLabsPlugins("myApoc")) {
219+
220+
// needs to get called explicitly for setup
221+
neo4jContainer.configure();
222+
223+
assertThat(neo4jContainer.getEnvMap())
224+
.containsEntry("NEO4JLABS_PLUGINS", "[\"myApoc\"]");
225+
}
226+
}
227+
228+
@Test
229+
public void shouldConfigureMultipleLabsPluginsWithString() {
230+
231+
try (Neo4jContainer<?> neo4jContainer = new Neo4jContainer<>("neo4j:4.4")
232+
.withLabsPlugins("myApoc", "myBloom")) {
233+
234+
// needs to get called explicitly for setup
235+
neo4jContainer.configure();
236+
237+
assertThat(neo4jContainer.getEnvMap().get("NEO4JLABS_PLUGINS"))
238+
.containsAnyOf("[\"myApoc\",\"myBloom\"]", "[\"myBloom\",\"myApoc\"]");
239+
}
240+
}
241+
186242
private static Driver getDriver(Neo4jContainer<?> container) {
187243

188244
AuthToken authToken = AuthTokens.none();

0 commit comments

Comments
 (0)