437395 - Start / Properties in template sections should be default applied for enabled modules

+ Initial edits to support loading of Module [INI-TEMPLATE] section
  as default values for the enabled module.
This commit is contained in:
Joakim Erdfelt 2014-06-16 14:48:39 -07:00
parent bca7e75d9f
commit 5fa564efa8
12 changed files with 264 additions and 70 deletions

View File

@ -389,10 +389,10 @@ public class Main
}
boolean transitive = module.isEnabled() && (module.getSources().size() == 0);
boolean has_ini_lines = module.getInitialise().size() > 0;
boolean hasDefinedDefaults = module.getDefaultConfig().size() > 0;
// If it is not enabled or is transitive with ini template lines or toplevel and doesn't exist
if (!module.isEnabled() || (transitive && has_ini_lines) || (topLevel && !FS.exists(startd_ini) && !appendStartIni))
if (!module.isEnabled() || (transitive && hasDefinedDefaults) || (topLevel && !FS.exists(startd_ini) && !appendStartIni))
{
// File BufferedWriter
BufferedWriter writer = null;
@ -430,7 +430,7 @@ public class Main
out.println("--module=" + name);
args.parse("--module=" + name,source);
modules.enable(name,Collections.singletonList(source));
for (String line : module.getInitialise())
for (String line : module.getDefaultConfig())
{
out.println(line);
args.parse(line,source);
@ -490,10 +490,9 @@ public class Main
// Process dependencies
module.expandProperties(args.getProperties());
modules.registerParentsIfMissing(baseHome,args,module);
modules.registerParentsIfMissing(module);
modules.buildGraph();
// process new ini modules
if (topLevel)
{
@ -573,9 +572,9 @@ public class Main
// ------------------------------------------------------------
// 3) Module Registration
Modules modules = new Modules();
Modules modules = new Modules(baseHome,args);
StartLog.debug("Registering all modules");
modules.registerAll(baseHome, args);
modules.registerAll();
// ------------------------------------------------------------
// 4) Active Module Resolution
@ -600,6 +599,7 @@ public class Main
// 6) Resolve Extra XMLs
args.resolveExtraXmls(baseHome);
// ------------------------------------------------------------
// 9) Resolve Property Files
args.resolvePropertyFiles(baseHome);

View File

@ -96,7 +96,7 @@ public class Module
/** List of xml configurations for this Module */
private List<String> xmls;
/** List of ini template lines */
private List<String> initialise;
private List<String> defaultConfig;
/** List of library options for this Module */
private List<String> libs;
/** List of files for this Module */
@ -213,9 +213,14 @@ public class Module
return fileRef;
}
public List<String> getInitialise()
public List<String> getDefaultConfig()
{
return initialise;
return defaultConfig;
}
public boolean hasDefaultConfig()
{
return (defaultConfig != null) && (defaultConfig.size() > 0);
}
public List<String> getLibs()
@ -274,7 +279,7 @@ public class Module
parentEdges = new HashSet<>();
childEdges = new HashSet<>();
xmls = new ArrayList<>();
initialise = new ArrayList<>();
defaultConfig = new ArrayList<>();
libs = new ArrayList<>();
files = new ArrayList<>();
jvmArgs = new ArrayList<>();
@ -328,7 +333,7 @@ public class Module
{
if ("INI-TEMPLATE".equals(sectionType))
{
initialise.add(line);
defaultConfig.add(line);
}
}
else
@ -344,8 +349,9 @@ public class Module
case "FILES":
files.add(line);
break;
case "DEFAULTS":
case "INI-TEMPLATE":
initialise.add(line);
defaultConfig.add(line);
break;
case "LIB":
libs.add(line);
@ -404,4 +410,5 @@ public class Module
str.append(']');
return str.toString();
}
}

View File

@ -212,9 +212,9 @@ public class ModuleGraphWriter
}
}
if (!module.getInitialise().isEmpty())
if (!module.getDefaultConfig().isEmpty())
{
List<String> inis = module.getInitialise();
List<String> inis = module.getDefaultConfig();
writeModuleDetailHeader(out,"INI Template",inis.size());
}

View File

