Skip to content

Instantly share code, notes, and snippets.

@jordanburke
Last active December 13, 2015 18:08
Show Gist options
  • Save jordanburke/4952956 to your computer and use it in GitHub Desktop.
Save jordanburke/4952956 to your computer and use it in GitHub Desktop.
Simple Scala FlywayServlet
class FlywayServlet extends javax.servlet.http.HttpServlet {
private val logger: Logger = LoggerFactory.getLogger(classOf[FlywayServlet])
//declaring globally so we can potentially make this an Schema Admin Servlet which can
//repair, destroy, migrate the schema
private val flyway: Flyway = {
//unclear if DriverDataSource is an internal class
//flyway example on google code uses it so I decided to as well
//avoids having to explicitly create properties object and put
//values for flyway properties
//the second parameter to GlobalProperties is a default value, avoiding hardcoding of user and pwd
val ds: DataSource = new DriverDataSource(
GlobalProperties.get("datasource.pg.databaseDriver", "org.postgresql.Driver"),
GlobalProperties.get("datasource.pg.databaseUrl", "jdbc:postgresql://localhost/apps"),
GlobalProperties.get("datasource.pg.username", ""),
GlobalProperties.get("datasource.pg.password", ""),
"select 1"
)
val flyway: Flyway = new Flyway()
flyway.setDataSource(ds)
//setting this to true - flyway recommends not to so that if you accidentally apply it to the wrong schema
//the schema will be untouched. But without it you have to manually run init
//we can take this out in the future - once it has been applied
// we will set this to false once init has been run once
// shouldnt harm anything if it gets run multiple times but lets avoid it
flyway.setInitOnMigrate(true)
flyway
}
override def init() {
migrate()
}
override def doGet(request: HttpServletRequest, response: HttpServletResponse) {
response.setContentType("text/html")
val resp = invokeAction(request.getParameter("action"))
response.getOutputStream.print(resp)
}
def invokeAction(action: String): String = action match {
//doing nothing on migrate because init is always called
case "migrate" => ""
case "version" => version
case _ => "Unknown action"
}
/**
* call migrate and then switch of default initialization
* @return
*/
def migrate(): String = {
val cnt = flyway.migrate
// we will set this to false once init has been run once
// shouldn't harm anything if it gets run multiple times but lets avoid it
flyway.setInitOnMigrate(false)
val resp: String = "Migrations applied: " + cnt
logger.info(resp)
resp
}
/**
*
* Should ideally create an xhtml page that fills out this information
* @return html response string
*/
def version(): String = {
val sb: StringBuilder = new StringBuilder
sb.append("<table style='border: 1px solid black;'>")
sb.append("<tr style='border: 1px solid black;'>")
sb.append("<td style='border: 1px solid black;'><b>DESCRIPTION </td>")
sb.append("<td style='border: 1px solid black;'><b>VERSION</td>")
sb.append("<td style='border: 1px solid black;'><b>SCRIPT</td>")
sb.append("<td style='border: 1px solid black;'><b>STATE</td>")
sb.append("<td style='border: 1px solid black;'><b>TYPE</td>")
sb.append("<td style='border: 1px solid black;'><b>INSTALLED ON</td>")
for (arg <- flyway.info.all) {
sb.append("<tr style='border: 1px solid black;'>")
sb.append("<td style='border: 1px solid black;'>" + arg.getDescription + "</td>")
sb.append("<td style='border: 1px solid black;'>" + arg.getVersion + "</td>")
sb.append("<td style='border: 1px solid black;'>" + arg.getScript + "</td>")
sb.append("<td style='border: 1px solid black;'>" + arg.getState + "</td>")
sb.append("<td style='border: 1px solid black;'>" + arg.getType + "</td>")
sb.append("<td style='border: 1px solid black;'>" + arg.getInstalledOn + "</td>")
sb.append("</tr>")
}
sb.append("</table>")
sb.toString()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment