Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.openliberty.tools.gradle.tasks.AbstractServerTask.groovy Maven / Gradle / Ivy
/**
* (C) Copyright IBM Corporation 2017, 2024.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.openliberty.tools.gradle.tasks
import groovy.xml.StreamingMarkupBuilder
import groovy.xml.XmlParser
import groovy.xml.XmlNodePrinter
import io.openliberty.tools.ant.ServerTask
import io.openliberty.tools.common.plugins.config.ApplicationXmlDocument
import io.openliberty.tools.common.plugins.config.ServerConfigDocument
import io.openliberty.tools.common.plugins.config.ServerConfigXmlDocument
import io.openliberty.tools.common.plugins.util.DevUtil
import io.openliberty.tools.common.plugins.util.LibertyPropFilesUtility
import io.openliberty.tools.common.plugins.util.PluginExecutionException
import io.openliberty.tools.gradle.utils.CommonLogger
import org.apache.commons.io.FileUtils
import org.apache.commons.io.FilenameUtils
import org.apache.commons.io.filefilter.FileFilterUtils
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.ModuleDependency
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.bundling.War
import org.gradle.plugins.ear.Ear
import javax.xml.parsers.ParserConfigurationException
import javax.xml.transform.TransformerException
import java.nio.file.Files
import java.nio.file.StandardCopyOption
import java.util.Map.Entry
import java.util.regex.Matcher
import java.util.regex.Pattern
abstract class AbstractServerTask extends AbstractLibertyTask {
protected final String HEADER = "# Generated by liberty-gradle-plugin"
private static final String LIBERTY_CONFIG_GRADLE_PROPS = "(^liberty\\.server\\.(env|jvmOptions|bootstrapProperties|var|defaultVar|keys))\\.(.+)"
private static final Pattern pattern = Pattern.compile(LIBERTY_CONFIG_GRADLE_PROPS)
protected final String PLUGIN_VARIABLE_CONFIG_OVERRIDES_XML = "configDropins/overrides/liberty-plugin-variable-config.xml"
protected final String PLUGIN_VARIABLE_CONFIG_DEFAULTS_XML = "configDropins/defaults/liberty-plugin-variable-config.xml"
protected final String CONTAINER_PROPERTY = 'dev_mode_container'
protected Properties bootstrapProjectProps = new Properties()
protected Properties envProjectProps = new Properties()
protected List jvmProjectProps = new ArrayList()
protected Properties varProjectProps = new Properties()
protected Properties defaultVarProjectProps = new Properties()
protected Map combinedBootstrapProperties = null
protected List combinedJvmOptions = null
protected Map combinedEnvProperties = null
protected ServerConfigDocument scd = null;
protected def server
protected def springBootBuildTask
private enum PropertyType {
BOOTSTRAP("liberty.server.bootstrapProperties"),
ENV("liberty.server.env"),
JVM("liberty.server.jvmOptions"),
VAR("liberty.server.var"),
DEFAULTVAR("liberty.server.defaultVar");
private final String name
private PropertyType(final String propName) {
this.name = propName
}
private static final Map lookup = new HashMap()
static {
for (PropertyType s : EnumSet.allOf(PropertyType.class)) {
lookup.put(s.name, s)
}
}
public static PropertyType getPropertyType(String propertyName) {
PropertyType pt = lookup.get(propertyName)
if (pt == null) {
// get a matcher object from pattern
Matcher matcher = pattern.matcher(propertyName)
// check whether Regex string is found in propertyName or not
if (matcher.find()) {
// strip off the end of the property name to get the prefix
String prefix = matcher.group(1);
pt = lookup.get(prefix);
}
}
return pt
}
public static String getSuffix(propertyName) {
// get a matcher object from pattern
Matcher matcher = pattern.matcher(propertyName)
// check whether Regex string is found in propertyName or not
if (matcher.find()) {
// strip off the beginning of the property name
String suffix = matcher.group(3)
// strip off surrounding quotation marks
if (suffix.startsWith("\"") && suffix.endsWith("\"")) {
suffix = suffix.substring(1, suffix.length() -1)
}
return suffix
}
return null
}
}
protected determineSpringBootBuildTask() {
if (isSpringBoot2plus(springBootVersion)) {
return project.bootJar
} else if (isSpringBoot1(springBootVersion)) {
return project.bootRepackage
}
}
protected void executeServerCommand(Project project, String command, Map params) {
project.ant.taskdef(name: 'server',
classname: 'io.openliberty.tools.ant.ServerTask',
classpath: project.buildscript.configurations.classpath.asPath)
params.put('operation', command)
project.ant.server(params)
}
protected Map buildLibertyMap(Project project) {
Map result = new HashMap();
result.put('serverName', server.name)
def installDir = getInstallDir(project)
result.put('installDir', installDir)
def userDir = getUserDir(project, installDir)
result.put('userDir', userDir)
result.put('outputDir', getOutputDir(project))
if (server.timeout != null && !server.timeout.isEmpty()) {
result.put('timeout', server.timeout)
}
return result;
}
protected List buildCommand (String operation) {
List command = new ArrayList()
String installDir = getInstallDir(project).toString()
if (isWindows) {
command.add(installDir + "\\bin\\server.bat")
} else {
command.add(installDir + "/bin/server")
}
command.add(operation)
command.add(server.name)
return command
}
protected File getServerDir(Project project){
return new File(getUserDir(project).toString() + "/servers/" + server.name)
}
protected String getOutputDir(Project project) {
if (server.outputDir != null) {
return server.outputDir
} else if (project.liberty.outputDir != null) {
return project.liberty.outputDir
} else {
return getUserDir(project).toString() + "/servers"
}
}
protected void initializeConfigDirectory() {
if (server.configDirectory == null) {
server.configDirectory = new File(project.projectDir, "src/main/liberty/config")
}
}
// Use this method to copy over the server.xml file from the defaultServer template.
// Returns true if the server.xml file does not exist and the defaultServer template server.xml file is copied over, false otherwise.
protected boolean copyDefaultServerTemplate(File installDir, File serverDir) {
File serverXmlFile = new File(serverDir, "server.xml")
if (!serverXmlFile.exists()) {
File defaultServerTemplate = new File(installDir, "templates/servers/defaultServer/server.xml")
if (defaultServerTemplate.exists()) {
Files.copy(defaultServerTemplate.toPath(), serverXmlFile.toPath(), StandardCopyOption.REPLACE_EXISTING)
return true;
}
}
return false;
}
protected void copyConfigDirectory() {
//merge default server.env with one in config directory
File configDirServerEnv = new File(server.configDirectory, "server.env")
if (configDirServerEnv.exists() && server.mergeServerEnv) {
FileFilter fileFilter = FileFilterUtils.notFileFilter(FileFilterUtils.nameFileFilter("server.env", null))
FileUtils.copyDirectory(server.configDirectory, getServerDir(project), fileFilter)
Properties configDirServerEnvProps = convertServerEnvToProperties(configDirServerEnv)
File defaultEnvFile = new File(getServerDir(project), "server.env")
Properties defaultServerEnvProps = convertServerEnvToProperties(defaultEnvFile)
Properties mergedProperties = combineServerEnvProperties(defaultServerEnvProps, configDirServerEnvProps)
writeServerEnvProperties(defaultEnvFile, mergedProperties)
}
else {
// replace entire directory with configured configDirectory
FileUtils.copyDirectory(server.configDirectory, getServerDir(project))
}
}
/**
* @throws IOException
* @throws FileNotFoundException
*/
protected void copyConfigFiles() throws IOException {
String serverDirectory = getServerDir(project).toString()
String serverXMLPath = null
String jvmOptionsPath = null
String bootStrapPropertiesPath = null
String serverEnvPath = null
// First check for Liberty configuration specified by Gradle project properties.
loadLibertyConfigFromProperties();
// make sure server.configDirectory exists
initializeConfigDirectory();
if(server.configDirectory.exists()) {
// copy configuration files from configuration directory to server directory if end-user set it
copyConfigDirectory()
File configDirServerXML = new File(server.configDirectory, "server.xml")
if (configDirServerXML.exists()) {
serverXMLPath = configDirServerXML.getCanonicalPath()
}
File configDirJvmOptionsFile = new File(server.configDirectory, "jvm.options")
if (configDirJvmOptionsFile.exists()) {
jvmOptionsPath = configDirJvmOptionsFile.getCanonicalPath()
}
File configDirBootstrapFile = new File(server.configDirectory, "bootstrap.properties")
if (configDirBootstrapFile.exists()) {
bootStrapPropertiesPath = configDirBootstrapFile.getCanonicalPath()
}
File configDirServerEnv = new File(server.configDirectory, "server.env")
if (configDirServerEnv.exists()) {
serverEnvPath = configDirServerEnv.getCanonicalPath()
}
}
// serverXmlFile takes precedence over server.xml from configDirectory
// copy configuration file to server directory if end-user set it.
if (server.serverXmlFile != null && server.serverXmlFile.exists()) {
Files.copy(server.serverXmlFile.toPath(), new File(serverDirectory, "server.xml").toPath(), StandardCopyOption.REPLACE_EXISTING)
serverXMLPath = server.serverXmlFile.getCanonicalPath()
}
// jvmOptions, jvmOptionsFile and jvmProjectProps take precedence over jvm.options from configDirectory
File optionsFile = new File(serverDirectory, "jvm.options")
if (optionsFile.exists() && jvmOptionsPath == null) {
// if using pre-existing installation, do not delete file
if (project.liberty.installDir == null) {
logger.info(optionsFile.getCanonicalPath() + " file deleted before processing plugin configuration.")
optionsFile.delete();
}
}
if((server.jvmOptions != null && !server.jvmOptions.isEmpty()) || !jvmProjectProps.isEmpty()){
if (jvmOptionsPath != null) {
logger.info("The " + jvmOptionsPath + " file is overwritten by inlined configuration.")
}
writeJvmOptions(optionsFile, server.jvmOptions, jvmProjectProps)
jvmOptionsPath = "inlined configuration"
} else if (server.jvmOptionsFile != null && server.jvmOptionsFile.exists()) {
if (jvmOptionsPath != null) {
logger.info("The " + jvmOptionsPath + " file is overwritten by the " + server.jvmOptionsFile.getCanonicalPath() + " file.");
}
Files.copy(server.jvmOptionsFile.toPath(), optionsFile.toPath(), StandardCopyOption.REPLACE_EXISTING)
jvmOptionsPath = server.jvmOptionsFile.getCanonicalPath()
}
// bootstrapProperties, bootstrapPropertiesFile and bootstrapProjectProps take precedence over
// bootstrap.properties from configDirectory
File bootstrapFile = new File(serverDirectory, "bootstrap.properties")
if (bootstrapFile.exists() && bootStrapPropertiesPath == null) {
// if using pre-existing installation, do not delete file
if (project.liberty.installDir == null) {
logger.info(bootstrapFile.getCanonicalPath() + " file deleted before processing plugin configuration.")
bootstrapFile.delete();
}
}
if((server.bootstrapProperties != null && !server.bootstrapProperties.isEmpty()) || !bootstrapProjectProps.isEmpty()){
if (bootStrapPropertiesPath != null) {
logger.info("The " + bootStrapPropertiesPath + " file is overwritten by inlined configuration.")
}
writeBootstrapProperties(bootstrapFile, server.bootstrapProperties, bootstrapProjectProps)
bootStrapPropertiesPath = "inlined configuration"
} else if (server.bootstrapPropertiesFile != null && server.bootstrapPropertiesFile.exists()) {
if (bootStrapPropertiesPath != null) {
logger.info("The " + bootStrapPropertiesPath + " file is overwritten by the " + server.bootstrapPropertiesFile.getCanonicalPath() + " file.")
}
Files.copy(server.bootstrapPropertiesFile.toPath(), bootstrapFile.toPath(), StandardCopyOption.REPLACE_EXISTING)
bootStrapPropertiesPath = server.bootstrapPropertiesFile.getCanonicalPath()
}
// envProjectProps and serverEnvFile take precedence over server.env from configDirectory
serverEnvPath = handleServerEnvFileAndProperties(serverEnvPath, serverDirectory)
// generate a config file on the server with any Liberty configuration variables specified via project properties
File pluginVariableConfig = new File(serverDirectory, PLUGIN_VARIABLE_CONFIG_OVERRIDES_XML)
if (pluginVariableConfig.exists()) {
logger.debug(pluginVariableConfig.getCanonicalPath() + " file deleted before processing plugin configuration.")
pluginVariableConfig.delete();
}
if ((server.var != null && !server.var.isEmpty()) || !varProjectProps.isEmpty()) {
writeConfigDropinsServerVariables(pluginVariableConfig, server.var, varProjectProps, false)
logger.info("Generate server configuration file " + pluginVariableConfig.getCanonicalPath())
}
// generate a config file on the server with any Liberty configuration default variables specified via project properties
pluginVariableConfig = new File(serverDirectory, PLUGIN_VARIABLE_CONFIG_DEFAULTS_XML)
if (pluginVariableConfig.exists()) {
logger.debug(pluginVariableConfig.getCanonicalPath() + " file deleted before processing plugin configuration.")
pluginVariableConfig.delete();
}
if ((server.defaultVar != null && !server.defaultVar.isEmpty()) || !defaultVarProjectProps.isEmpty()) {
writeConfigDropinsServerVariables(pluginVariableConfig, server.defaultVar, defaultVarProjectProps, true)
logger.info("Generate server configuration file " + pluginVariableConfig.getCanonicalPath())
}
// log info on the configuration files that get used
if (serverXMLPath != null && !serverXMLPath.isEmpty()) {
logger.info("Update server configuration file server.xml from " + serverXMLPath)
}
if (jvmOptionsPath != null && !jvmOptionsPath.isEmpty()) {
logger.info("Update server configuration file jvm.options from " + jvmOptionsPath)
}
if (bootStrapPropertiesPath != null && !bootStrapPropertiesPath.isEmpty()) {
logger.info("Update server configuration file bootstrap.properties from " + bootStrapPropertiesPath)
}
if (serverEnvPath != null && !serverEnvPath.isEmpty()) {
logger.info("Update server configuration file server.env from " + serverEnvPath)
}
writeServerPropertiesToXml(project)
}
private void loadLibertyConfigFromProperties() {
Set> entries = project.getProperties().entrySet()
for (Entry entry : entries) {
String key = (String) entry.getKey()
PropertyType propType = PropertyType.getPropertyType(key)
if (propType != null) {
String suffix = PropertyType.getSuffix(key)
if (suffix != null) {
// dealing with single property
Object value = entry.getValue()
String propValue = value == null ? null : value.toString()
if (propValue != null && propValue.startsWith("\"") && propValue.endsWith("\"")) {
propValue = propValue.substring(1, propValue.length() -1)
}
addProjectProperty(suffix, propValue, propType)
} else {
// dealing with array of properties
Object value = entry.getValue()
String propValue = value == null ? null : value.toString()
if ( (propValue != null) && ( (propValue.startsWith("{") && propValue.endsWith("}")) || (propValue.startsWith("[") && propValue.endsWith("]")) ) ) {
propValue = propValue.substring(1, propValue.length() -1)
}
// parse the array where properties are delimited by commas and the name/value are separated with a colon
String[] values = propValue.split(",")
for (String nextNameValuePair : values) {
String trimmedNameValuePair = nextNameValuePair.trim()
String[] splitNameValue = trimmedNameValuePair.split(":")
String nextPropName = splitNameValue[0].trim()
// remove surrounding quotes from property names and property values
if (nextPropName.startsWith("\"") && nextPropName.endsWith("\"")) {
nextPropName = nextPropName.substring(1, nextPropName.length() -1)
}
String nextPropValue = null
if (splitNameValue.length == 2) {
nextPropValue = splitNameValue[1].trim()
if (nextPropValue.startsWith("\"") && nextPropValue.endsWith("\"")) {
nextPropValue = nextPropValue.substring(1, nextPropValue.length() -1)
}
}
addProjectProperty(nextPropName, nextPropValue, propType)
}
}
}
}
}
private void addProjectProperty(String propName, String propValue, PropertyType propType) {
if (propValue != null) {
logger.debug("Processing Liberty configuration from property with type "+ propType +" and name "+ propName +" and value "+ propValue)
} else {
logger.debug("Processing Liberty configuration from property with type "+ propType +" and value " + propName)
}
switch (propType) {
case PropertyType.ENV: envProjectProps.setProperty(propName, propValue)
break
case PropertyType.BOOTSTRAP: bootstrapProjectProps.setProperty(propName, propValue)
break
case PropertyType.JVM: jvmProjectProps.remove(propName) // avoid exact duplicates
jvmProjectProps.add(propName)
break
case PropertyType.VAR: varProjectProps.setProperty(propName, propValue)
break
case PropertyType.DEFAULTVAR: defaultVarProjectProps.setProperty(propName, propValue)
break
}
}
protected void setServerDirectoryNodes(Project project, Node serverNode) {
serverNode.appendNode('userDirectory', getUserDir(project).toString())
serverNode.appendNode('serverDirectory', getServerDir(project).toString())
serverNode.appendNode('serverOutputDirectory', new File(getOutputDir(project), server.name))
}
protected void setServerPropertyNodes(Project project, Node serverNode) {
serverNode.appendNode('serverName', server.name)
if (server.configDirectory != null && server.configDirectory.exists()) {
serverNode.appendNode('configDirectory', server.configDirectory.toString())
}
if (server.serverXmlFile != null && server.serverXmlFile.exists()) {
serverNode.appendNode('configFile', server.serverXmlFile.toString())
}
if (combinedBootstrapProperties != null) {
Node bootstrapProperties = new Node(null, 'bootstrapProperties')
combinedBootstrapProperties.each { k, v ->
bootstrapProperties.appendNode(k, v.toString())
}
serverNode.append(bootstrapProperties)
} else if (server.bootstrapProperties != null && !server.bootstrapProperties.isEmpty()) {
Node bootstrapProperties = new Node(null, 'bootstrapProperties')
server.bootstrapProperties.each { k, v ->
bootstrapProperties.appendNode(k, v.toString())
}
serverNode.append(bootstrapProperties)
} else if (server.bootstrapPropertiesFile != null && server.bootstrapPropertiesFile.exists()) {
serverNode.appendNode('bootstrapPropertiesFile', server.bootstrapPropertiesFile.toString())
}
if (combinedJvmOptions != null) {
Node jvmOptions = new Node(null, 'jvmOptions')
combinedJvmOptions.each { v ->
jvmOptions.appendNode('params', v.toString())
}
serverNode.append(jvmOptions)
} else if (server.jvmOptions != null && !server.jvmOptions.isEmpty()) {
Node jvmOptions = new Node(null, 'jvmOptions')
server.jvmOptions.each { v ->
jvmOptions.appendNode('params', v.toString())
}
serverNode.append(jvmOptions)
} else if (server.jvmOptionsFile != null && server.jvmOptionsFile.exists()) {
serverNode.appendNode('jvmOptionsFile', server.jvmOptionsFile.toString())
}
// Only write the serverEnvFile path if it was not overridden by liberty.env.{var} project properties.
if (envProjectProps.isEmpty() && server.serverEnvFile != null && server.serverEnvFile.exists()) {
serverNode.appendNode('serverEnv', server.serverEnvFile.toString())
}
serverNode.appendNode('looseApplication', server.looseApplication)
serverNode.appendNode('stripVersion', server.stripVersion)
configureMultipleAppsConfigDropins(serverNode)
}
protected ServerConfigDocument getServerConfigDocument(CommonLogger log, File serverXML) throws IOException {
if (scd == null || !scd.getOriginalServerXMLFile().getCanonicalPath().equals(serverXML.getCanonicalPath())) {
try {
scd = new ServerConfigDocument(log, serverXML, getInstallDir(project), getUserDir(project), getServerDir(project));
} catch (PluginExecutionException e) {
throw new GradleException(e.getMessage());
}
}
return scd
}
protected boolean isAppConfiguredInSourceServerXml(String fileName) {
boolean configured = false;
File serverConfigFile = new File(getServerDir(project), 'server.xml')
if (serverConfigFile != null && serverConfigFile.exists()) {
try {
Map props = combinedBootstrapProperties == null ? convertPropertiesToMap(server.bootstrapProperties) : combinedBootstrapProperties;
getServerConfigDocument(new CommonLogger(project), serverConfigFile);
if (scd != null && isLocationFound( scd.getLocations(), fileName)) {
logger.debug("Application configuration is found in server.xml : " + fileName)
configured = true
} else {
logger.debug("Application configuration is not found in server.xml : " + fileName)
}
}
catch (Exception e) {
logger.warn(e.getLocalizedMessage())
}
}
return configured
}
protected boolean isLocationFound(Set locations, String fileName) {
if (locations == null) {
return false
}
if (locations.contains(fileName)) {
return true
}
for (String nextLocation : locations) {
int index = nextLocation.lastIndexOf("/")
if (index > -1) {
String appName = nextLocation.substring(index+1)
if (fileName.equals(appName)) {
return true
}
}
}
return false
}
// Gradle passes the properties from the configuration as Strings and Integers and maybe Booleans.
// Need to convert to the String values for those Objects before passing along to ServerConfigDocument.
protected Map convertPropertiesToMap(Properties props) {
if (props == null) {
return null
}
Map returnProps = new HashMap ()
Set> entries = props.entrySet()
for (Entry entry : entries) {
String key = (String) entry.getKey()
Object value = entry.getValue()
if (value != null) {
returnProps.put(key,value.toString())
}
}
return returnProps
}
protected String getArchiveName(Task task){
if (isSpringBoot1(springBootVersion)) {
task = project.jar
}
if (server.stripVersion){
return task.getArchiveBaseName().get() + "." + task.getArchiveExtension().get()
}
return task.getArchiveFileName().get();
}
protected void configureApps(Project project) {
if ((server.deploy.apps == null || server.deploy.apps.isEmpty()) && (server.deploy.dropins == null || server.deploy.dropins.isEmpty())) {
if (!project.configurations.libertyApp.isEmpty()) {
server.deploy.apps = getApplicationFilesFromConfiguration().toArray()
} else if (project.plugins.hasPlugin('war')) {
server.deploy.apps = [project.war]
} else if (project.plugins.hasPlugin('ear')) {
server.deploy.apps = [project.ear]
} else if (project.plugins.hasPlugin('org.springframework.boot')) {
server.deploy.apps = [springBootBuildTask]
}
}
}
protected void configureMultipleAppsConfigDropins(Node serverNode) {
if (server.deploy.apps != null && !server.deploy.apps.isEmpty()) {
Tuple applications = splitAppList(server.deploy.apps)
applications[0].each{ Task task ->
isConfigDropinsRequired(task, 'apps', serverNode)
}
}
}
protected Tuple splitAppList(List allApps) {
List appFiles = new ArrayList()
List appTasks = new ArrayList()
allApps.each { Object appObj ->
if (appObj instanceof Task) {
appTasks.add((Task)appObj)
} else if (appObj instanceof File) {
appFiles.add((File)appObj)
} else {
logger.warn('Application ' + appObj.getClass.name + ' is expressed as ' + appObj.toString() + ' which is not a supported input type. Define applications using Task or File objects.')
}
}
return new Tuple(appTasks, appFiles)
}
private boolean isSupportedType(){
switch (getPackagingType()) {
case "ear":
case "war":
return true;
default:
return false;
}
}
protected String getLooseConfigFileName(Task task){
return getArchiveName(task) + ".xml"
}
protected void isConfigDropinsRequired(Task task, String appsDir, Node serverNode) {
File installAppsConfigDropinsFile = ApplicationXmlDocument.getApplicationXmlFile(getServerDir(project))
if (isSupportedType()) {
if (server.looseApplication){
String looseConfigFileName = getLooseConfigFileName(task)
String application = looseConfigFileName.substring(0, looseConfigFileName.length()-4)
if (!isAppConfiguredInSourceServerXml(application)) {
serverNode.appendNode('installAppsConfigDropins', installAppsConfigDropinsFile.toString())
}
} else {
if (!isAppConfiguredInSourceServerXml(getArchiveName(task)) || hasConfiguredApp(ApplicationXmlDocument.getApplicationXmlFile(getServerDir(project)))) {
serverNode.appendNode('installAppsConfigDropins', installAppsConfigDropinsFile.toString())
}
}
}
}
protected void createApplicationElements(Node applicationsNode, List appList, String appDir) {
springBootVersion=findSpringBootVersion(project)
appList.each { Object appObj ->
Node application = new Node(null, 'application')
if (appObj instanceof Task) {
if (isSpringBoot1(springBootVersion)) {
appObj = project.jar
}
application.appendNode('appsDirectory', appDir)
if (server.looseApplication) {
application.appendNode('applicationFilename', appObj.getArchiveFileName().get() + '.xml')
} else {
application.appendNode('applicationFilename', appObj.getArchiveFileName().get())
}
if (appObj instanceof War) {
application.appendNode('warSourceDirectory', project.webAppDirName)
}
} else if (appObj instanceof File) {
application.appendNode('appsDirectory', appDir)
if (server.looseApplication) {
application.appendNode('applicationFilename', appObj.name + '.xml')
} else {
application.appendNode('applicationFilename', appObj.name)
}
}
if(!application.children().isEmpty()) {
if (project.plugins.hasPlugin("war")) {
application.appendNode('projectType', 'war')
} else if (project.plugins.hasPlugin("ear")) {
application.appendNode('projectType', 'ear')
}
applicationsNode.append(application)
}
}
}
protected void setApplicationPropertyNodes(Project project, Node serverNode) {
Node applicationsNode;
if ((server.deploy.apps == null || server.deploy.apps.isEmpty()) && (server.deploy.dropins == null || server.deploy.dropins.isEmpty())) {
if (project.plugins.hasPlugin('war')) {
applicationsNode = new Node(null, 'applications')
createApplicationElements(applicationsNode, [project.tasks.war], 'apps')
serverNode.append(applicationsNode)
}
} else {
applicationsNode = new Node(null, 'applications')
if (server.deploy.apps != null && !server.deploy.apps.isEmpty()) {
createApplicationElements(applicationsNode, server.deploy.apps, 'apps')
}
if (server.deploy.dropins != null && !server.deploy.dropins.isEmpty()) {
createApplicationElements(applicationsNode, server.deploy.dropins, 'dropins')
}
serverNode.append(applicationsNode)
}
}
protected void setDependencyNodes(Project project, Node serverNode) {
Project parent = project.getParent()
if (parent != null) {
serverNode.appendNode('aggregatorParentId', parent.getName())
serverNode.appendNode('aggregatorParentBasedir', parent.getProjectDir())
}
if (project.configurations.findByName('compile') && !project.configurations.compile.dependencies.isEmpty()) {
project.configurations.compile.dependencies.each { dependency ->
serverNode.appendNode('projectCompileDependency', dependency.group + ':' + dependency.name + ':' + dependency.version)
}
}
}
protected void writeServerPropertiesToXml(Project project) {
XmlParser pluginXmlParser = new XmlParser()
Node libertyPluginConfig = pluginXmlParser.parse(new File(project.getLayout().getBuildDirectory().getAsFile().get(), 'liberty-plugin-config.xml'))
if (libertyPluginConfig.getAt('servers').isEmpty()) {
libertyPluginConfig.appendNode('servers')
} else {
//removes the server nodes from the servers element
libertyPluginConfig.getAt('servers')[0].value = ""
}
Node serverNode = new Node(null, 'server')
setServerDirectoryNodes(project, serverNode)
setServerPropertyNodes(project, serverNode)
setApplicationPropertyNodes(project, serverNode)
setDependencyNodes(project, serverNode)
libertyPluginConfig.getAt('servers')[0].append(serverNode)
new File( project.getLayout().getBuildDirectory().getAsFile().get(), 'liberty-plugin-config.xml' ).withWriter('UTF-8') { output ->
output << new StreamingMarkupBuilder().bind { mkp.xmlDeclaration(encoding: 'UTF-8', version: '1.0' ) }
XmlNodePrinter printer = new XmlNodePrinter( new PrintWriter(output) )
printer.preserveWhitespace = true
printer.print( libertyPluginConfig )
}
logger.info ("Adding Liberty plugin config info to ${project.getLayout().getBuildDirectory().getAsFile().get()}/liberty-plugin-config.xml.")
}
private void writeBootstrapProperties(File file, Properties properties, Map projectProperties) throws IOException {
Map convertedProps = convertPropertiesToMap(properties)
if (! projectProperties.isEmpty()) {
if (properties == null) {
combinedBootstrapProperties = projectProperties;
} else {
combinedBootstrapProperties = new HashMap ()
// add the project properties (which come from the command line) last so that they take precedence over the properties specified in build.gradle
combinedBootstrapProperties.putAll(convertedProps)
combinedBootstrapProperties.putAll(projectProperties)
}
} else {
combinedBootstrapProperties = convertedProps
}
makeParentDirectory(file)
PrintWriter writer = null
try {
writer = new PrintWriter(file, "UTF-8")
writer.println(HEADER)
for (Map.Entry entry : combinedBootstrapProperties.entrySet()) {
writer.print(entry.getKey())
writer.print("=")
writer.println((entry.getValue() != null) ? entry.getValue().toString().replace("\\", "/") : "")
}
} finally {
if (writer != null) {
writer.close()
}
}
}
// Remove any duplicate entries in the passed in List
protected List getUniqueValues(List values) {
List uniqueValues = new ArrayList ();
if (values == null) {
return uniqueValues
}
for (String nextValue : values) {
// by removing a matching existing value, it ensures there will not be a duplicate and that this current one will appear later in the List
if (uniqueValues.contains(nextValue)) {
getLog().debug("Remove duplicate value: "+nextValue+" at position: "+uniqueValues.indexOf(nextValue))
}
uniqueValues.remove(nextValue) // has no effect if the value is not present
uniqueValues.add(nextValue)
}
return uniqueValues
}
private void writeJvmOptions(File file, List options, List projectProperties) throws IOException {
List uniqueOptions = getUniqueValues(options)
List uniqueProps = getUniqueValues(projectProperties)
if (! uniqueProps.isEmpty()) {
if (uniqueOptions.isEmpty()) {
combinedJvmOptions = uniqueProps;
} else {
combinedJvmOptions = new ArrayList ()
// add the project properties (which come from the command line) last so that they take precedence over the options specified in build.gradle
combinedJvmOptions.addAll(uniqueOptions)
combinedJvmOptions.removeAll(uniqueProps) // remove any exact duplicates before adding all the project properties
combinedJvmOptions.addAll(uniqueProps)
}
} else {
combinedJvmOptions = uniqueOptions
}
makeParentDirectory(file)
PrintWriter writer = null
try {
writer = new PrintWriter(file, "UTF-8")
writer.println(HEADER)
for (String option : combinedJvmOptions) {
writer.println(option)
}
} finally {
if (writer != null) {
writer.close()
}
}
}
private String handleServerEnvFileAndProperties(String serverEnvPath, String serverDirectory) {
File envFile = new File(serverDirectory, "server.env")
Properties configuredProps = combineServerEnvProperties(server.env, envProjectProps);
if(server.mergeServerEnv) {
return setServerEnvWithAppendServerEnvHelper(envFile, serverEnvPath, configuredProps)
}
else {
return setServerEnvHelper(envFile, serverEnvPath, configuredProps)
}
}
private String setServerEnvWithAppendServerEnvHelper(File envFile, String serverEnvPath, Properties configuredProps) {
Properties serverEnvProps = convertServerEnvToProperties(envFile);
Properties mergedProperties = new Properties();
if (server.serverEnvFile != null && server.serverEnvFile.exists()) {
if (serverEnvPath != null) {
logger.debug("The serverEnvFile "+ server.serverEnvFile.getCanonicalPath() + " is merged with the " + serverEnvPath + " file.")
}
else {
logger.debug("The serverEnvFile "+ server.serverEnvFile.getCanonicalPath() + " is merged with the " + getServerDir(project).getCanonicalPath() + " file.")
}
Properties configuredServerEnvProps = convertServerEnvToProperties(server.serverEnvFile);
//Merge with either default server.env or with what has already been merged if
mergedProperties = (Properties) combineServerEnvProperties(serverEnvProps, configuredServerEnvProps);
}
if (!configuredProps.isEmpty()) {
if (serverEnvPath != null) {
logger.debug("The " + serverEnvPath + " file is merged with inlined configuration.")
}
else {
logger.debug("The " + getServerDir(project).getCanonicalPath() + " file is merged with inlined configuration.")
}
if (mergedProperties.isEmpty()) {
mergedProperties = combineServerEnvProperties(serverEnvProps, configuredProps);
} else {
mergedProperties = combineServerEnvProperties(mergedProperties, configuredProps);
}
}
if(!mergedProperties.isEmpty()) {
writeServerEnvProperties(envFile, mergedProperties);
return setServerEnvPathHelperForAppendServerEnv(envFile, configuredProps, serverEnvPath)
}
return serverEnvPath;
}
private String setServerEnvPathHelperForAppendServerEnv(File envFile, Properties configuredProps, String serverEnvPath) {
boolean configDirEnvMerged = serverEnvPath != null;
boolean serverEnvFileMerged = server.serverEnvFile != null && server.serverEnvFile.exists()
boolean inlineEnvPropsMerged = !configuredProps.isEmpty()
StringBuilder updatedServerEnvPath = new StringBuilder("merging");
if(configDirEnvMerged) {
updatedServerEnvPath.append(" configDir server.env " + serverEnvPath + ", ")
}
if (serverEnvFileMerged) {
updatedServerEnvPath.append(" serverEnvFile " + server.serverEnvFile.getCanonicalPath() + ", ")
}
if (inlineEnvPropsMerged) {
updatedServerEnvPath.append(" env properties, ")
}
// remove excess comma and space
int lastCommaIndex = updatedServerEnvPath.lastIndexOf(", ")
updatedServerEnvPath = updatedServerEnvPath.replace(lastCommaIndex, lastCommaIndex + 2, ".")
//replace last comma and space with and
lastCommaIndex = updatedServerEnvPath.lastIndexOf(", ")
if(lastCommaIndex > 0) {
updatedServerEnvPath = updatedServerEnvPath.replace(lastCommaIndex, lastCommaIndex + 2, "")
updatedServerEnvPath = updatedServerEnvPath.insert(lastCommaIndex, " and")
}
return updatedServerEnvPath.toString();
}
private String setServerEnvHelper(File envFile, String serverEnvPath, Properties configuredProps) {
if ((server.env != null && !server.env.isEmpty()) || !envProjectProps.isEmpty()) {
Properties envPropsToWrite = configuredProps
if (serverEnvPath == null && server.serverEnvFile == null) {
// Do a special case merge but ONLY if there is no server.env file present in configDirectory or specified with serverEnvFile
envPropsToWrite = mergeSpecialPropsFromInstallServerEnvIfAbsent(envFile, configuredProps)
logger.warn("The default " + envFile.getCanonicalPath() + " file is overwritten by inlined configuration.")
} else if (serverEnvPath != null) {
logger.warn("The " + serverEnvPath + " file is overwritten by inlined configuration.")
}
writeServerEnvProperties(envFile, envPropsToWrite)
return "inlined configuration"
} else if (server.serverEnvFile != null && server.serverEnvFile.exists()) {
if (serverEnvPath != null) {
logger.warn("The " + serverEnvPath + " file is overwritten by the " + server.serverEnvFile.getCanonicalPath() + " file.")
}
Files.copy(server.serverEnvFile.toPath(), envFile.toPath(), StandardCopyOption.REPLACE_EXISTING)
return server.serverEnvFile.getCanonicalPath()
}
}
/**
* Merges envProps with special properties found in envFile, the install (target) server.env. We return a clone/copy of
* envProps, to which any of a list of special properties found in envFile have been added. We give precedence
* to properties already in envProps.
*/
private Properties mergeSpecialPropsFromInstallServerEnvIfAbsent(File envFile, Properties envProps) throws IOException {
// Make a copy to avoid side effects
Properties mergedProps = new Properties()
mergedProps.putAll(envProps)
// From install (target) dir
Properties serverEnvProps = convertServerEnvToProperties(envFile)
String propertyName = "keystore_password"
if (serverEnvProps.containsKey(propertyName)) {
mergedProps.putIfAbsent(propertyName,serverEnvProps.get(propertyName))
}
return mergedProps
}
private Properties convertServerEnvToProperties(File serverEnv) {
Properties serverEnvProps = new Properties();
if ((serverEnv == null) || !serverEnv.exists()) {
return serverEnvProps;
}
BufferedReader bf = new BufferedReader(new FileReader(serverEnv));
String line;
while((line = bf.readLine()) != null) {
//Skip comments
if(!line.startsWith("#")) {
String[] keyValue = line.split("=", 2);
if (keyValue.length == 2) {
String key = keyValue[0];
String value = keyValue[1];
serverEnvProps.put(key,value);
}
}
}
return serverEnvProps;
}
private Properties combineServerEnvProperties(Properties properties, Properties projectProperties) {
Properties combinedEnvProperties = new Properties()
if (! projectProperties.isEmpty()) {
if (properties.isEmpty()) {
combinedEnvProperties.putAll(projectProperties)
} else {
// add the project properties (which come from the command line) last so that they take precedence over the properties specified in build.gradle
combinedEnvProperties.putAll(properties)
combinedEnvProperties.putAll(projectProperties)
}
} else {
combinedEnvProperties.putAll(properties)
}
return combinedEnvProperties;
}
private void writeServerEnvProperties(File file, Properties combinedEnvProperties) throws IOException {
makeParentDirectory(file)
PrintWriter writer = null
try {
writer = new PrintWriter(file, "UTF-8")
writer.println(HEADER)
for (Map.Entry entry : combinedEnvProperties.entrySet()) {
writer.print(entry.getKey())
writer.print("=")
writer.println((entry.getValue() != null) ? entry.getValue().toString().replace("\\", "/") : "")
}
} finally {
if (writer != null) {
writer.close()
}
}
}
private void writeConfigDropinsServerVariables(File file, Properties varProps, Properties varProjectProps, boolean isDefaultVar) throws IOException, TransformerException, ParserConfigurationException {
ServerConfigXmlDocument configDocument = ServerConfigXmlDocument.newInstance()
configDocument.createComment(HEADER)
for (Map.Entry entry : varProjectProps.entrySet()) {
configDocument.createVariableWithValue(entry.getKey(), entry.getValue(), isDefaultVar)
}
for (Map.Entry entry : varProps.entrySet()) {
configDocument.createVariableWithValue(entry.getKey(), entry.getValue(), isDefaultVar)
}
// write XML document to file
makeParentDirectory(file)
configDocument.writeXMLDocument(file)
}
private void makeParentDirectory(File file) {
File parentDir = file.getParentFile()
if (parentDir != null) {
parentDir.mkdirs()
}
}
@Internal
protected String getPackagingType() throws Exception{
if (project.plugins.hasPlugin("war") || !project.tasks.withType(War).isEmpty()) {
if (project.plugins.hasPlugin("org.springframework.boot")) {
return "springboot"
}
return "war"
}
else if (project.plugins.hasPlugin("ear") || !project.tasks.withType(Ear).isEmpty()) {
return "ear"
}
else if (project.plugins.hasPlugin("org.springframework.boot") ) {
return "springboot"
}
else {
throw new GradleException("Archive path not found. Supported formats are jar, war, ear, and springboot jar.")
}
}
//Checks if there is an app configured in an existing configDropins application xml file
protected boolean hasConfiguredApp(File applicationXmlFile) {
if (applicationXmlFile.exists()) {
ApplicationXmlDocument appXml = new ApplicationXmlDocument()
appXml.createDocument(applicationXmlFile)
return appXml.hasChildElements()
}
return false
}
@Internal
protected List getApplicationFilesFromConfiguration() {
List appFiles = new ArrayList()
//This loops thorugh all the Dependency objects that get created by the configuration
for (Dependency dep : project.configurations.libertyApp.getDependencies()) {
if (dep instanceof ModuleDependency) { //Check that dep isn't a File dependency
dep.setTransitive(false) //Only want main artifacts, one for Maven and one or more for Gradle/Ivy dependencies
}
Set depArtifacts = project.configurations.libertyApp.files(dep) //Resolve the artifacts
for (File depArtifact : depArtifacts) {
File appFile = depArtifact
if (dep instanceof ModuleDependency && server.stripVersion && depArtifact.getName().contains(dep.getVersion())) {
String noVersionName = depArtifact.getName().minus("-" + dep.getVersion()) //Assuming default Gradle naming scheme
File noVersionDependencyFile = new File(project.getLayout().getBuildDirectory().asFile.get(), 'libs/' + noVersionName) //Copying the file to build/libs with no version
FileUtils.copyFile(depArtifact, noVersionDependencyFile)
appFile = noVersionDependencyFile
}
if (FilenameUtils.getExtension(appFile.getName()).equals('war') || FilenameUtils.getExtension(appFile.getName()).equals('ear')) {
appFiles.add(appFile)
}
}
}
return appFiles
}
protected ServerTask createServerTask(Project project, String operation) {
ServerTask serverTask = new ServerTask()
serverTask.setServerName(server.name)
def installDir = getInstallDir(project)
serverTask.setInstallDir(installDir)
serverTask.setUserDir(getUserDir(project, installDir))
serverTask.setOutputDir(new File(getOutputDir(project)))
//Some uses of a server task do not require an operation to be specified
if (operation != null && !operation.isEmpty()) {
serverTask.setOperation(operation)
}
if (server.timeout != null && !server.timeout.isEmpty()) {
serverTask.setTimeout(server.timeout)
}
return serverTask
}
protected Map getLibertyDirectoryPropertyFiles(String serverDirectoryParam) {
File serverConfigDir = getServerDir(project)
// if DevMode provides a server directory parameter use that for finding the server config dir
if (serverDirectoryParam != null) {
serverConfigDir = new File(serverDirectoryParam)
}
File wlpInstallDir = getInstallDir(project)
File wlpUserDir = getUserDir(project, wlpInstallDir)
return LibertyPropFilesUtility.getLibertyDirectoryPropertyFiles(new CommonLogger(project), wlpInstallDir, wlpUserDir, serverConfigDir)
}
// Return the loose application configuration xml file
public File getLooseAppConfigFile(Boolean container, String appsDir) throws GradleException {
String looseConfigFileName
List appsList
if (appsDir.equals("apps")) {
appsList = server.deploy.apps
} else if (appsDir.equals("dropins")) {
appsList = server.deploy.dropins
}
Tuple applications = splitAppList(appsList)
if (applications[0].isEmpty()) {
throw new GradleException("Liberty dev mode requires a loose application file. No war/ear task was configured for 'apps' or 'dropins'. Unable to create a loose application file.")
}
applications[0].each { Task task ->
looseConfigFileName = getLooseConfigFileName(task)
}
if (container) {
File devcDestDir = new File(new File(project.getLayout().getBuildDirectory().getAsFile().get(), DevUtil.DEVC_HIDDEN_FOLDER), appsDir)
return (new File(devcDestDir, looseConfigFileName));
} else {
File destDir = new File(getServerDir(project), appsDir)
return (new File(destDir, looseConfigFileName));
}
}
}