4
4
import io .r2dbc .postgresql .PostgresqlConnectionFactory ;
5
5
import io .r2dbc .spi .ConnectionFactory ;
6
6
7
+ import java .util .function .Supplier ;
8
+
7
9
import javax .sql .DataSource ;
8
10
9
11
import org .postgresql .ds .PGSimpleDataSource ;
10
12
import org .springframework .data .r2dbc .testing .ExternalDatabase .ProvidedDatabase ;
13
+ import org .testcontainers .containers .PostgreSQLContainer ;
11
14
12
15
/**
13
16
* Utility class for testing against Postgres.
14
17
*
15
18
* @author Mark Paluch
19
+ * @author Jens Schauder
16
20
*/
17
21
public class PostgresTestSupport {
18
22
23
+ private static ExternalDatabase testContainerDatabase ;
24
+
19
25
public static String CREATE_TABLE_LEGOSET = "CREATE TABLE legoset (\n " //
20
26
+ " id integer CONSTRAINT id PRIMARY KEY,\n " //
21
27
+ " name varchar(255) NOT NULL,\n " //
@@ -31,30 +37,91 @@ public class PostgresTestSupport {
31
37
public static String INSERT_INTO_LEGOSET = "INSERT INTO legoset (id, name, manual) VALUES($1, $2, $3)" ;
32
38
33
39
/**
34
- * Returns a locally provided database at {@code postgres:@localhost:5432/postgres}.
40
+ * Returns a database either hosted locally at {@code postgres:@localhost:5432/postgres} or running inside Docker .
35
41
*
36
- * @return
42
+ * @return information about the database. Guaranteed to be not {@literal null}.
37
43
*/
38
44
public static ExternalDatabase database () {
39
- return local ();
45
+
46
+ if (Boolean .getBoolean ("spring.data.r2dbc.test.preferLocalDatabase" )) {
47
+
48
+ return getFirstWorkingDatabase ( //
49
+ PostgresTestSupport ::local , //
50
+ PostgresTestSupport ::testContainer //
51
+ );
52
+ } else {
53
+
54
+ return getFirstWorkingDatabase ( //
55
+ PostgresTestSupport ::testContainer , //
56
+ PostgresTestSupport ::local //
57
+ );
58
+ }
59
+ }
60
+
61
+ private static ExternalDatabase getFirstWorkingDatabase (Supplier <ExternalDatabase > first ,
62
+ Supplier <ExternalDatabase > second ) {
63
+
64
+ ExternalDatabase database = first .get ();
65
+ if (database .checkValidity ()) {
66
+ return database ;
67
+ } else {
68
+ return second .get ();
69
+ }
40
70
}
41
71
42
72
/**
43
73
* Returns a locally provided database at {@code postgres:@localhost:5432/postgres}.
44
- *
45
- * @return
46
74
*/
47
75
private static ExternalDatabase local () {
48
- return ProvidedDatabase .builder ().hostname ("localhost" ).port (5432 ).database ("postgres" ).username ("postgres" )
76
+
77
+ return ProvidedDatabase .builder () //
78
+ .hostname ("localhost" ) //
79
+ .port (5432 ) //
80
+ .database ("postgres" ) //
81
+ .username ("postgres" ) //
49
82
.password ("" ).build ();
50
83
}
51
84
85
+ /**
86
+ * Returns a database provided via Testcontainers.
87
+ */
88
+ private static ExternalDatabase testContainer () {
89
+
90
+ if (testContainerDatabase == null ) {
91
+
92
+ try {
93
+ PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer ();
94
+ postgreSQLContainer .start ();
95
+
96
+ testContainerDatabase = ProvidedDatabase .builder () //
97
+ .hostname ("localhost" ) //
98
+ .port (postgreSQLContainer .getFirstMappedPort ()) //
99
+ .database (postgreSQLContainer .getDatabaseName ()) //
100
+ .username (postgreSQLContainer .getUsername ()) //
101
+ .password (postgreSQLContainer .getPassword ()).build ();
102
+
103
+ } catch (IllegalStateException ise ) {
104
+ // docker is not available.
105
+ testContainerDatabase = new ExternalDatabase .NoSuchDatabase ();
106
+ }
107
+
108
+ }
109
+
110
+ return testContainerDatabase ;
111
+ }
112
+
52
113
/**
53
114
* Creates a new {@link ConnectionFactory} configured from the {@link ExternalDatabase}..
54
115
*/
55
116
public static ConnectionFactory createConnectionFactory (ExternalDatabase database ) {
56
- return new PostgresqlConnectionFactory (PostgresqlConnectionConfiguration .builder ().host (database .getHostname ())
57
- .database (database .getDatabase ()).username (database .getUsername ()).password (database .getPassword ()).build ());
117
+
118
+ return new PostgresqlConnectionFactory (PostgresqlConnectionConfiguration .builder () //
119
+ .host (database .getHostname ()) //
120
+ .database (database .getDatabase ()) //
121
+ .port (database .getPort ()) //
122
+ .username (database .getUsername ()) //
123
+ .password (database .getPassword ()) //
124
+ .build ());
58
125
}
59
126
60
127
/**
@@ -72,4 +139,5 @@ public static DataSource createDataSource(ExternalDatabase database) {
72
139
73
140
return dataSource ;
74
141
}
142
+
75
143
}
0 commit comments