QuickBuild2 Documentation
|
Store build related dataPlugin might need to have a place on server to store build related data. For example, JUnit plugin stores processed JUnit test data for each build into the build storage area after JUnit publish step runs, and use that data to render JUnit report upon UI access. Normally this place is a directory choosed by plugins under the Build Publish Directory, and files can be stored into the place by calling publish method of the build object. package com.example.myplugin; import java.io.File; import org.hibernate.validator.NotEmpty; import com.pmease.quickbuild.annotation.Editable; import com.pmease.quickbuild.annotation.Scriptable; import com.pmease.quickbuild.stepsupport.Step; import com.pmease.quickbuild.util.FileUtils; import com.pmease.quickbuild.Context; @Editable(category="examples", name="publish message", description= "This step publishes an user defined message and render them on build overview screen.") public class MyAnotherStep extends Step { private static final long serialVersionUID = 1L; private String message; @Editable @NotEmpty @Scriptable public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } @Override public void run() { File tempDir = FileUtils.createTempDir(); FileUtils.writeFile(new File(tempDir, "message.txt"), getMessage()); try { // call publish to transfer files to server node. Do not simply // copy files here since the step might be running on an agent // node. Context.getBuild().publish(tempDir.getAbsolutePath(), null, "myplugin"); } finally { FileUtils.deleteDir(tempDir); } } } And then modify MyPanel.java like below to render the message in published file. package com.example.myplugin; import java.io.File; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.panel.Panel; import com.pmease.quickbuild.Context; import com.pmease.quickbuild.util.FileUtils; public class MyPanel extends Panel { private static final long serialVersionUID = 1L; public MyPanel(String id) { super(id); String message = FileUtils.readFileAsString( new File(Context.getBuild().getPublishDir(), "myplugin/message.txt")); add(new Label("message", message)); } } Finally modify MyPlugin.java to contribute the message panel only when sub directory myplugin exists. package com.example.myplugin; import java.io.File; import java.util.ArrayList; import java.util.List; import org.apache.wicket.markup.html.panel.Panel; import com.pmease.quickbuild.extensionpoint.BuildDashboardContribution; import com.pmease.quickbuild.extensionpoint.StepProvider; import com.pmease.quickbuild.extensionpoint.support.PanelCreator; import com.pmease.quickbuild.pluginsupport.AbstractPlugin; import com.pmease.quickbuild.stepsupport.Step; import com.pmease.quickbuild.Context; public class MyPlugin extends AbstractPlugin { @Override public Object[] getExtensions() { return new Object[] { new StepProvider() { @Override public Class<? extends Step> getStepClass() { return MyStep.class; } }, new StepProvider() { @Override public Class<? extends Step> getStepClass() { return MyAnotherStep.class; } }, new BuildDashboardContribution() { public List<PanelCreator> getPanelCreators() { List<PanelCreator> creators = new ArrayList<PanelCreator>(); if (new File(Context.getBuild().getPublishDir(), "myplugin").exists()) { creators.add(new PanelCreator() { public Panel getPanel(String id) { return new MyPanel(id); } }); } return creators; } public int getOrder() { return 500; } } }; } } Now start QuickBuild, and run the root configuration. You will see the published message file under directory <global storage directory>/builds/<build id>/myplugin, where <global storage directory> is the directory you specified when set up QuickBuild server, and <build id> refers to id of the newly generated build and is displayed at the build overview screen. Store configuration related dataBesides storing build related data, plugin may also need to store configuation related data to server. Still taking the JUnit plugin for example, it accumulates test statistics information for a configuration overtime and use it to render JUnit statistics chart upon UI access. The Configuration Publish Directory is a good place to store such data, and plugins can create sub directories under this place to hold their own data if necessary. package com.example.myplugin; import java.util.LinkedHashMap; import java.util.Map; public class MyStatistics { // map build version to message length private Map<String, Integer> msgLens = new LinkedHashMap<String, Integer>(); public Map<String, Integer> getMsgLens() { return msgLens; } public void setMsgLens(Map<String, Integer> msgLens) { this.msgLens = msgLens; } } And add a new class MyMetricsCollector.java as below to collect message char count for current build and update the statistics data: package com.example.myplugin; import java.io.File; import com.pmease.quickbuild.extensionpoint.BuildMetricsCollector; import com.pmease.quickbuild.model.Build; import com.pmease.quickbuild.util.BeanUtils; import com.pmease.quickbuild.util.FileUtils; import com.pmease.quickbuild.Context; public class MyMetricsCollector implements BuildMetricsCollector { public void collectMetrics() { /* * This method will be called from server after build finishes. So we can * access the message file and statistics file directly. */ Build build = Context.getBuild(); File msgFile = new File(build.getPublishDir(), "myplugin/message.txt"); // collect metrics only if message publishing step was executed for this build. if (msgFile.exists()) { int msgLen = FileUtils.readFileAsString(msgFile).length(); File statsFile = new File(build.getConfiguration().getPublishDir(), "myplugin/statistics.xml"); MyStatistics stats; if (statsFile.exists()) stats = (MyStatistics) BeanUtils.readFile(statsFile); else stats = new MyStatistics(); stats.getMsgLens().put(build.getVersion(), msgLen); BeanUtils.writeFile(stats, statsFile); } } } Then add MyStatisticsPanel.java and MyStatisticsPanel.html to draw the chart using statistics data.
Finally modify MyPlugin.java to implement extension point BuildMetricsCollector and StatisticsTabContribution: package com.example.myplugin; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.wicket.markup.html.panel.Panel; import com.pmease.quickbuild.extensionpoint.BuildDashboardContribution; import com.pmease.quickbuild.extensionpoint.StatisticsTabContribution; import com.pmease.quickbuild.extensionpoint.StepProvider; import com.pmease.quickbuild.extensionpoint.support.PanelCreator; import com.pmease.quickbuild.pluginsupport.AbstractPlugin; import com.pmease.quickbuild.stepsupport.Step; import com.pmease.quickbuild.web.component.tabbedpanel.Tab; import com.pmease.quickbuild.Context; public class MyPlugin extends AbstractPlugin { @Override public Object[] getExtensions() { return new Object[] { new StepProvider() { @Override public Class<? extends Step> getStepClass() { return MyStep.class; } }, new StepProvider() { @Override public Class<? extends Step> getStepClass() { return MyAnotherStep.class; } }, new BuildDashboardContribution() { public List<PanelCreator> getPanelCreators() { List<PanelCreator> creators = new ArrayList<PanelCreator>(); if (new File(Context.getBuild().getPublishDir(), "myplugin").exists()) { creators.add(new PanelProvider() { public Panel getPanel(String id) { return new MyPanel(id); } }); } return creators; } public int getOrder() { return 500; } }, new MyMetricsCollector(), new StatisticsTabContribution() { public List<Tab> getTabs() { List<Tab> tabs = new ArrayList<Tab>(); if (new File(Context.getConfiguration().getPublishDir(), "myplugin").exists()) { tabs.add(new Tab("message char count") { private static final long serialVersionUID = 1L; @Override public Panel getPanel(String id, Map<String, String> params) { return new MyStatisticsPanel(id); } }); } return tabs; } public int getOrder() { return 500; } } }; } } Save modifications, start QuickBuild, and run the root configuation several times (remember to change the message length a little bit before each run to make the line chart varies). Switch to statistics tab of the root configuration, and you will see the "message char count" tab displaying statistics chart of number of message chars. |