1 package net.avcompris.commons3.core.it.utils;
2
3 import static com.google.common.base.Preconditions.checkNotNull;
4 import static net.avcompris.commons3.it.utils.IntegrationTestUtils.getTestProperty;
5
6 import java.io.IOException;
7 import java.sql.Connection;
8 import java.sql.DatabaseMetaData;
9 import java.sql.PreparedStatement;
10 import java.sql.ResultSet;
11 import java.sql.SQLException;
12 import java.util.concurrent.ExecutionException;
13
14 import javax.sql.DataSource;
15
16 import org.springframework.boot.jdbc.DataSourceBuilder;
17
18 import com.google.common.cache.CacheBuilder;
19 import com.google.common.cache.CacheLoader;
20 import com.google.common.cache.LoadingCache;
21 import com.zaxxer.hikari.HikariDataSource;
22
23 import net.avcompris.commons3.dao.DbTable;
24 import net.avcompris.commons3.dao.DbTablesUtils;
25
26 public abstract class RDSTestUtils {
27
28 public static final String DEFAULT_PROPERTY_PREFIX_RDS = "rds";
29
30 private RDSTestUtils() {
31
32 throw new IllegalStateException();
33 }
34
35 private static final CacheLoader<String, DataSource> DATASOURCES_LOADER = new CacheLoader<String, DataSource>() {
36
37 @Override
38 public DataSource load(final String prefix) throws Exception {
39
40 return setUpDataSource(prefix);
41 }
42 };
43
44 private static final LoadingCache<String, DataSource> DATASOURCES = CacheBuilder.newBuilder()
45 .build(DATASOURCES_LOADER);
46
47 private static DataSource setUpDataSource(final String prefix) throws SQLException, IOException {
48
49 final String dbURL = getTestProperty(prefix + ".url");
50 final String dbUsername = getTestProperty(prefix + ".username");
51 final String dbPassword = getTestProperty(prefix + ".password");
52
53 System.out.println(prefix + ".url: " + dbURL);
54 System.out.println(prefix + ".username: " + dbUsername);
55
56 final DataSource dataSource = DataSourceBuilder.create()
57 .type(HikariDataSource.class)
58 .url(dbURL)
59 .username(dbUsername)
60 .password(dbPassword)
61 .build();
62
63 ((HikariDataSource) dataSource).setConnectionInitSql("SET TIME ZONE 'UTC'");
64
65 return dataSource;
66 }
67
68 public static DataSource getDataSource() throws SQLException, IOException {
69
70 return getDataSource(DEFAULT_PROPERTY_PREFIX_RDS);
71 }
72
73 public static DataSource getDataSource(final String prefix) throws SQLException, IOException {
74
75 try {
76
77 return DATASOURCES.get(prefix);
78
79 } catch (final ExecutionException e) {
80
81 final Throwable cause = e.getCause();
82
83 if (cause == null) {
84
85 throw new RuntimeException(e);
86
87 } else if (cause instanceof SQLException) {
88
89 throw (SQLException) cause;
90
91 } else if (cause instanceof IOException) {
92
93 throw (IOException) cause;
94
95 } else if (cause instanceof RuntimeException) {
96
97 throw (RuntimeException) cause;
98
99 } else if (cause instanceof Error) {
100
101 throw (Error) cause;
102
103 } else {
104
105 throw new RuntimeException(e);
106 }
107 }
108 }
109
110
111
112
113
114
115
116 public static String ensureDbTableName(final DbTable dbTable) throws IOException, SQLException {
117
118 return ensureDbTableName(dbTable, DEFAULT_PROPERTY_PREFIX_RDS);
119 }
120
121 private static boolean hasDbTable(final DatabaseMetaData metadata, final String runtimeDbTableName)
122 throws SQLException {
123
124 System.err.println("runtimeDbTableName: " + runtimeDbTableName);
125
126 try (ResultSet rs = metadata.getTables(null, null, runtimeDbTableName, null)) {
127
128 if (rs.next()) {
129
130 return true;
131 }
132 }
133
134 return false;
135 }
136
137 private static boolean isDbTableCompatible(final DatabaseMetaData metadata, final String runtimeDbTableName,
138 final DbTable dbTable) throws SQLException {
139
140 return false;
141 }
142
143 private static String ensureDbTableName(final DbTable dbTable, final String prefix)
144 throws IOException, SQLException {
145
146 checkNotNull(dbTable, "dbTable");
147 checkNotNull(prefix, "prefix");
148
149 final String tableNamePrefix = getTestProperty(prefix + ".tableNamePrefix");
150
151 final String runtimeDbTableName = dbTable.getRuntimeDbTableNameWithPrefix(tableNamePrefix);
152
153 final DataSource dataSource = getDataSource(prefix);
154
155 try (Connection cxn = dataSource.getConnection()) {
156
157 final DatabaseMetaData metadata = cxn.getMetaData();
158
159 final boolean toCreate;
160
161 if (!hasDbTable(metadata, runtimeDbTableName)) {
162
163 toCreate = true;
164
165 } else if (isDbTableCompatible(metadata, runtimeDbTableName, dbTable)) {
166
167 toCreate = false;
168
169 } else {
170
171 for (final String sqlDropCommand : DbTablesUtils.composeSQLDropCommands(tableNamePrefix, dbTable)) {
172
173 System.out.println("Executing DROP command: " + sqlDropCommand);
174
175 try (PreparedStatement pstmt = cxn.prepareStatement(sqlDropCommand)) {
176
177 pstmt.executeUpdate();
178
179 } catch (final SQLException e) {
180
181 System.err.println(e);
182 }
183 }
184
185 toCreate = true;
186 }
187
188 if (toCreate) {
189
190 for (final String sqlCreateCommand : DbTablesUtils.composeSQLCreateCommands(tableNamePrefix, dbTable)) {
191
192 System.out.println("Executing CREATE command: " + sqlCreateCommand);
193
194 try (PreparedStatement pstmt = cxn.prepareStatement(sqlCreateCommand)) {
195
196 pstmt.executeUpdate();
197 }
198 }
199 }
200 }
201
202 return runtimeDbTableName;
203 }
204 }