@ -38,6 +38,9 @@ import java.util.regex.Pattern;
*/
public class Modules implements Iterable<Module>
{
private final BaseHome baseHome;
private final StartArgs args;
private Map<String, Module> modules = new HashMap<>();
/*
* modules that may appear in the resolved graph but are undefined in the module system
@ -48,6 +51,12 @@ public class Modules implements Iterable<Module>
private int maxDepth = -1;
public Modules(BaseHome basehome, StartArgs args)
{
this.baseHome = basehome;
this.args = args;
}
private Set<String> asNameSet(Set<Module> moduleSet)
{
Set<String> ret = new HashSet<>();
@ -106,8 +115,10 @@ public class Modules implements Iterable<Module>
/**
* Using the provided dependencies, build the module graph
*/
public void buildGraph()
public void buildGraph() throws FileNotFoundException, IOException
{
normalizeDependencies();
// Connect edges
for (Module module : modules.values())
{
@ -118,9 +129,13 @@ public class Modules implements Iterable<Module>
if (parent == null)
{
if (parentName.contains("${"))
{
StartLog.debug("module not found [%s]%n",parentName);
}
else
{
StartLog.warn("module not found [%s]%n",parentName);
}
}
else
{
@ -250,7 +265,7 @@ public class Modules implements Iterable<Module>
}
}
public void enable(String name, List<String> sources)
public void enable(String name, List<String> sources) throws IOException
{
if (name.contains("*"))
{
@ -276,14 +291,47 @@ public class Modules implements Iterable<Module>
}
}
private void enableModule(Module module, List<String> sources)
private void enableModule(Module module, List<String> sources) throws IOException
{
if (module.isEnabled())
{
// already enabled, skip
return;
}
StartLog.debug("Enabling module: %s (via %s)",module.getName(),Main.join(sources,", "));
module.setEnabled(true);
args.parseModule(module);
module.expandProperties(args.getProperties());
if (sources != null)
{
module.addSources(sources);
}
// enable any parents that haven't been enabled (yet)
for(String name: module.getParentNames())
{
Module parent = modules.get(name);
if (name == null)
{
// parent module doesn't exist, yet
Path file = baseHome.getPath("modules/" + name + ".mod");
if (FS.canReadFile(file))
{
parent = registerModule(file);
updateParentReferencesTo(parent);
}
else
{
StartLog.debug("Missing module definition: [ Mod: %s | File: %s ]",name,file);
missingModules.add(name);
}
}
if (parent != null)
{
enableModule(parent,sources);
}
}
}
private void findChildren(Module module, Set<Module> ret)
@ -372,32 +420,35 @@ public class Modules implements Iterable<Module>
return module;
}
public void registerParentsIfMissing(BaseHome basehome, StartArgs args, Module module) throws IOException
public void registerParentsIfMissing(Module module) throws IOException
{
Set<String> parents = new HashSet<>(module.getParentNames());
for (String name : parents)
{
if (!modules.containsKey(name))
{
Path file = basehome.getPath("modules/" + name + ".mod");
Path file = baseHome.getPath("modules/" + name + ".mod");
if (FS.canReadFile(file))
{
Module parent = registerModule(basehome,args,file);
Module parent = registerModule(file);
updateParentReferencesTo(parent);
registerParentsIfMissing(basehome, args, parent);
registerParentsIfMissing(parent);
}
}
}
}
public void registerAll(BaseHome basehome, StartArgs args) throws IOException
public void registerAll() throws IOException
{
for (Path path : basehome.getPaths("modules/*.mod"))
for (Path path : baseHome.getPaths("modules/*.mod"))
{
registerModule(basehome,args,path);
registerModule(path);
}
}
// load missing post-expanded dependent modules
// load missing post-expanded dependent modules
private void normalizeDependencies() throws FileNotFoundException, IOException
{
boolean done = false;
while (!done)
{
@ -419,30 +470,29 @@ public class Modules implements Iterable<Module>
for (String missingParent : missingParents)
{
Path file = basehome.getPath("modules/" + missingParent + ".mod");
Path file = baseHome.getPath("modules/" + missingParent + ".mod");
if (FS.canReadFile(file))
{
Module module = registerModule(basehome,args,file);
Module module = registerModule(file);
updateParentReferencesTo(module);
}
else
{
StartLog.debug("Missing module definition: [ Mod: %s | File: %s]",missingParent,file);
StartLog.debug("Missing module definition: [ Mod: %s | File: %s ]",missingParent,file);
missingModules.add(missingParent);
}
}
}
}
private Module registerModule(BaseHome basehome, StartArgs args, Path file) throws FileNotFoundException, IOException
private Module registerModule(Path file) throws FileNotFoundException, IOException
{
if (!FS.canReadFile(file))
{
throw new IOException("Cannot read file: " + file);
}
StartLog.debug("Registering Module: %s",basehome.toShortForm(file));
Module module = new Module(basehome,file);
module.expandProperties(args.getProperties());
StartLog.debug("Registering Module: %s",baseHome.toShortForm(file));
Module module = new Module(baseHome,file);
return register(module);
}

View File

@ -61,6 +61,22 @@ public final class Props implements Iterable<Prop>
this(key,value,origin);
this.overrides = overrides;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("Prop [key=");
builder.append(key);
builder.append(", value=");
builder.append(value);
builder.append(", origin=");
builder.append(origin);
builder.append(", overrides=");
builder.append(overrides);
builder.append("]");
return builder.toString();
}
}
public static final String ORIGIN_SYSPROP = "<system-property>";

