app/services/PostrunActionScanner.scala (70 lines of code) (raw):

package services import java.io.File import java.sql.Timestamp import akka.actor.{Actor, ActorSystem} import com.google.inject.{Inject, Singleton} import play.api.{Configuration, Logger} import models.PostrunAction import java.time.{Instant, ZonedDateTime} import org.reflections.Reflections import org.reflections.scanners.{ResourcesScanner, SubTypesScanner} import org.reflections.util.{ClasspathHelper, ConfigurationBuilder, FilterBuilder} import org.slf4j.MDC import play.api.db.slick.DatabaseConfigProvider import postrun.PojoPostrun import slick.jdbc.PostgresProfile import scala.jdk.CollectionConverters._ import collection.mutable._ import scala.concurrent.duration._ import scala.util.{Failure, Success} object PostrunActionScanner { trait PASMsg case object Rescan extends PASMsg } @Singleton class PostrunActionScanner @Inject() (dbConfigProvider: DatabaseConfigProvider, config:Configuration, actorSystem: ActorSystem) extends Actor { private val logger = Logger(this.getClass) import actorSystem.dispatcher implicit val db = dbConfigProvider.get[PostgresProfile].db implicit val configImplicit = config def scanPojos = { logger.info(s"URLs from classpath are ${ClasspathHelper.forPackage("postrun")}") val classLoadersList = ArrayBuffer(ClasspathHelper.contextClassLoader, ClasspathHelper.staticClassLoader) val reflections = new Reflections(new ConfigurationBuilder() .setScanners(new SubTypesScanner(false), new ResourcesScanner()) .setUrls(ClasspathHelper.forPackage("postrun")) ) reflections .getSubTypesOf(classOf[PojoPostrun]) .asScala .foreach(classRef => addIfNotExists(classRef.getCanonicalName, s"java:${classRef.getCanonicalName}")) } protected def addIfNotExists(scriptName:String,absolutePath:String) = { logger.info(s"will add $scriptName at $absolutePath if it does not exist already") PostrunAction.entryForRunnable(absolutePath) map { case Success(results)=> if(results.isEmpty){ logger.info(s"Adding newly found postrun script $absolutePath to database") val newRecord = PostrunAction(None,absolutePath,scriptName,None,"system",1,new Timestamp(ZonedDateTime.now().toEpochSecond*1000)) newRecord.save map { case Failure(error)=> logger.error("Unable to save postrun script to database: ", error) case Success(newPostrunAction)=> logger.info(s"Saved postrun action for $scriptName with id of ${newPostrunAction.id.get}") } } else { logger.debug(s"Script $absolutePath is already present in database") } case Failure(error)=> logger.error("Could not look up script:", error) } } protected def addFileIfNotExists(scriptFile: File) = { addIfNotExists(scriptFile.getName, scriptFile.getName) } override def receive: Receive = { case PostrunActionScanner.Rescan=> logger.info("Rescanning postrun actions") scanPojos } }