From: Mathieu Baudier Date: Sat, 21 Jun 2008 15:29:23 +0000 (+0000) Subject: Integrate Slc Execution notification in the new runtime X-Git-Tag: argeo-slc-2.1.7~2774 X-Git-Url: http://git.argeo.org/?a=commitdiff_plain;h=5ac335634ca09f980e452051dd41bc1ce1ea8c16;p=gpl%2Fargeo-slc.git Integrate Slc Execution notification in the new runtime git-svn-id: https://svn.argeo.org/slc/trunk@1268 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntRunner.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntRunner.java index 09de703d8..5ce4b53b7 100644 --- a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntRunner.java +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntRunner.java @@ -11,6 +11,7 @@ import org.apache.tools.ant.Project; import org.apache.tools.ant.ProjectHelper; import org.springframework.context.ApplicationContext; +/** @deprecated */ public class AntRunner { private ApplicationContext context; private ProjectHelper projectHelper; diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntSlcApplication.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntSlcApplication.java index 68c7f18de..8771c0d99 100644 --- a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntSlcApplication.java +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntSlcApplication.java @@ -12,6 +12,10 @@ import java.util.Vector; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.log4j.Appender; +import org.apache.log4j.LogManager; +import org.apache.log4j.MDC; +import org.apache.tools.ant.BuildListener; import org.apache.tools.ant.Project; import org.apache.tools.ant.ProjectHelper; import org.apache.tools.ant.helper.ProjectHelper2; @@ -25,6 +29,7 @@ import org.argeo.slc.core.structure.tree.TreeSRegistry; import org.argeo.slc.logging.Log4jUtils; import org.argeo.slc.runtime.SlcExecutionContext; import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.context.ApplicationContext; @@ -41,7 +46,7 @@ public class AntSlcApplication { private final static Log log = LogFactory.getLog(AntSlcApplication.class); private Resource contextLocation; - private ApplicationContext runtimeContext; + private ApplicationContext parentContext; private Resource rootDir; private Resource confDir; @@ -63,8 +68,7 @@ public class AntSlcApplication { } // Spring initialization - initRuntimeContext(slcExecution); - ConfigurableApplicationContext ctx = createExecutionContext(); + ConfigurableApplicationContext ctx = createExecutionContext(slcExecution); // Ant coordinates Resource script = findAntScript(slcExecution); @@ -142,66 +146,48 @@ public class AntSlcApplication { } } - protected void initRuntimeContext(SlcExecution slcExecution) { - if (runtimeContext == null) { + protected ConfigurableApplicationContext createExecutionContext( + SlcExecution slcExecution) { + try { + + // Find runtime definition Resource runtimeRes = null; String runtimeStr = slcExecution.getAttributes().get( SlcAntConstants.EXECATTR_RUNTIME); if (runtimeStr != null) { + ResourceLoader rl = new DefaultResourceLoader(getClass() + .getClassLoader()); try { - ResourceLoader rl = new DefaultResourceLoader(getClass() - .getClassLoader()); - try { - runtimeRes = rl.getResource(runtimeStr); - } catch (Exception e) { - // silent - } - if (runtimeRes == null || !runtimeRes.exists()) { - runtimeRes = confDir.createRelative("runtime/" - + runtimeStr + ".xml"); - } - - if (runtimeRes.exists()) { - GenericApplicationContext ctx = new GenericApplicationContext(); - XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader( - ctx); - xmlReader.loadBeanDefinitions(runtimeRes); - - // Add property place holder - PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer(); - ppc.setIgnoreUnresolvablePlaceholders(true); - ctx.addBeanFactoryPostProcessor(ppc); - - ctx.refresh(); - - runtimeContext = ctx; - } + runtimeRes = rl.getResource(runtimeStr); } catch (Exception e) { - throw new SlcException( - "Could not initialize runtime context from " - + runtimeStr, e); + // silent + } + if (runtimeRes == null || !runtimeRes.exists()) { + runtimeRes = confDir.createRelative("runtime/" + runtimeStr + + ".xml"); } } - if (runtimeContext == null) - log.warn("No runtime is defined."); - } - } - - protected ConfigurableApplicationContext createExecutionContext() { - try { + // Find runtime independent application context definition if (confDir != null && contextLocation == null) { contextLocation = confDir .createRelative("applicationContext.xml"); } GenericApplicationContext ctx = new GenericApplicationContext( - runtimeContext); - if (contextLocation != null && contextLocation.exists()) { - XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader( - ctx); + parentContext); + ctx.setDisplayName("SLC Execution #" + slcExecution.getUuid()); + + XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(ctx); + if (runtimeRes != null && runtimeRes.exists()) + xmlReader.loadBeanDefinitions(runtimeRes); + else + log.warn("No runtime context defined"); + + if (contextLocation != null && contextLocation.exists()) xmlReader.loadBeanDefinitions(contextLocation); - } + else + log.warn("No runtime independent application context defined"); // Add property place holder PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer(); @@ -258,6 +244,24 @@ public class AntSlcApplication { } project.addBuildListener(new CommonsLoggingListener()); + + ListableBeanFactory context = (ListableBeanFactory) project + .getReference(SlcAntConstants.REF_ROOT_CONTEXT); + // Register build listeners + Map listeners = context.getBeansOfType( + BuildListener.class, false, true); + for (BuildListener listener : listeners.values()) { + project.addBuildListener(listener); + } + + // Register log4j appenders from context + MDC.put(SlcAntConstants.MDC_ANT_PROJECT, project); + Map appenders = context.getBeansOfType( + Appender.class, false, true); + for (Appender appender : appenders.values()) { + LogManager.getRootLogger().addAppender(appender); + } + project.init(); addCustomTaskAndTypes(project); } @@ -402,8 +406,8 @@ public class AntSlcApplication { this.workDir = workDir; } - public void setRuntimeContext(ApplicationContext runtimeContext) { - this.runtimeContext = runtimeContext; + public void setParentContext(ApplicationContext runtimeContext) { + this.parentContext = runtimeContext; } } diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/BasicSlcProjectHelper.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/BasicSlcProjectHelper.java index ef50f0555..7a797d613 100644 --- a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/BasicSlcProjectHelper.java +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/BasicSlcProjectHelper.java @@ -10,6 +10,7 @@ import org.argeo.slc.core.structure.SimpleSElement; import org.argeo.slc.core.structure.tree.TreeSPath; import org.argeo.slc.core.structure.tree.TreeSRegistry; +/** @deprecated */ public class BasicSlcProjectHelper extends ProjectHelper2 { private ApplicationContext context; diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/ProjectRelatedBuildListener.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/ProjectRelatedBuildListener.java index 48c8394c6..f6077b39b 100644 --- a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/ProjectRelatedBuildListener.java +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/ProjectRelatedBuildListener.java @@ -3,6 +3,7 @@ package org.argeo.slc.ant; import org.apache.tools.ant.BuildListener; import org.apache.tools.ant.Project; +/** @deprecated */ public interface ProjectRelatedBuildListener extends BuildListener { public Project getProject(); diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcAntConstants.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcAntConstants.java index 2215af77d..3c798cacb 100644 --- a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcAntConstants.java +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcAntConstants.java @@ -1,7 +1,7 @@ package org.argeo.slc.ant; public interface SlcAntConstants { - + // ANT /** The Ant reference to the Spring application context used. */ public static final String REF_ROOT_CONTEXT = "slcApplicationContext"; /** The Ant reference to the SLC structure registry used. */ @@ -18,13 +18,17 @@ public interface SlcAntConstants { * /org/argeo/slc/ant/typedefs.properties */ public static final String SLC_TYPEDEFS_RESOURCE_PATH = "/org/argeo/slc/ant/typedefs.properties"; + public static final String REF_SLC_EXECUTION = "slcExecution"; + + // SLC EXECUTION public static final String EXECTYPE_ANT = "org.apache.tools.ant"; public static final String EXECTYPE_SLC_ANT = "org.argeo.slc.ant"; - public static final String REF_SLC_EXECUTION = "slcExecution"; public final static String EXECATTR_RUNTIME = "slc.runtime"; public final static String EXECATTR_ANT_FILE = "ant.file"; public final static String EXECATTR_ANT_TARGETS = "ant.targets"; + + // PROPERTIES /** Property for the root dir (SLC root property file). */ public final static String ROOT_DIR_PROPERTY = "slc.rootDir"; /** Property for the conf dir (SLC root property file). */ @@ -34,4 +38,7 @@ public interface SlcAntConstants { /** Name of the Spring bean used by default */ public final static String DEFAULT_TEST_RUN_PROPERTY = "slc.defaultTestRun"; + // LOG4J + public final static String MDC_ANT_PROJECT = "slc.ant.project"; + } diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcExecutionBuildListener.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcExecutionBuildListener.java index f39b79baa..2b9400e4b 100644 --- a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcExecutionBuildListener.java +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcExecutionBuildListener.java @@ -4,55 +4,47 @@ import java.util.List; import java.util.Vector; import org.apache.log4j.AppenderSkeleton; +import org.apache.log4j.Level; import org.apache.log4j.LogManager; +import org.apache.log4j.MDC; +import org.apache.log4j.Priority; import org.apache.log4j.spi.LoggingEvent; import org.apache.tools.ant.BuildEvent; +import org.apache.tools.ant.BuildListener; import org.apache.tools.ant.Project; +import org.argeo.slc.core.SlcException; import org.argeo.slc.core.process.SlcExecution; import org.argeo.slc.core.process.SlcExecutionNotifier; import org.argeo.slc.core.process.SlcExecutionStep; import org.argeo.slc.ws.process.WebServiceSlcExecutionNotifier; public class SlcExecutionBuildListener extends AppenderSkeleton implements - ProjectRelatedBuildListener { - private Project project; - - // to avoid stack overflow when logging for log4j - private boolean isLogging = false; - + BuildListener { private List notifiers = new Vector(); private boolean currentStepNotified = true; // CUSTOMIZATIONS + /** + * Whether to log Ant initialization stuff before the first target has been + * called. + */ private boolean logBeforeFirstTarget = false; + /** Whether the first target has been called. */ private boolean firstTargetStarted = false; private boolean logTaskStartFinish = true; - public void init(Project project) { - if (this.project != null) { - throw new SlcAntException("Build listener already initialized"); - } - - this.project = project; - - if (!LogManager.getRootLogger().isAttached(this)) { - LogManager.getRootLogger().addAppender(this); - } - - SlcExecution slcExecution = (SlcExecution) project - .getReference(SlcAntConstants.REF_SLC_EXECUTION); - if (slcExecution == null) - throw new SlcAntException("No SLC Execution registered."); + public SlcExecutionBuildListener() { + // Default log level + setThreshold(Level.INFO); + } + public void buildStarted(BuildEvent event) { + SlcExecution slcExecution = getSlcExecution(event); for (SlcExecutionNotifier notifier : notifiers) { notifier.newExecution(slcExecution); } - - } - - public void buildStarted(BuildEvent event) { } public void buildFinished(BuildEvent event) { @@ -64,11 +56,6 @@ public class SlcExecutionBuildListener extends AppenderSkeleton implements notifier.updateStatus(slcExecution, oldStatus, slcExecution .getStatus()); } - -// AbstractApplicationContext context = (AbstractApplicationContext) getProject() -// .getReference(SlcProjectHelper.REF_ROOT_CONTEXT); -// if (context != null) -// context.close(); } public void messageLogged(BuildEvent event) { @@ -141,11 +128,10 @@ public class SlcExecutionBuildListener extends AppenderSkeleton implements } protected SlcExecution getSlcExecution(BuildEvent event) { - Project projectEvt = event.getProject(); - if (!projectEvt.equals(project)) - throw new SlcAntException("Event project " + projectEvt - + " not consistent with listener project " + project); + return getSlcExecution(event.getProject()); + } + protected SlcExecution getSlcExecution(Project project) { SlcExecution slcExecution = (SlcExecution) project .getReference(SlcAntConstants.REF_SLC_EXECUTION); @@ -179,38 +165,18 @@ public class SlcExecutionBuildListener extends AppenderSkeleton implements @Override protected void append(LoggingEvent event) { - if (isLogging) { - // avoid StackOverflow if notification calls Log4j itself. - return; - } - - // FIXME: make it more generic - if (event.getLoggerName().equals( - WebServiceSlcExecutionNotifier.class.getName())) { - return; - } - - isLogging = true; - - try { - SlcExecution slcExecution = (SlcExecution) project - .getReference(SlcAntConstants.REF_SLC_EXECUTION); - if (slcExecution != null) { - if (currentStepNotified) { - slcExecution.getSteps().add( - new SlcExecutionStep("LOG", event.getMessage() - .toString())); - currentStepNotified = false; - } - slcExecution.currentStep() - .addLog(event.getMessage().toString()); - } else { - // TODO: log before initialization? - } - } finally { - isLogging = false; + Project project = (Project) MDC.get(SlcAntConstants.MDC_ANT_PROJECT); + if (project == null) + throw new SlcException("No Ant project registered in Log4j MDC."); + + SlcExecution slcExecution = getSlcExecution(project); + if (currentStepNotified) { + slcExecution.getSteps().add( + new SlcExecutionStep("LOG", event.getMessage().toString())); + currentStepNotified = false; + } else { + slcExecution.currentStep().addLog(event.getMessage().toString()); } - } protected boolean shouldLog() { @@ -226,8 +192,16 @@ public class SlcExecutionBuildListener extends AppenderSkeleton implements return false; } - public Project getProject() { - return project; + public void setLogBeforeFirstTarget(boolean logBeforeFirstTarget) { + this.logBeforeFirstTarget = logBeforeFirstTarget; + } + + public void setLogTaskStartFinish(boolean logTaskStartFinish) { + this.logTaskStartFinish = logTaskStartFinish; + } + + public void setLogLevel(String logLevel) { + setThreshold(Level.toLevel(logLevel)); } } diff --git a/org.argeo.slc.agent/src/test/java/org/argeo/slc/ant/SlcAntTest.java b/org.argeo.slc.agent/src/test/java/org/argeo/slc/ant/SlcAntTest.java index f58b8133d..214bafc9e 100644 --- a/org.argeo.slc.agent/src/test/java/org/argeo/slc/ant/SlcAntTest.java +++ b/org.argeo.slc.agent/src/test/java/org/argeo/slc/ant/SlcAntTest.java @@ -15,7 +15,7 @@ public class SlcAntTest extends AbstractSpringTestCase { .getAbsolutePath() + File.separator)); slcApp.setWorkDir(new File(System.getProperty("java.io.tmpdir"))); - slcApp.setRuntimeContext(getContext()); + slcApp.setParentContext(getContext()); SlcExecution slcExecution = new SlcExecution(); slcExecution.getAttributes().put(SlcAntConstants.EXECATTR_ANT_FILE,