View File

@ -647,6 +647,18 @@ public class StartArgs
}
public void parse(final String rawarg, String source)
{
parse(rawarg,source,true);
}
/**
* Parse a single line of argument.
*
* @param rawarg the raw argument to parse
* @param source the origin of this line of argument
* @param replaceProps true if properties in this parse replace previous ones, false to not replace.
*/
private void parse(final String rawarg, String source, boolean replaceProps)
{
if (rawarg == null)
{
@ -810,11 +822,11 @@ public class StartArgs
{
case 2:
System.setProperty(assign[0],assign[1]);
setProperty(assign[0],assign[1],source);
setProperty(assign[0],assign[1],source,replaceProps);
break;
case 1:
System.setProperty(assign[0],"");
setProperty(assign[0],"",source);
setProperty(assign[0],"",source,replaceProps);
break;
default:
break;
@ -840,11 +852,14 @@ public class StartArgs
String key = arg.substring(0,idx);
String value = arg.substring(idx + 1);
if (propertySource.containsKey(key))
if (replaceProps)
{
StartLog.warn("Property %s in %s already set in %s",key,source,propertySource.get(key));
if (propertySource.containsKey(key))
{
StartLog.warn("Property %s in %s already set in %s",key,source,propertySource.get(key));
}
propertySource.put(key,source);
}
propertySource.put(key,source);
if ("OPTION".equals(key) || "OPTIONS".equals(key))
{
@ -857,7 +872,7 @@ public class StartArgs
StartLog.warn(warn.toString());
}
setProperty(key,value,source);
setProperty(key,value,source,replaceProps);
return;
}
@ -886,6 +901,17 @@ public class StartArgs
throw new UsageException(ERR_BAD_ARG,"Unrecognized argument: \"%s\" in %s",arg,source);
}
public void parseModule(Module module)
{
if(module.hasDefaultConfig())
{
for(String line: module.getDefaultConfig())
{
parse(line,module.getFilesystemRef(),false);
}
}
}
public void resolveExtraXmls(BaseHome baseHome) throws IOException
{
// Find and Expand XML files
@ -921,7 +947,7 @@ public class StartArgs
this.allModules = allModules;
}
private void setProperty(String key, String value, String source)
private void setProperty(String key, String value, String source, boolean replaceProp)
{
// Special / Prevent override from start.ini's
if (key.equals("jetty.home"))
@ -938,7 +964,19 @@ public class StartArgs
}
// Normal
properties.setProperty(key,value,source);
if (replaceProp)
{
// always override
properties.setProperty(key,value,source);
}
else
{
// only set if unset
if (!properties.containsKey(key))
{
properties.setProperty(key,value,source);
}
}
}
public void setRun(boolean run)
@ -961,4 +999,5 @@ public class StartArgs
builder.append("]");
return builder.toString();
}
}

View File

