23
23
24
24
import org .apache .seatunnel .e2e .common .TestResource ;
25
25
import org .apache .seatunnel .e2e .common .TestSuiteBase ;
26
+ import org .apache .seatunnel .e2e .common .container .ContainerExtendedFactory ;
26
27
import org .apache .seatunnel .e2e .common .container .TestContainer ;
28
+ import org .apache .seatunnel .e2e .common .junit .TestContainerExtension ;
27
29
28
30
import org .junit .jupiter .api .AfterAll ;
29
31
import org .junit .jupiter .api .Assertions ;
34
36
import org .mockserver .model .Format ;
35
37
import org .testcontainers .containers .Container ;
36
38
import org .testcontainers .containers .GenericContainer ;
39
+ import org .testcontainers .containers .PostgreSQLContainer ;
37
40
import org .testcontainers .containers .output .Slf4jLogConsumer ;
38
41
import org .testcontainers .containers .wait .strategy .HttpWaitStrategy ;
39
42
import org .testcontainers .lifecycle .Startables ;
45
48
import lombok .EqualsAndHashCode ;
46
49
import lombok .Getter ;
47
50
import lombok .Setter ;
51
+ import lombok .extern .slf4j .Slf4j ;
48
52
49
53
import java .io .File ;
50
54
import java .io .IOException ;
51
55
import java .math .BigDecimal ;
52
56
import java .net .URL ;
57
+ import java .sql .Connection ;
58
+ import java .sql .DriverManager ;
59
+ import java .sql .ResultSet ;
60
+ import java .sql .SQLException ;
61
+ import java .sql .Statement ;
53
62
import java .util .ArrayList ;
54
63
import java .util .List ;
55
64
import java .util .Optional ;
65
+ import java .util .concurrent .CompletableFuture ;
66
+ import java .util .concurrent .TimeUnit ;
56
67
import java .util .stream .Collectors ;
57
68
import java .util .stream .Stream ;
58
69
70
+ import static org .awaitility .Awaitility .await ;
71
+ import static org .awaitility .Awaitility .given ;
59
72
import static org .mockserver .model .HttpRequest .request ;
60
73
74
+ @ Slf4j
61
75
public class HttpIT extends TestSuiteBase implements TestResource {
62
76
63
77
private static final String TMP_DIR = "/tmp" ;
@@ -70,9 +84,31 @@ public class HttpIT extends TestSuiteBase implements TestResource {
70
84
71
85
private MockServerClient mockServerClient ;
72
86
87
+ private static final String POSTGRESQL_SCHEMA = "public" ;
88
+ private static final String SINK_TABLE_1 = "sink" ;
89
+ private static final Integer MAX_COUNT = 15 ;
90
+ private static final String COUNT_QUERY = "select count(*) from sink" ;
91
+
92
+ private static final String PG_IMAGE = "postgres:14-alpine" ;
93
+ private static final String PG_DRIVER_JAR =
94
+ "https://repo1.maven.org/maven2/org/postgresql/postgresql/42.3.3/postgresql-42.3.3.jar" ;
95
+ private PostgreSQLContainer <?> postgreSQLContainer ;
96
+
97
+ @ TestContainerExtension
98
+ private final ContainerExtendedFactory extendedFactory =
99
+ container -> {
100
+ Container .ExecResult extraCommands =
101
+ container .execInContainer (
102
+ "bash" ,
103
+ "-c" ,
104
+ "mkdir -p /tmp/seatunnel/plugins/Jdbc/lib && cd /tmp/seatunnel/plugins/Jdbc/lib && curl -O "
105
+ + PG_DRIVER_JAR );
106
+ Assertions .assertEquals (0 , extraCommands .getExitCode ());
107
+ };
108
+
73
109
@ BeforeAll
74
110
@ Override
75
- public void startUp () {
111
+ public void startUp () throws ClassNotFoundException {
76
112
Optional <URL > resource =
77
113
Optional .ofNullable (HttpIT .class .getResource (getMockServerConfig ()));
78
114
this .mockserverContainer =
@@ -100,6 +136,22 @@ public void startUp() {
100
136
Startables .deepStart (Stream .of (mockserverContainer )).join ();
101
137
mockServerClient = new MockServerClient ("127.0.0.1" , 1080 );
102
138
fillMockRecords ();
139
+
140
+ postgreSQLContainer =
141
+ new PostgreSQLContainer <>(DockerImageName .parse (PG_IMAGE ))
142
+ .withNetwork (TestSuiteBase .NETWORK )
143
+ .withNetworkAliases ("postgresql" )
144
+ .withLogConsumer (
145
+ new Slf4jLogConsumer (DockerLoggerFactory .getLogger (PG_IMAGE )));
146
+ Startables .deepStart (Stream .of (postgreSQLContainer )).join ();
147
+ log .info ("PostgreSQL container started" );
148
+ Class .forName (postgreSQLContainer .getDriverClassName ());
149
+ given ().ignoreExceptions ()
150
+ .await ()
151
+ .atLeast (100 , TimeUnit .MILLISECONDS )
152
+ .pollInterval (500 , TimeUnit .MILLISECONDS )
153
+ .atMost (2 , TimeUnit .MINUTES )
154
+ .untilAsserted (this ::initializeJdbcTable );
103
155
}
104
156
105
157
private static void fillMockRecords () {
@@ -149,6 +201,71 @@ public void tearDown() {
149
201
if (mockServerClient != null ) {
150
202
mockServerClient .close ();
151
203
}
204
+ if (postgreSQLContainer != null ) {
205
+ postgreSQLContainer .stop ();
206
+ }
207
+ }
208
+
209
+ @ TestTemplate
210
+ public void testStreamingSourceToPostgresqlSink (TestContainer container ) {
211
+ try {
212
+ CompletableFuture .supplyAsync (
213
+ () -> {
214
+ try {
215
+ Container .ExecResult execResult1 =
216
+ container .executeJob ("/http_streaming_json_to_postgresql.conf" );
217
+ } catch (Exception e ) {
218
+ log .error ("Commit task exception :" + e .getMessage ());
219
+ throw new RuntimeException (e );
220
+ }
221
+ return null ;
222
+ });
223
+ await ().atMost (60000 , TimeUnit .MILLISECONDS )
224
+ .untilAsserted (
225
+ () -> {
226
+ Long count = queryCount (COUNT_QUERY );
227
+ Assertions .assertTrue (
228
+ count >= MAX_COUNT ,
229
+ "Actual value should be greater than expected value" );
230
+ });
231
+ } finally {
232
+ log .info ("clear schema:{}" , SINK_TABLE_1 );
233
+ clearTable (POSTGRESQL_SCHEMA , SINK_TABLE_1 );
234
+ }
235
+ }
236
+
237
+ private Long queryCount (String sql ) {
238
+ try (Connection connection = getJdbcConnection ()) {
239
+ ResultSet resultSet = connection .createStatement ().executeQuery (sql );
240
+ if (resultSet .next ()) {
241
+
242
+ return resultSet .getLong (1 );
243
+ }
244
+ return 0L ;
245
+ } catch (SQLException e ) {
246
+ throw new RuntimeException (e );
247
+ }
248
+ }
249
+
250
+ private Connection getJdbcConnection () throws SQLException {
251
+ return DriverManager .getConnection (
252
+ postgreSQLContainer .getJdbcUrl (),
253
+ postgreSQLContainer .getUsername (),
254
+ postgreSQLContainer .getPassword ());
255
+ }
256
+
257
+ private void executeSql (String sql ) {
258
+ try (Connection connection = getJdbcConnection ();
259
+ Statement statement = connection .createStatement ()) {
260
+ statement .execute ("SET search_path TO inventory;" );
261
+ statement .execute (sql );
262
+ } catch (SQLException e ) {
263
+ throw new RuntimeException (e );
264
+ }
265
+ }
266
+
267
+ private void clearTable (String database , String tableName ) {
268
+ executeSql ("truncate table " + database + "." + tableName );
152
269
}
153
270
154
271
@ TestTemplate
@@ -259,6 +376,24 @@ public void testMultiTableHttp(TestContainer container)
259
376
Assertions .assertIterableEquals (records , recordResponse );
260
377
}
261
378
379
+ private void initializeJdbcTable () {
380
+ try (Connection connection =
381
+ DriverManager .getConnection (
382
+ postgreSQLContainer .getJdbcUrl (),
383
+ postgreSQLContainer .getUsername (),
384
+ postgreSQLContainer .getPassword ())) {
385
+ Statement statement = connection .createStatement ();
386
+ String sink =
387
+ "create table sink(\n "
388
+ + "c_String varchar(255) NOT NULL PRIMARY KEY,\n "
389
+ + "c_int INT\n "
390
+ + ")" ;
391
+ statement .execute (sink );
392
+ } catch (SQLException e ) {
393
+ throw new RuntimeException ("Initializing PostgreSql table failed!" , e );
394
+ }
395
+ }
396
+
262
397
@ Getter
263
398
@ Setter
264
399
@ EqualsAndHashCode
0 commit comments