diff options
Diffstat (limited to 'build.gradle')
-rw-r--r-- | build.gradle | 1436 |
1 files changed, 1436 insertions, 0 deletions
diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000000..b80295eff8 --- /dev/null +++ b/build.gradle @@ -0,0 +1,1436 @@ +import java.awt.Color +import java.util.concurrent.Callable +import java.util.concurrent.Executors +import java.util.concurrent.atomic.AtomicBoolean + +import static Services.* +import static ServiceControl.* +import java.awt.AWTException +import java.awt.Font +import java.awt.Image +import java.awt.Menu +import java.awt.MenuItem +import java.awt.PopupMenu +import java.awt.SystemTray +import java.awt.TrayIcon +import java.awt.event.ActionEvent +import java.awt.event.ActionListener +import javax.swing.JOptionPane +import javax.imageio.ImageIO + + +group 'com.att.ecomp' +version '1.01-SNAPSHOT' + +apply plugin: 'groovy' +apply plugin: 'java' +apply plugin: "org.hidetake.ssh" +apply plugin: 'java-gradle-plugin' +apply plugin: 'idea' + +sourceCompatibility = 1.8 + +buildscript { + repositories { + jcenter() + mavenCentral() + } + dependencies { + classpath 'org.codehaus.groovy:groovy-all:2.4.12' + classpath "org.hidetake:gradle-ssh-plugin:2.9.0" + } +} + +enum Services { + BACKEND , //be + FRONTEND , //fe + DB , //cassandra + CACHING , //elawsrticsearch + SECURITY , //webseal + ALL //all services +} +enum ServiceControl { + HEALTH , + START , + RESTART , + STOP , + KILL +} +//env variables +//fill YOUR_WINDOWS_USER_HOME +project.ext.set("NEW_VAG",Boolean.FALSE) //flags to use new vagrant configuration +project.ext.set("IS_HOTSWAP",Boolean.FALSE) //flags to use new vagrant configuration +project.ext.set("PROJECT_PATH", System.getenv("SDC")) //ex. 'C:\\GIT_WORK\\asdc\\sdc') +project.ext.set("VAGRANT_HOME", NEW_VAG ? System.getenv("NEW_VAG") : System.getenv("VAG")) //ex. 'C:\\GIT_WORK\\vagrant-asdc-all-in-one') +project.ext.set("USER_HOME", "${System.getenv("USERPROFILE")}\\.ssh") +project.ext.set("BE_REMOTE", NEW_VAG ? '/opt/app/jetty/base/be' : '/home/vagrant/catalog-be' ) +project.ext.set("FE_REMOTE", NEW_VAG ? '/opt/app/jetty/base/fe' : '/home/vagrant/catalog-fe' ) +project.ext.set("VAGRANT_USER", NEW_VAG ? 'm11981' : 'vagrant' ) +project.ext.set("RSA_PRIVATE_KEY_PATH", NEW_VAG ? "$VAGRANT_HOME/id_rsa" : '' ) +project.ext.set("VAGRANT_PASSWORD", NEW_VAG ? 'Aa123456' : 'vagrant' ) +project.ext.set("X_FOLDER",'/xFolder' ) +project.ext.set("BE_DEPENDENCIES", 'common-be,common-app-api,catalog-dao,catalog-model,security-utils' ) +project.ext.set("command", [ (ALL) : [ (HEALTH) : { NEW_VAG ? 'sudo curl -i http://localhost:8181/sdc1/rest/healthCheck' : 'curl -i localhost:8080/sdc2/rest/healthCheck' } , + (KILL) : { NEW_VAG ? 'sudo pkill java' : 'pkill java'} ] , // TODO: refine kill only for services + (BACKEND) : [ (START) : { NEW_VAG ? 'sudo service jettyBE start' : 'service catalog-be start'} , + (STOP) : { NEW_VAG ? 'sudo service jettyBE stop' : 'service catalog-be stop'} , + (RESTART) : { NEW_VAG ? 'sudo service jettyBE restart' : 'service catalog-be restart'}] , + (DB) : [ (START) : { NEW_VAG ? 'sudo service cassandra start' : 'start-asdc-storage.sh' } , + (STOP) : { NEW_VAG ? 'sudo service cassandra stop' : 'service cassandra stop'} , + (RESTART) : { NEW_VAG ? 'sudo service cassandra restart' : 'service cassandra restart'} ] , + (FRONTEND): [ (START) : { NEW_VAG ? 'sudo service jettyFE start' : 'service catalog-fe start' } , + (STOP) : { NEW_VAG ? 'sudo service jettyFE stop' : 'service catalog-fe stop'} , + (RESTART) : { NEW_VAG ? 'sudo service jettyFE restart' : 'service catalog-fe restart' } ] , + (CACHING): [ (START) : { NEW_VAG ? 'sudo service elasticsearch start' : 'echo "starting es is not yet supported"' } ], + (SECURITY): [ (START) : { NEW_VAG ? 'sudo docker start sdc-WebSeal-Simulator' : 'service webseal-simulator start' } , + (STOP) : { NEW_VAG ? 'sudo docker stop sdc-WebSeal-Simulator' : 'service webseal-simulator stop'} , + (RESTART) : { NEW_VAG ? 'sudo docker restart sdc-WebSeal-Simulator' : 'service webseal-simulator restart'}] + ] ) //abstraction level to shell scripts , support old and new vagrant bash commands + +//icons +project.ext.set("warnImg",'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAADvSURBVDhPY2RgYPgPxGQDiAGLXkB4UMD56DuD9YFUhj179oD5Li4uDEcdZjN8l+ME8+EgTgLTAJDm7zWKYPb/enUwzdh4E0xzttxHNQRoABOUCQYYmj+9QrCBACQHUoMM4AYga74ZDiRAmvnEwHwQGywGBOiGgA1A16wmJYjQDAJANkgMmyEosYBVMzIAuuTWs/cM6iuhfCCAGwDWrAHxKyFw68ZNuCE40wGygcga0AEkEEHRiIxxASzqUKKRHIAwAJgo4BgXwKIGxQUgf8MwOsAlh+EFUMDBMAxgE0MGoLwAignSMFQPzmgkDjAwAACSmn13nChk1QAAAABJRU5ErkJggg==') +project.ext.set("okImg1",'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAD4SURBVDhPY2RgYPgPxGQDiAGLXkB4UMD56DuD9YFUhj179oD5Li4uDEcdZjN8l+ME8+EgTgLTAJDm7zWKYLbSRh8wfc9/C5jmbLmPagjQACYoEwwwNLMxgzHMIJAcSA0ygBuArFm81gyi+ddfCAaywWJAgG4I2AB0zdxWkhCNMABkg8SwGYISC1g1IwOgS74ee87wsvkUVADJAJjpyIDbRAxMfz3zCkwjA5ghONMB2DVIBiDbigwggQiKRmSMC2BRhxKN5ACEAcBEAce4ABY1LFAaDLAFJAwgyyGHB4YXQAEHwzCATQwZgPICKCZIw1A9OKOROMDAAAA4gXvZorg7ZgAAAABJRU5ErkJggg==') +project.ext.set("okImg2" , 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAADjSURBVDhPY2RgYPgPxGQDiAGLXkB4UMD56DuD9YFUhj179oD5Li4uDEcdZjN8l+ME8+EgTgLTAJDm7zWKYPbWZ7Jg2lvqMZjmbLmPagjQACYoEwywaQYBGBskB1KDDOAGIGuetFsUTCMDmBi6IWAD0DUra3OA2cgAJIbNEJRYwKUZGdy9+oMhz/U1lIdkADZnwwwDaUIHMENwpgNk16DbigwggQiKRmSMC2BRhxKN5ACEAcBEAce4ABY1LFAaDLAFJAwgyyGHB4YXQAEHwzCATQwZgPICKCZIw1A9OKOROMDAAAAZD3X55epfOAAAAABJRU5ErkJggg==') +project.ext.set("errorImg" , 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAADlSURBVDhPY2RgYPgPxGQDiAGLXkB4UMD56DuD9YFUhj179oD5Li4uDEcdZjN8l+ME8+EgTgLTAJDm7zWKYPZbGRUwLfzkDpjmbLmPagjQACYoEwywaQYBGBskB1KDDOAGIGtexisCppEBTAzdELAB6Jrd+QXAbGQAEsNmCEos4NKMDHZ+/MAQ9fkNlIdkADZnwwwDaUIHyIaADMDAQAP/AwMPjEFsbGpAGGs6AEUPsnfgzsaiDiUayQUgF2A4jaAXoHpQXAByNgyjA1xyGF4A+RuGYQCbGDLA6gWCGKoHJSGRDhgYAL/hkunRq+joAAAAAElFTkSuQmCC') +project.ext.set("unavailableImg" , 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABJ0AAASdAHeZh94AAAAB3RJTUUH4QwNDgEDrNoaqgAAAOhJREFUOMulkz8OgjAUhz8MQ7mBkwnnkBAH4mbCCdxcXLwAoxdwYXHjBCRupoMheg4TJ29QNhwshMofSfpLOry2v6/vta8OUGEhF4DsbUx6L8XytkNKCUAURTxWZ9TCM93buQb8mFXiI4E43gCQ5xeQPt7x2YG4fWa0OQwDhBANRCVdyGyKOQyDJhuV+HgvZQLGzABCiEGI036FPnNbZVlSFPfvnWg1gJpea72OjPh6lUZcQ5yhPkjTkxHv94fpfcB23t81PftmWMr9e+pQZjobd6zuobX2fViXAFCRvSv9GtOH9ji23/kDswRrCVqtQOAAAAAASUVORK5CYII=') + + +//health params +project.ext.set("trayIcon", null) +project.ext.set("lastStatus", null) +project.ext.set("isStopHealthCheck", false) +project.ext.set("isHaltHealth", new AtomicBoolean(false) ) +project.ext.set("startedAwait", Long.MAX_VALUE) +project.ext.set("logFile", 'C:/ProgramData/all.log') +project.ext.set("pomList" , ["${System?.getenv('SDC')}/catalog-fe/pom.xml" ,"${System?.getenv('SDC')}/catalog-be/pom.xml" ] ) //empty list will scan all openecomp poms +project.ext.set("pomChangesMap" , [:] ) +project.ext.set("beConfigFilesToCopyMapping" , [ 'src/main/resources/config/*.yaml' : 'config/catalog-be/' , + 'src/main/resources/config/*.properties' : 'config/catalog-be/'] ) + +//menu item strings +project.ext.set("toggleHealthString" , "Halt Health" ) +//menu item +project.ext.set("toggleHealthItemView" , null ) + +//other +project.ext.set("IS_MVN_INSTALL",false) +project.ext.set("executor" , null ) +project.ext.set("lockObj" , new Object() ) +/*compile?.doLast { + println "2. hello compile2" +}*/ + +/*def post(String host , String serviceName,String msg){ + // POST + def post = new URL("$host/$serviceName").openConnection(); + def message = '{"message":"this is a message"}' + post.setRequestMethod("POST") + post.setDoOutput(true) + post.setRequestProperty("Content-Type", "application/json") + post.getOutputStream().write(message.getBytes("UTF-8")); + def postRC = post.getResponseCode(); + println(postRC); + if( postRC.equals(200)) { + println(post.getInputStream().getText()); + } +} + +def postStat( long operationTime, String user , String meta ){ + def host = 'http://135.76.123.70:8888' + def params = "user=$user&meta=$meta" + post host , "UserStats" , params +}*/ + + +def hash( List list ){ + def map = list?.collectEntries { File file -> [(file?.absolutePath) : file?.text?.hashCode() ]} + + map +} + +def pomChanges(){ + long started = System.currentTimeMillis() + if ( !pomList ) + listPom() + //find hash changes + def changes = pomList?.findAll { + def File file = new File(it); + pomChangesMap[it] != file?.text?.hashCode() + } + println "\n\n[MasterD][POM]--> detected changes for -> $changes" + //update changes in map + changes?.each { pomChangesMap[it] = new File(it)?.text?.hashCode() } + println "\n\n[MasterD][POM]--> pom map -> $pomChangesMap" + + println """ + ****** POM changes detection finished after -> ${System.currentTimeMillis()- started}ms ****** + """ + + changes +} +//list pom with updated file hashes +def listPom(){ + long started = System.currentTimeMillis() + if (!pomList) { + def tree = fileTree( PROJECT_PATH ).include '**/pom.xml'//.filter { it.isFile() && it?.toString()?.toLowerCase()?.endsWith('pom.xml') } + //println "$PROJECT_PATH list is ->${ list?.collect { it?.absolutePath } }" + //flatten and filter openecomp poms + pomList = tree?.flatten()?.findAll { File file -> file?.text?.contains('org.openecomp.sdc') }?.collect {File file -> file?.absolutePath } + } + pomChangesMap = pomList.collectEntries { absolutePath ->[ ( absolutePath ) : new File(absolutePath)?.text?.hashCode() ] } + + println """ [MasterD][Init] intializing POM detector + + ********* POM listing finished after -> ${System.currentTimeMillis()- started}ms ********* + """ + return pomList +} + + +task initialization(){ + listPom() + executor = Executors.newCachedThreadPool(); +} + +def parallel( closure ){ + executor?.submit(new Callable<Object>(){ + @Override + public Object call() { + closure(); + return null; + } + }) +} +/*class Preferences { + def String Username + def String IsNewVagrant + def String IsRapidMode +} + +def initXFolder(){ + def folder = new File(X_FOLDER); + folder?.exists() ?: folder?.mkdirs() + + new File("${folder?.absolutePath}/$PREFERENCES_FILENAME") +}*/ + +task tester{ + /*doLast{ + //postStat(10000, "shay" , "report/index") + listPom() + new File('catalog-be\\pom.xml') << "#hello" + pomChanges() + }*/ +} + + +def fetchFilesByExtention(remote, local , ext ){ + ssh.run { + def started = System.currentTimeMillis() + println "folder diff" + session(remotes.vagrant) { + //execute "cd /home/vagrant/catalog-be/tmp ; ls -lt | grep catalog-be" //todo- use my dates to filter + get from: remote , into: local , filter: { it?.absolutePath =~ /jetty.*catalog-be.*\.dir.*\.$ext/ } // { it?.absolutePath =~ /.*catalog-be.*dir.*classes.*/ } + } + println "fetched files in ${System.currentTimeMillis() - started} ms" + } +} + +def updateRemoteFile(String remote , String local){ + ssh.run { + def to = "$BE_REMOTE${remote[remote?.indexOf("tmp\\")..remote.size()-1].replaceAll("\\\\","/")}" + println "copying $local \nto\n $to" + session(remotes.vagrant) { + put from: local , into: to } + } +} + +def compareAndSwap(){ + def final LIMIT = 10 + def newClasses = new File("$PROJECT_PATH\\catalog-be\\target\\classes") + def File jettyClasses ; + //locate classes + println "traversing.." + new File("build/hotswap").traverse { if (it?.directory && it?.name?.equals("classes")){ + jettyClasses = it + return; + } } + def jettyClassesList = [] + jettyClasses?.traverse { jettyClassesList << it } + + println "$jettyClasses" + //Sort compiled classes + def files = [] + newClasses?.traverse { files << it } + def result = files.sort{ a,b -> b.lastModified() <=> a.lastModified() } + println "show only last $LIMIT changes" + result[0..LIMIT]?.each{ println it?.lastModified() +" | "+ it?.name + (it?.directory ? "[Directory]" : "") } //show only last 10 changes + + //update + def changesMap = [ : ] //<old,new> + println "updating changes" + result[0..LIMIT]?.each { File f -> def File other = jettyClassesList.find{ File other-> other?.absolutePath?.endsWith(f?.name) }; + if ( !(f.directory) && f?.text?.hashCode() != other?.text?.hashCode() ) + updateRemoteFile( other?.getAbsolutePath() , f?.getAbsolutePath() ) + } //use hashing +} + +task hotswap(){ + doLast { + new File("build/hotswap")?.deleteDir() + new File("build/hotswap")?.mkdirs() + ssh.settings { + knownHosts = allowAnyHosts + } + fetchFilesByExtention( "$BE_REMOTE/tmp/" , 'build/hotswap' , "class") + compareAndSwap() + } +} + +remotes { + vagrant { + host = '127.0.0.1' + port = 2222 + user = VAGRANT_USER + password = VAGRANT_PASSWORD + identity = NEW_VAG ? new File(RSA_PRIVATE_KEY_PATH) : null + } + +} + +def gitLatest(){ + +} + +def newEcoSystem(){ + //cleanTitan() + backupDB() //and clean all + //restoreDB() //restore latest + createSchema() + fillSchema() + postCreate() + startAll() + //todo- conside updating from git + updaterBEFull() + updaterFE() +} +def importHeatTypes(){ + //todo- impl +} +def postCreate(){ + importNormative() + importHeatTypes() +} +def fillSchema(){ + // add conformence level +} +def createSchemaPreStep(){ + //todo- DB up +} +def createSchemaPostStep(){ + ////todo- impl create amdocs dox +} +def createSchema(){ + createSchemaPreStep() + //todo- create schema + //todo- create titan + createSchemaPostStep() +} + +def cleanTitan(){ + execSafe{ + ssh.settings { + knownHosts = allowAnyHosts + } + ssh.run { + session(remotes.vagrant) { + execute "cqlsh -e 'DROP KEYSPACE titan;'" + println "[MasterD][DB_DROP]-> Dropped 'titan' KEYSPACE." + } + } + } +} +task cleanTitan { + doLast{ + cleanTitan() + } +} + +task fetchE2EDB(){ + doLast{ + fetchE2EDB() + } +} +def fetchE2EDB(){ + execSafe{ + ssh.settings { + knownHosts = allowAnyHosts + } + ssh.run { + session(remotes.vagrant) { + def tmp = '$CASSANDRA_HOME/backup/e2e' + //execute 'mkdir $CASSANDRA_HOME/backup/e2e/' + //execute 'wget http://135.76.210.202:8080/ETE_backup_files/latest_ETE_backup_file.zip -P /vagrant/db' + println "[MasterD] download finished, unzipping.." + execute "unzip -u $tmp/latest_ETE_backup_file.zip" //execute 'unzip -u /vagrant/db/latest_ETE_backup_file.zip'//' + def folder = execute "cd $tmp; ls -d -- */" + println "[MasterD] unzipping finished into -> $folder , untaring.." + execute "tar zxf $tmp/$folder/* --strip 3 -C" +'$CASSANDRA_HOME/data | pv -l >/dev/null' + println "[MasterD][E2E_DB]-> Downloaded & unzipped e2e data successfully." + } + } + } +} +def copyExplodedBE() { + execSafe{ + println "[MasterD][BackEnd] copying exploded war." + ssh.settings { + knownHosts = allowAnyHosts + } + long started = System.currentTimeMillis() + def dirPath = "${PROJECT_PATH}/catalog-be/target/catalog-be-1.1.0-SNAPSHOT" + def dir = new File(dirPath); + println "[MasterD][BackEnd] copying ${dir?.directorySize()/(1024*1024)} MB, from ${dir?.name} to $BE_REMOTE/webapps" + ssh.run { + session(remotes.vagrant) { + execute "rm -R $BE_REMOTE/webapps/catalog-be-1.1.0-SNAPSHOT" + put from: dir?.absolutePath , into: "$BE_REMOTE/webapps" + } + } + println "[MasterD][BackEnd] Successfully copied exploded war in ${System.currentTimeMillis()-started}ms." + } +} +task copyExplodedBE(){ + doLast{ + copyExplodedBE() + } +} +def backupDB() { + execSafe{ + ssh.settings { + knownHosts = allowAnyHosts + } + ssh.run { + session(remotes.vagrant) { + execute 'mkdir -p $CASSANDRA_HOME/backup' + def res = execute 'mv $CASSANDRA_HOME/data $CASSANDRA_HOME/backup/data_$(date +\'%Y_%m_%d__%H:%M:%S\')' + println "[MasterD][DB_BACKUP]-> snapshot DB finished. $res" + } + } + } +} +task backupDB{ + doLast{ + backupDB() + } +} + +def restoreDB(){ + execSafe{ + ssh.settings { + knownHosts = allowAnyHosts + } + ssh.run { + session(remotes.vagrant) { + println "[MasterD]-> restoring DB" + execute 'mkdir -p $CASSANDRA_HOME/data' + def res = execute 'mv $CASSANDRA_HOME/backup/data_*/* $CASSANDRA_HOME/data' + println "[MasterD]-> DB restore FINISHED!! $res" + } + } + } +} +task restoreDB() { + doLast { + restoreDB() + } +} + +def vm( ){ + exec{ + if (VAGRANT_HOME){ + workingDir VAGRANT_HOME //vagrant path + println "*****************\nworking dir -> $VAGRANT_HOME" + commandLine "cmd","/c", "vagrant up" + //args = [ ] + } else { + println "[MasterD]--> please define windows enviroment variable VAG pointing to vagrant project" + } + } +} + +task vm{ + doLast{ + vm() + } +} + +def copyFE() { + println "[MasterD][FrontEnd] starting war copy." + ssh.settings { + knownHosts = allowAnyHosts + } + long started = System.currentTimeMillis() + def target = "${PROJECT_PATH}/catalog-fe/target/" + def files = GFileUtils.listFiles( new File(target) , ["war"] as String[] , false); + files?.each{ File file -> + if (!file?.name?.contains('classes')){ + println "[MasterD][FrontEnd] copying ${file.length()/(1024*1024)} MB, from ${file?.name} to $FE_REMOTE/webapps" + ssh.run { + session(remotes.vagrant) { + put from: file?.absolutePath , into: "$FE_REMOTE/webapps" + } + } + } + + } + println "[MasterD][FrontEnd] Successfully copied war in ${System.currentTimeMillis()-started}ms." +} + +task deployFE{ + doLast { + copyFE() + } +} + + +def copyBE(){ + println "[MasterD][BackEnd] starting war copy." + ssh.settings { + knownHosts = allowAnyHosts + } + def target = "${PROJECT_PATH}/catalog-be/target/" + def files = GFileUtils.listFiles( new File(target) , ["war"] as String[] , false); + long started = System.currentTimeMillis() + files?.each{ File file -> + if (!file?.name?.contains('classes')){ + println "[MasterD][BackEnd] copying ${file.length()/(1024*1024)} MB, from ${file?.name} to $BE_REMOTE/webapps" + ssh.run { + session(remotes.vagrant) { + put from: file?.absolutePath , into: "$BE_REMOTE/webapps" + } + } + } + } + println "[MasterD][BackEnd] SUCCESSFULY copied be war in ${System.currentTimeMillis()-started}ms." +} + +task deployBE { + doLast { + copyBE() + } +} +def compileFE(){ + exec{ + println "[MasterD][FE]--> compiling project at -> ${PROJECT_PATH}\\catalog-fe" + workingDir "${PROJECT_PATH}" //vagrant path + commandLine 'cmd','/c','mvn -T 2 compile -pl catalog-fe,catalog-ui -am -Pcatalog -Dmaven.test.skip' + } +} +task compileFE(){ + doLast{ + compileFE() + } +} +def compileBE(){ + exec{ + println "[MasterD][BE]--> compiling project at -> ${PROJECT_PATH}\\catalog-be" + workingDir "${PROJECT_PATH}" //vagrant path + commandLine 'cmd','/c','mvn -T 2 compile -pl catalog-be -Pcatalog -Dmaven.test.skip' + } +} +task compileBE{ + doLast{ + compileBE() + } +} + +def compile(){ + exec{ + println "[MasterD]--> compiling project at -> ${PROJECT_PATH}" + workingDir "${PROJECT_PATH}" //vagrant path + commandLine 'cmd','/c','mvn -T 2 compile -am -Pcatalog -Dmaven.test.skip' + } +} + +task compile{ + doLast{ + compile() + } +} +def compileDependencies(){ + def cmd = IS_MVN_INSTALL ? 'install' : 'compile' + exec{ + println "[MasterD]--> compiling BE dependencies -> $BE_DEPENDENCIES [ SKIPPING TESTS!! ]" + workingDir "${PROJECT_PATH}" //vagrant path + commandLine 'cmd','/c',"mvn $cmd -pl $BE_DEPENDENCIES -Pcatalog -Dmaven.test.skip" //commandLine 'cmd', '/c','mvn -T 1C package -pl catalog-model,catalog-dao,catalog-be -P catalog -Dmaven.test.skip' + } +} +task compileDependencies { + doLast{ + compileDependencies() + } +} +def compileWar(){ + def cmd = IS_MVN_INSTALL ? 'install' : 'compile' + exec{ + println "--> compiling project at -> ${PROJECT_PATH}\\catalog-be" + workingDir "${PROJECT_PATH}" //vagrant path + commandLine 'cmd','/c',"mvn -T 1 $cmd war:war -pl catalog-be -Pcatalog -Dmaven.test.skip" //commandLine 'cmd', '/c','mvn -T 1C package -pl catalog-model,catalog-dao,catalog-be -P catalog -Dmaven.test.skip' + } +} +task compileWar(){ + doLast{ + compileWar() + } +} + +//deprecated - use deployBE() +task be() { + doLast{ + def started = System.currentTimeMillis(); + exec{ + println "[MasterD]--> copying be... [from $VAGRANT_HOME]" + workingDir VAGRANT_HOME //vagrant path + commandLine 'cmd','/c', 'copy_war_be.bat','localhost' , "$PROJECT_PATH\\catalog-be\\target\\catalog-be*.war" , "$BE_REMOTE/webapps" + //args = [ ] + } + println """ + **** copying finished in -> ${System.currentTimeMillis() - started}ms **** + """ + } +} + +task beConfig( ) { + doLast{ + exec{ + workingDir "${System.env.VAG}" //vagrant path + commandLine 'cmd','/c','copy_war_be_with_configuration','localhost' , "$PROJECT_PATH\\catalog-be\\target\\catalog-be*.war" , "$BE_REMOTE/webapps" + //args = [ ] + } + } + +} +task feConfig( ) { + doLast{ + exec{ + workingDir "${System.env.VAG}" //vagrant path + commandLine 'cmd','/c','copy_war_fe_with_configuration','localhost' , "$PROJECT_PATH\\catalog-fe\\target\\catalog-fe*.war" , "$FE_REMOTE/webapps" + //args = [ ] + } + } + +} + +task fe() { + doLast{ + exec { + workingDir "${System.env.VAG}" //vagrant path + commandLine 'cmd','/c', 'copy_war_fe.bat', 'localhost', "$PROJECT_PATH\\catalog-fe\\target\\catalog-fe*.war", "$FE_REMOTE/webapps" + //args = [ ] + } + } +} + +def installAllProject(){ + exec{ + println "[MasterD]--> Compiling&Installing project at -> ${PROJECT_PATH}" + workingDir "${PROJECT_PATH}" //vagrant path + commandLine 'cmd','/c','mvn -T 2 clean install -U -Pcatalog -Dmaven.test.skip' + } +} +task installAllProject { + doLast { + installAllProject() + } +} + +task installAll { + doLast{ + println '[MasterD]--> Finished!!' + } +} +installAll.dependsOn { tasks.findAll { task -> task.name.startsWith('install_') } } + +def install_BE(){ + exec { + println '[MasterD][Install]--> Installing BE!!' + workingDir "${PROJECT_PATH}" + commandLine 'cmd','/c', 'mvn clean install -pl catalog-be -am -Pcatalog -Dmaven.test.skip' + //args = [ ] + } +} + +task install_BE() { + doLast{ + install_BE() + } +} + +def install_FE() { + exec { + workingDir "${PROJECT_PATH}" + commandLine 'cmd','/c', 'mvn clean install -pl catalog-ui,catalog-fe -am -Pcatalog -Dmaven.test.skip' + } +} +task install_FE() { + doLast { + install_FE() + } +} + +def updaterBERapid(){ + /* if ( ticket() > PREVIOUS_BUILD_VAR ){ + PREVIOUS_BUILD_VAR = ticket()*/ + def started = System.currentTimeMillis(); + println "[MasterD][Rapid]--> compiling changes using maven" + compileWar() + println "[MasterD][Rapid]--> copying war" + copyBE() //use this if you want to deploy entire war //hotswap.execute() + restartBackend() + println msg(" redeploy finished in -> ${System.currentTimeMillis() - started}ms ") +} +task updaterBERapid(){ + doLast { + updaterBERapid() + } +} +def updaterBE(){ + def started = System.currentTimeMillis(); + IS_MVN_INSTALL = pomChanges() ? true : false + println "[MasterD]--> compiling changes using maven" + compileDependencies() + compileWar() + println "[MasterD]--> copying war" + IS_HOTSWAP ? copyExplodedBE() : copyBE() //execute() //use this if you want to deploy entire war //hotswap.execute() + restartBackend() + println msg("redeploy finished in -> ${System.currentTimeMillis() - started}ms ") +} +task updaterBE(){ + doLast { + updaterBE() + } +} +def copyBEConfiguration(){ +/* execSafe { + ssh.settings { + knownHosts = allowAnyHosts + } + ssh.run { + session(remotes.vagrant) { + println msg("Stopping BackEnd Server") + execute command[BACKEND][STOP]() + } + } + }*/ +} +def updaterBEFull(){ + def started = System.currentTimeMillis(); + compile() + println "[MasterD]--> copying war" + copyBE() //use this if you want to deploy entire war //hotswap.execute() + copyBEConfiguration() + println msg("redeploy finished in -> ${System.currentTimeMillis() - started}ms ") +} +task updaterBEFull(){ + doLast { + updaterBEFull() + } +} +def copyFEConfiguration(){ + //todo- implement +} +def updaterFE(){ + def started = System.currentTimeMillis(); + println "[MasterD]--> compiling changes using maven" + compileFE() + println "[MasterD]--> copying war" + copyFE() //.execute() //use this if you want to deploy entire war //hotswap.execute() + copyFEConfiguration() + println msg("redeploy finished in -> ${System.currentTimeMillis() - started}ms ") +} +task updaterFE(){ + doLast { + updaterFE() + } +} +def stopBackend(){ + execSafe { + ssh.settings { + knownHosts = allowAnyHosts + } + ssh.run { + session(remotes.vagrant) { + println msg("Stopping BackEnd Server") + execute command[BACKEND][STOP]() + } + } + } +} +task stopBackend(){ + doLast { + stopBackend() + } +} + +def startBackend(){ + execSafe { + ssh.settings { + knownHosts = allowAnyHosts + } + ssh.run { + session(remotes.vagrant) { + println msg("[MasterD] starting backend sever") + + execute command[BACKEND][START]() + } + } + } + println """[MasterD]-> finished !! + """ +} +task startBackend(){ + doLast{ + startBackend() + } +} + +def restartBackend(){ + execSafe { + ssh.settings { + knownHosts = allowAnyHosts + } + ssh.run { + session(remotes.vagrant) { + println msg("[MasterD] restarting backend sever") + + execute command[BACKEND][RESTART]() + } + } + } + println """[MasterD]-> finished !! + """ +} +//todo- remove this if you want to auto-deploy on every file save +/* +compileJava.doFirst{ + updater?.execute() +}*/ + +enum STATUS { UP, DOWN , UNKNOWN , UNAVAILABLE } + +task health(){ + doLast { + prepareTray() + } +} + +def execSafe( closure){ + if (!lockObj) { + [0..4].forEach( {println "Critical ERROR : lock object is not initialized\n\nCritical ERROR : cannot run tasks\n"}() ) + return; + } + synchronized (lockObj){ + boolean prev = isHaltHealth.get() + try { + isHaltHealth.set(true) + closure() + } catch (Exception e) { + println e + } finally { + isHaltHealth.set(prev) + } + } +} + +def fetchFiles( remote, local ){ + ssh.run { + session(remotes.vagrant) { + //execute "cd /home/vagrant/catalog-be/tmp ; ls -lt | grep catalog-be" //todo- use my dates to filter + def f = get from: remote , into: local + println f?.name + //return f + } + //println "fetched files in ${System.currentTimeMillis() - started} ms" + } + + //return null +} + + +def killJava(){ + execSafe { + def res + ssh.run { + session( remotes.vagrant ) { + println """ *-*-****************************-*-* + killing all java proccesses + *-*-****************************-*-* + """ + res = execute command[ALL][KILL]() + } + } + println res?.toString() + } +} + +def importNormative(){ + execSafe { + ssh.run { + session(remotes.vagrant) { + println """ *-*-************************************-*-* + importNormative + *-*-************************************-*-* + """ + execute "python -v $BE_REMOTE/scripts/import/tosca/importNormativeAll.py" + } + } + } +} + +def startAll(){ + def startCassandra = """ + #!/bin/bash + + cassandra& + elasticsearch -d + + #Wait until ES is up + until curl localhost:9200/_cluster/health; + do + printf "." + sleep 3 + done + + # Create Elastic Mapping if not exist in ES + createESMapping.sh + """ + execSafe { + ssh.run { + session(remotes.vagrant) { + println """ *-*-************************************-*-* + starting all SDC services(DB,BE,FE,Webseal) + *-*-************************************-*-* + """ + if ( NEW_VAG ){ + execute command[DB][START]() + Thread.sleep(5000) + execute command[CACHING][START]() + } + else + execute startCassandra + //[0..4]?.forEach( Thread?.sleep(2000) ) + Thread?.sleep(10000) + Thread?.sleep(10000) + execute command[BACKEND][START]() + execute command[FRONTEND][START]() + execute command[SECURITY][START]() + } + } + } +} + + +/*def clearLog(type: Delete){ + delete{ + delete 'C:/ProgramData/all.log' + followSymlinks = true + } +}*/ +task clearLog(type: Delete){ + doLast{ + delete 'C:/ProgramData/all.log' + followSymlinks = true + } +} +def logBE(){ + try{ + println "\n*** logging BE all.log ***\n" + + ssh.run { + session( remotes.vagrant ) { + //String now = execute 'echo \"\$(date +\'%Y_%m_%d\')\"' + //println "\n\n*******************************************************\n\n"+now?.toString() + clearLog?.execute() //todo- remove this .execute() + fetchFiles( '/home/vagrant/catalog-be/logs/SDC/SDC-BE/all.log' , 'C:/ProgramData') //"%USERPROFILE%\AppData\Local\") + //project.ext.set( "logFile" , 'C:/ProgramData/all.log' ) + + // -f /home/vagrant/catalog-fe/logs/*$now.stderrout.log -f /home/vagrant/catalog-be/logs/*$now.stderrout.log -f /home/vagrant/catalog-be/logs/ASDC/ASDC-BE/debug.log*' + } + } + + parallel { + exec { + //if ( logFile ){ + String notepad = 'C:\\Program Files (x86)\\Notepad++\\notepad++.exe' + println "logging $logFile to notepad++ [$notepad]" + commandLine 'cmd','/c' , notepad ,logFile + } + } + }catch(Exception e){ + println "cannot open logs!!!" + e.printStackTrace() + } +} +task logBE(){ + doLast{ + logBE() + } +} + +def toggleHealthPolling(){ + isHaltHealth.set(!isHaltHealth.get()) +} +//converts predefined icon to Image +def Image convert( imageName ){ + String encodedimage = project.ext.get(imageName); + byte[] byteImage = encodedimage?.split(',')[1]?.decodeBase64() + Image image = ImageIO.read(new ByteArrayInputStream(byteImage)); +} + +def refreshMenu(String imageName){ + switch( imageName ) { + case 'unavailableImg' : toggleHealthString = "Resume Health"; break; + default : toggleHealthString = "Halt Health"; + } + if (((MenuItem)toggleHealthItemView).getLabel() != toggleHealthString) + ((MenuItem)toggleHealthItemView).setLabel(toggleHealthString); +} +def startDB(){ + println "[MasterD] Starting database.." + execSafe { + ssh.settings { + knownHosts = allowAnyHosts + } + ssh.run { + session(remotes.vagrant) { + execute command[DB][START]() + } + } + } +} +task startDB(){ + doLast { + startDB() + } +} +def stopDB(){ + execSafe { + ssh.settings { + knownHosts = allowAnyHosts + } + ssh.run { + session(remotes.vagrant) { + execute command[DB][STOP]() + } + } + } +} +task stopDB(){ + doLast { + stopDB() + } +} +def startFE(){ + execSafe { + ssh.settings { + knownHosts = allowAnyHosts + } + ssh.run { + session(remotes.vagrant) { + execute command[FRONTEND][START]() + } + } + } +} +task startFE(){ + doLast { + startFE() + } +} +def stopFE(){ + execSafe { + ssh.settings { + knownHosts = allowAnyHosts + } + ssh.run { + session(remotes.vagrant) { + execute command[FRONTEND][STOP]() + } + } + } +} +task stopFE(){ + doLast { + stopFE() + } +} + +def ActionListener newListener( closure ){ + ActionListener listener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + try { + closure() + } catch (AWTException e1) { + System.err.println(e1); + } + } + } + + listener +} + +ext.updateTray = { STATUS status -> + lastStatus = status + if (SystemTray.isSupported()) { + // get the SystemTray instance + SystemTray tray = SystemTray.getSystemTray(); + // load an image + String imageName = status==STATUS.UP ? (Math.random()>0.5 ?'okImg1':'okImg2') : status==STATUS.UNAVAILABLE ? 'unavailableImg' : status==STATUS.DOWN ? 'errorImg' : 'warnImg' + Image image = convert imageName + if (trayIcon != null) { + trayIcon.setImage(image) + refreshMenu(imageName); + return ; + } + //region -> Menu UI + // create a popup menu + PopupMenu popup = new PopupMenu(); + // create menu item for the default action + + MenuItem hotswapItem = new MenuItem("===> WAR <==="); + hotswapItem.setFont(new Font("MONOSPACED" , Font.BOLD ,15f )) + + //region Multilevel Menus + Menu deployMasterMenu = new Menu("DeployMaster"); + Menu backendMenu = new Menu("Backend"); + Menu frontendMenu = new Menu("Frontend"); + Menu dbMenu = new Menu("Database"); + try{ + deployMasterMenu.setFont(new Font("Cooper Black" ,Font.BOLD ,14f )) + backendMenu.setFont(new Font("Cooper Black" ,Font.PLAIN ,13f )) + frontendMenu.setFont(new Font("Cooper Black" ,Font.PLAIN ,13f )) + dbMenu.setFont(new Font("Cooper Black" ,Font.PLAIN ,13f )) + }catch(Exception e){ + println e + } + + //DeployMaster Menu + MenuItem updaterBeWithDependenciesItem = new MenuItem("[BE] Quick Compile -> Deploy"); + MenuItem updaterFullBeItem = new MenuItem("[BE] Full Install -> Deploy"); + MenuItem updaterFeItem = new MenuItem("[FE] Quick Compile -> Deploy"); + MenuItem updaterFullFeItem = new MenuItem("[FE] Full Install -> Deploy"); + + //Menu UI build + + deployMasterMenu.add(updaterFullBeItem); + deployMasterMenu.add(updaterBeWithDependenciesItem); + + deployMasterMenu.addSeparator(); + deployMasterMenu.add(updaterFullFeItem); + deployMasterMenu.add(updaterFeItem); + + + //BE menu + MenuItem startItem = new MenuItem("[BE] Start"); + MenuItem stopItem = new MenuItem("[BE] Stop BackEnd"); + MenuItem copyBeWarItem = new MenuItem("[BE] Copy War"); + backendMenu.add(startItem); + backendMenu.add(stopItem); + backendMenu.add(copyBeWarItem); + + //FE menu + MenuItem startFEItem = new MenuItem("[FE] Start"); + MenuItem stopFEItem = new MenuItem("[FE] Stop"); + MenuItem copyFeWarItem = new MenuItem("[FE] Copy War"); + frontendMenu.add(startFEItem); + frontendMenu.add(stopFEItem); + frontendMenu.add(copyFeWarItem); + + //DB menu + MenuItem startDBItem = new MenuItem("[DB] Start"); + MenuItem stopDBItem = new MenuItem("[DB] Stop"); + MenuItem backupDBItem = new MenuItem("[DB] Backup"); + MenuItem restoreDBItem = new MenuItem("[DB] Restore"); + dbMenu.add(startDBItem); + dbMenu.add(stopDBItem); + dbMenu.add(backupDBItem); + dbMenu.add(restoreDBItem); + //endregion + + + MenuItem killItem = new MenuItem("Kill All"); + MenuItem startAllItem = new MenuItem("Start All"); + MenuItem importItem = new MenuItem("Import Normative"); + MenuItem healthInfoItem = new MenuItem("[Info] Health"); + MenuItem toggleHealthItem = new MenuItem(toggleHealthString); + MenuItem logsItem = new MenuItem("Logs [Beta]"); + MenuItem exitItem = new MenuItem("Exit"); + + toggleHealthItemView = toggleHealthItem; + + popup.add(hotswapItem); + popup?.addSeparator(); + popup.add(deployMasterMenu); + popup?.addSeparator(); + popup.add(backendMenu) + popup.add(frontendMenu) + popup.add(dbMenu) + popup?.addSeparator(); + popup.add(startAllItem); + popup.add(killItem); + popup?.addSeparator(); + popup.add(toggleHealthItem); + popup.add(healthInfoItem); + popup?.addSeparator(); + popup.add(importItem); + popup.add(logsItem); + popup?.addSeparator(); + popup.add(exitItem); + //endregion UI + // construct a TrayIcon + trayIcon = new TrayIcon(image, "HealthTray", popup); + + //region -> Button actions + def listenerHotswap = newListener { project.ext.set("IS_HOTSWAP", !IS_HOTSWAP); hotswapItem?.setLabel( IS_HOTSWAP ? "==> HotSwap <==" : "===> WAR <===") } + // create a action listener to listen for default action executed on the tray icon + def listenerFullBE = newListener { parallel { install_BE(); IS_HOTSWAP ? copyExplodedBE() : copyBE(); restartBackend() } } + def listenerFullFE = newListener { parallel { install_FE(); copyFE() } } + ActionListener listenerFE = newListener { parallel { updaterFE() } } + ActionListener listenerBE = newListener { parallel { updaterBE() } } + ActionListener exitListener = newListener { + executor?.isShutdown() ?: executor?.shutdown() + tray.remove(trayIcon); + project.ext.set("isStopHealthCheck", true) + println "Shutting down.. bye bye.." + } + ActionListener stopBackendListener = newListener { stopBackend() } + ActionListener startBEListener = newListener { parallel { startBackend() } } + ActionListener killJavaListener = newListener { killJava() } + + ActionListener startAllListener = newListener { parallel { startAll() } } + + ActionListener listener5 = new ActionListener() { + public void actionPerformed(ActionEvent e) { + try { + parallel { importNormative() } + } catch (AWTException e1) { + System.err.println(e1); + } + } + }; + + ActionListener listener6 = new ActionListener() { + public void actionPerformed(ActionEvent e) { + try { + parallel { healthPopup() } + } catch (AWTException e1) { + System.err.println(e1); + } + } + }; + + ActionListener listener7 = new ActionListener() { + public void actionPerformed(ActionEvent e) { + try { + logBE()//tasks.logger.execute() + } catch (AWTException e1) { + System.err.println(e1); + } + } + }; + ActionListener listener8 = new ActionListener() { + public void actionPerformed(ActionEvent e) { + try { + toggleHealthPolling()//tasks.logger.execute() + } catch (AWTException e1) { + System.err.println(e1); + } + } + }; + ActionListener copyBeWarListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + try { + parallel { copyBE() }//.execute()//tasks.logger.execute() + } catch (AWTException e1) { + System.err.println(e1); + } + } + }; + + ActionListener startDBListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + try { + parallel { + startDB() + }//tasks.logger.execute() + } catch (AWTException e1) { + System.err.println(e1); + } + } + } + + ActionListener stopDBListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + try { + stopDB()//tasks.logger.execute() + } catch (AWTException e1) { + System.err.println(e1); + } + } + } + + ActionListener dbBackupListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + try { + parallel { + backupDB()//tasks.logger.execute() + } + } catch (AWTException e1) { + System.err.println(e1); + } + } + } + + ActionListener feStartListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + try { + parallel { + startFE() + }//tasks.logger.execute() + } catch (AWTException e1) { + System.err.println(e1); + } + } + } + + ActionListener feStopListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + try { + stopFE()//tasks.logger.execute() + } catch (AWTException e1) { + System.err.println(e1); + } + } + } + + ActionListener feCopyListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + try { + parallel { + copyFE() //.execute()//tasks.logger.execute() + } + } catch (AWTException e1) { + System.err.println(e1); + } + } + } + + + //def listenerFullModules = newListener { parallel { installAllProject() } } + //region -> Button<=Listener + hotswapItem.addActionListener(listenerHotswap) + updaterFeItem.addActionListener(listenerFE) + updaterFullBeItem.addActionListener( listenerFullBE ) + updaterBeWithDependenciesItem.addActionListener( listenerBE ) + updaterFullFeItem.addActionListener( listenerFullFE ) + stopItem.addActionListener(stopBackendListener) + startItem.addActionListener(startBEListener) + copyBeWarItem.addActionListener(copyBeWarListener); + killItem.addActionListener(killJavaListener) + startAllItem.addActionListener(startAllListener) + importItem.addActionListener(listener5) + healthInfoItem.addActionListener(listener6) + toggleHealthItem.addActionListener(listener8) + logsItem.addActionListener(listener7) + exitItem.addActionListener(exitListener) + + startDBItem.addActionListener( startDBListener ) + stopDBItem.addActionListener( stopDBListener ) + backupDBItem.addActionListener( dbBackupListener ) + copyFeWarItem.addActionListener( feCopyListener ) + startFEItem.addActionListener( feStartListener ) + stopFEItem.addActionListener( feStopListener ) + //endregion + //endregion + // set the TrayIcon properties + + // ... + // add the tray image + try { + tray.add(trayIcon); + + } catch (AWTException e) { + System.err.println(e); + } + // ... + } else { + println "Java TrayIcon Option is not supported in your System, try enabling it. Bye Bye" + } + +} + +def prepareTray(){ + long UPDATE_THRESHOLD = 3500 + float SCALAR = 1 + ssh.settings { + knownHosts = allowAnyHosts + } + while(!isStopHealthCheck) { + if (!isHaltHealth.get()) { //if await or await is more then 60 second return health check + ssh.run { + session(remotes.vagrant) { + try { + def healthOutput = execute command[ALL][HEALTH]() + if (healthOutput?.contains("Failed command .* with status 7") || healthOutput?.contains("Problem accessing /sdc2/rest/healthCheck")) + updateTray(STATUS.DOWN) + def statusCollecion = healthOutput?.findAll "\"healthCheckStatus\": \".*\"" + def upCount = statusCollecion?.count { it?.contains("UP") } + def downCount = statusCollecion?.count { it?.contains("DOWN") } + def uknownCount = (statusCollecion?.size() - upCount) - downCount + println " UP -> $upCount | downCount=$downCount | uknownCount=$uknownCount " + (uknownCount > 0 || (downCount > 0 && upCount > 0)) ? updateTray(STATUS.UNKNOWN) : ((upCount > 0) ? updateTray(STATUS.UP) : updateTray(STATUS.DOWN)) + SCALAR = 1 + } catch (Exception e) { + updateTray(STATUS.DOWN) + println e + SCALAR = Math.min(SCALAR * 1.1, 5) //slow down on errors + } + //green color effects + if (lastStatus && lastStatus == STATUS.UP) { + trayIcon.setImage(convert(Math.random() > 0.5 ? 'okImg1' : 'okImg2')) + //randomly green change color + } + Thread.yield() + Thread?.sleep((long) (UPDATE_THRESHOLD * SCALAR)) + } + } + }else{ + updateTray(STATUS.UNAVAILABLE) + Thread.yield() + } + } +} + +def healthPopup(){ + ssh.run { + session(remotes.vagrant) { + def healthOutput = execute command[ALL][HEALTH]() + JOptionPane.showMessageDialog(null, + healthOutput, + "HEALTH", + JOptionPane.INFORMATION_MESSAGE); + } + } +} + +project.ext.set("msg", { content -> """ + ************************************************************************************************ + ************************************************************************************************ + ******* ********* + ************** **************** + $content + + ************************************************************************************************ + ************************************************************************************************ + """} ) |