1 package de.funfried.maven.plugin.zonky;
2
3 import java.io.IOException;
4 import java.sql.Connection;
5 import java.sql.SQLException;
6 import java.sql.Statement;
7 import java.util.List;
8
9 import javax.sql.DataSource;
10
11 import org.apache.maven.plugin.AbstractMojo;
12 import org.apache.maven.plugin.MojoExecutionException;
13 import org.apache.maven.plugins.annotations.LifecyclePhase;
14 import org.apache.maven.plugins.annotations.Mojo;
15 import org.apache.maven.plugins.annotations.Parameter;
16 import org.apache.maven.project.MavenProject;
17
18 import de.funfried.maven.plugin.zonky.utils.AlreadyStartedPolicy;
19 import de.funfried.maven.plugin.zonky.utils.ZonkyUtil;
20 import io.zonky.test.db.postgres.embedded.EmbeddedPostgres;
21
22
23
24
25 @Mojo(name = "start", defaultPhase = LifecyclePhase.INITIALIZE, requiresProject = true, threadSafe = true)
26 public class StartEmbeddedPostgresMojo extends AbstractMojo {
27
28
29
30 @Parameter(defaultValue = "0", property = "port")
31 private int port;
32
33
34
35
36 @Parameter(defaultValue = "true", property = "createDatabase")
37 private boolean createDatabase;
38
39
40
41
42 @Parameter(defaultValue = "data", property = "databaseName")
43 private String databaseName;
44
45
46
47
48
49
50
51
52
53 @Parameter(defaultValue = "reinit", property = "onAlreadyStarted")
54 private AlreadyStartedPolicy onAlreadyStarted;
55
56
57
58
59 @Parameter(defaultValue = "${project.build.directory}/embedded-postgres/work", property = "workingDirectory")
60 private String workingDirectory;
61
62
63
64
65 @Parameter(defaultValue = "${project.build.directory}/embedded-postgres/data", property = "dataDirectory")
66 private String dataDirectory;
67
68
69
70
71 @Parameter(defaultValue = "${project}", required = true, readonly = true)
72 private MavenProject project;
73
74
75
76
77 @Parameter(defaultValue = "${reactorProjects}", readonly = true, required = true)
78 private List<MavenProject> reactorProjects;
79
80
81
82
83
84
85 @Override
86 public void execute() throws MojoExecutionException {
87 EmbeddedPostgres pg;
88
89 Object obj = project.getProperties().get("zonky");
90 if (obj != null && obj instanceof EmbeddedPostgres) {
91 if (AlreadyStartedPolicy.fail.equals(onAlreadyStarted)) {
92 throw new MojoExecutionException("Embedded database already started.");
93 }
94
95 pg = (EmbeddedPostgres) obj;
96
97 if (AlreadyStartedPolicy.reinit.equals(onAlreadyStarted)) {
98 DataSource dataSource = pg.getDatabase("postgres", "postgres");
99 try (Connection connection = dataSource.getConnection()) {
100 try (Statement stmt = connection.createStatement()) {
101 stmt.execute("DROP DATABASE \"" + databaseName + "\";");
102
103 if (createDatabase) {
104 stmt.execute("CREATE DATABASE \"" + databaseName + "\";");
105 }
106 }
107 } catch (SQLException ex) {
108 throw new MojoExecutionException("Failed to reset embedded database", ex);
109 }
110
111 System.out.println("Embedded postgres database reinitialized");
112 }
113 } else {
114 start(port);
115 }
116 }
117
118 private EmbeddedPostgres start(int port) throws MojoExecutionException {
119 EmbeddedPostgres pg;
120
121 try {
122 pg = ZonkyUtil.start(port, workingDirectory, dataDirectory);
123
124 if (createDatabase) {
125 DataSource dataSource = pg.getDatabase("postgres", "postgres");
126 try (Connection connection = dataSource.getConnection()) {
127 try (Statement stmt = connection.createStatement()) {
128 stmt.execute("DROP DATABASE IF EXISTS \"" + databaseName + "\";");
129 stmt.execute("CREATE DATABASE \"" + databaseName + "\";");
130 }
131 } catch (SQLException ex) {
132 throw new MojoExecutionException("Failed to create embedded database '" + databaseName + "'", ex);
133 }
134 }
135
136 started(pg);
137 } catch (IOException ex) {
138 throw new MojoExecutionException("Failed to start embedded database", ex);
139 }
140
141 return pg;
142 }
143
144 private void started(EmbeddedPostgres pg) {
145 int pgPort = pg.getPort();
146 String jdbcUrl = pg.getJdbcUrl("postgres", databaseName);
147
148 System.out.println("Started embedded postgres database at port " + pgPort + " (JDBC URL: " + jdbcUrl + ")");
149
150 project.getProperties().put("zonky.host", "localhost");
151 project.getProperties().put("zonky.port", pgPort);
152 project.getProperties().put("zonky.database", databaseName);
153 project.getProperties().put("zonky.username", "postgres");
154 project.getProperties().put("zonky.password", "postgres");
155 project.getProperties().put("zonky.jdbcUrl", jdbcUrl);
156 project.getProperties().put("zonky", pg);
157
158 for (MavenProject p : reactorProjects) {
159 p.getProperties().put("zonky.host", "localhost");
160 p.getProperties().put("zonky.port", pgPort);
161 p.getProperties().put("zonky.database", databaseName);
162 p.getProperties().put("zonky.username", "postgres");
163 p.getProperties().put("zonky.password", "postgres");
164 p.getProperties().put("zonky.jdbcUrl", jdbcUrl);
165 p.getProperties().put("zonky", pg);
166 }
167 }
168 }