@ -160,7 +160,7 @@ public class ConfigurationAssert
return value;
}
private static void assertContainsUnordered(String msg, Collection<String> expectedSet, Collection<String> actualSet)
public static void assertContainsUnordered(String msg, Collection<String> expectedSet, Collection<String> actualSet)
{
// same size?
boolean mismatch = expectedSet.size() != actualSet.size();

View File

@ -60,8 +60,8 @@ public class ModuleGraphWriterTest
StartArgs args = new StartArgs();
args.parse(config);
Modules modules = new Modules();
modules.registerAll(basehome, args);
Modules modules = new Modules(basehome, args);
modules.registerAll();
modules.buildGraph();
Path outputFile = basehome.getBasePath("graph.dot");

View File

@ -66,8 +66,8 @@ public class ModulesTest
args.parse(config);
// Test Modules
Modules modules = new Modules();
modules.registerAll(basehome,args);
Modules modules = new Modules(basehome,args);
modules.registerAll();
List<String> moduleNames = new ArrayList<>();
for (Module mod : modules)
@ -80,11 +80,41 @@ public class ModulesTest
moduleNames.add(mod.getName());
}
String expected[] = { "jmx", "client", "stats", "spdy", "deploy", "debug", "security", "npn", "ext", "websocket", "rewrite", "ipaccess", "xinetd",
"proxy", "webapp", "jndi", "lowresources", "https", "plus", "requestlog", "jsp", "monitor", "xml", "servlet", "jaas", "http", "base", "server",
"annotations", "resources", "loggging" };
List<String> expected = new ArrayList<>();
expected.add("jmx");
expected.add("client");
expected.add("stats");
expected.add("spdy");
expected.add("deploy");
expected.add("debug");
expected.add("security");
expected.add("npn");
expected.add("ext");
expected.add("websocket");
expected.add("rewrite");
expected.add("ipaccess");
expected.add("xinetd");
expected.add("proxy");
expected.add("webapp");
expected.add("jndi");
expected.add("lowresources");
expected.add("https");
expected.add("plus");
expected.add("requestlog");
expected.add("jsp");
// (only present if enabled) expected.add("jsp-impl");
expected.add("monitor");
expected.add("xml");
expected.add("servlet");
expected.add("jaas");
expected.add("http");
expected.add("base");
expected.add("server");
expected.add("annotations");
expected.add("resources");
expected.add("logging");
Assert.assertThat("Module count: " + moduleNames,moduleNames.size(),is(expected.length));
ConfigurationAssert.assertContainsUnordered("All Modules",expected,moduleNames);
}
@Test
@ -93,7 +123,7 @@ public class ModulesTest
// Test Env
File homeDir = MavenTestingUtils.getTestResourceDir("usecases/home");
File baseDir = testdir.getEmptyDir();
String cmdLine[] = new String[] {"jetty.version=TEST"};
String cmdLine[] = new String[] {"jetty.version=TEST", "java.version=1.7.0_21"};
// Configuration
CommandLineConfigSource cmdLineSource = new CommandLineConfigSource(cmdLine);
@ -109,13 +139,35 @@ public class ModulesTest
args.parse(config);
// Test Modules
Modules modules = new Modules();
modules.registerAll(basehome,args);
Modules modules = new Modules(basehome,args);
modules.registerAll();
modules.enable("[sj]{1}.*",TEST_SOURCE);
modules.buildGraph();
String expected[] = { "jmx", "stats", "spdy", "security", "jndi", "jsp", "servlet", "jaas", "server" };
List<String> expected = new ArrayList<>();
expected.add("jmx");
expected.add("stats");
expected.add("spdy");
expected.add("security");
expected.add("jndi");
expected.add("jsp");
expected.add("servlet");
expected.add("jaas");
expected.add("server");
// transitive
expected.add("base");
expected.add("npn");
expected.add("npn-boot");
expected.add("xml");
expected.add("jsp-impl");
Assert.assertThat("Enabled Module count",modules.resolveEnabled().size(),is(expected.length));
List<String> resolved = new ArrayList<>();
for (Module module : modules.resolveEnabled())
{
resolved.add(module.getName());
}
ConfigurationAssert.assertContainsUnordered("Enabled Modules",expected,resolved);
}
@Test
@ -140,14 +192,15 @@ public class ModulesTest
args.parse(config);
// Test Modules
Modules modules = new Modules();
modules.registerAll(basehome,args);
modules.buildGraph();
Modules modules = new Modules(basehome, args);
modules.registerAll();
// Enable 2 modules
modules.enable("server",TEST_SOURCE);
modules.enable("http",TEST_SOURCE);
modules.buildGraph();
// Collect active module list
List<Module> active = modules.resolveEnabled();
@ -211,15 +264,16 @@ public class ModulesTest
args.parse(config);
// Test Modules
Modules modules = new Modules();
modules.registerAll(basehome,args);
modules.buildGraph();
// modules.dump();
Modules modules = new Modules(basehome,args);
modules.registerAll();
// Enable 2 modules
modules.enable("websocket",TEST_SOURCE);
modules.enable("http",TEST_SOURCE);
modules.buildGraph();
// modules.dump();
// Collect active module list
List<Module> active = modules.resolveEnabled();

View File

@ -0,0 +1,10 @@
#
# Apache JSP Module
#
[name]
jsp-impl
[lib]
lib/apache-jsp/*.jar

View File

@ -0,0 +1,8 @@
#
# Glassfish JSP Module
#
[name]
jsp-impl
[lib]
lib/jsp/*.jar

View File

@ -1,10 +1,20 @@
#
# Jetty Servlet Module
# Jetty JSP Module
#
[depend]
servlet
jsp-impl/${jsp-impl}-jsp
[lib]
lib/jsp/*.jar
[ini-template]
# JSP Configuration
# Select JSP implementation, choices are
# glassfish : The reference implementation
# default in jetty <= 9.1
# apache : The apache version
# default jetty >= 9.2
jsp-impl=apache
# To use a non-jdk compiler for JSP compilation when using glassfish uncomment next line
# -Dorg.apache.jasper.compiler.disablejsr199=true