annotate agent/src/jetbrains/buildServer/symbols/SymbolsIndexer.java @ 2:c6ca0a26d93e

initial implementation of agent-side symbol indexer
author Evgeniy.Koshkin
date Thu, 18 Jul 2013 15:34:28 +0400
parents
children 53028ba390e0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
1 package jetbrains.buildServer.symbols;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
2
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
3 import com.intellij.execution.configurations.GeneralCommandLine;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
4 import jetbrains.buildServer.ExecResult;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
5 import jetbrains.buildServer.SimpleCommandLineProcessRunner;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
6 import jetbrains.buildServer.agent.AgentLifeCycleAdapter;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
7 import jetbrains.buildServer.agent.AgentLifeCycleListener;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
8 import jetbrains.buildServer.agent.AgentRunningBuild;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
9 import jetbrains.buildServer.agent.BuildFinishedStatus;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
10 import jetbrains.buildServer.agent.artifacts.ArtifactsWatcher;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
11 import jetbrains.buildServer.agent.impl.artifacts.ArtifactsBuilderAdapter;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
12 import jetbrains.buildServer.agent.impl.artifacts.ArtifactsCollection;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
13 import jetbrains.buildServer.agent.plugins.beans.PluginDescriptor;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
14 import jetbrains.buildServer.util.EventDispatcher;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
15 import jetbrains.buildServer.util.FileUtil;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
16 import org.apache.log4j.Logger;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
17 import org.jetbrains.annotations.NotNull;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
18 import org.jetbrains.annotations.Nullable;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
19
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
20 import java.io.File;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
21 import java.io.IOException;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
22 import java.util.*;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
23
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
24 /**
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
25 * @author Evgeniy.Koshkin
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
26 */
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
27 public class SymbolsIndexer extends ArtifactsBuilderAdapter {
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
28
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
29 public static final Logger LOG = Logger.getLogger(SymbolsIndexer.class);
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
30
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
31 public static final String PDB_FILE_EXTENSION = "pdb";
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
32 public static final String EXE_FILE_EXTENSION = "exe";
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
33 public static final String DLL_FILE_EXTENSION = "dll";
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
34
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
35 public static final String SYMBOLS_EXE = "symbols.exe";
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
36 public static final String DUMP_SYMBOL_SIGN_CMD = "dumpSymbolSign";
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
37 public static final String DUMP_BIN_SIGN_CMD = "dumpBinSign";
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
38
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
39 @NotNull private final ArtifactsWatcher myArtifactsWatcher;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
40 @NotNull private final File myNativeToolPath;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
41 @Nullable private AgentRunningBuild myBuild;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
42 @Nullable private Collection<File> myBinariesToProcess;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
43 @Nullable private Collection<File> mySymbolsToProcess;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
44
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
45 public SymbolsIndexer(@NotNull final PluginDescriptor pluginDescriptor, @NotNull final EventDispatcher<AgentLifeCycleListener> agentDispatcher, @NotNull final ArtifactsWatcher artifactsWatcher) {
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
46 myNativeToolPath = new File(new File(pluginDescriptor.getPluginRoot(), "bin"), SYMBOLS_EXE);
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
47 myArtifactsWatcher = artifactsWatcher;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
48 agentDispatcher.addListener(new AgentLifeCycleAdapter() {
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
49 @Override
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
50 public void buildStarted(@NotNull final AgentRunningBuild runningBuild) {
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
51 myBuild = runningBuild;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
52 myBinariesToProcess = new HashSet<File>();
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
53 mySymbolsToProcess = new HashSet<File>();
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
54 }
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
55
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
56 @Override
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
57 public void beforeBuildFinish(@NotNull AgentRunningBuild build, @NotNull BuildFinishedStatus buildStatus) {
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
58 super.beforeBuildFinish(build, buildStatus);
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
59 if (myBuild == null || mySymbolsToProcess == null || myBinariesToProcess == null) return;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
60 if (mySymbolsToProcess.isEmpty()) {
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
61 LOG.debug("Symbols weren't found in artifacts to be published.");
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
62 } else {
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
63 final File targetDir = myBuild.getBuildTempDirectory();
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
64 try {
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
65 final File symbolSignaturesFile = dumpSymbolSignatures(mySymbolsToProcess, targetDir);
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
66 myArtifactsWatcher.addNewArtifactsPath(symbolSignaturesFile + "=>" + ".teamcity/symbols/symbol-signatures.xml");
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
67 final File binariesSignaturesFile = dumpBinarySignatures(myBinariesToProcess, targetDir);
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
68 myArtifactsWatcher.addNewArtifactsPath(binariesSignaturesFile + "=>" + ".teamcity/symbols/binary-signatures.xml");
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
69 } catch (IOException e) {
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
70 LOG.error("Error while dumping symbols/binaries signatures.", e);
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
71 }
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
72 }
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
73 mySymbolsToProcess = null;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
74 myBinariesToProcess = null;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
75 myBuild = null;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
76 }
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
77 });
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
78 }
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
79
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
80 @Override
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
81 public void afterCollectingFiles(@NotNull List<ArtifactsCollection> artifacts) {
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
82 super.afterCollectingFiles(artifacts);
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
83 if(myBuild == null || mySymbolsToProcess == null || myBinariesToProcess == null) return;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
84 if(myBuild.getBuildFeaturesOfType(SymbolsConstants.BUILD_FEATURE_TYPE).isEmpty()){
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
85 LOG.debug(SymbolsConstants.BUILD_FEATURE_TYPE + " build feature disabled. No indexing performed.");
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
86 return;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
87 }
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
88 LOG.debug(SymbolsConstants.BUILD_FEATURE_TYPE + " build feature enabled. Searching for symbol files.");
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
89 mySymbolsToProcess.addAll(getArtifactPathsByFileExtension(artifacts, PDB_FILE_EXTENSION));
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
90 myBinariesToProcess.addAll(getArtifactPathsByFileExtension(artifacts, EXE_FILE_EXTENSION));
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
91 myBinariesToProcess.addAll(getArtifactPathsByFileExtension(artifacts, DLL_FILE_EXTENSION));
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
92 }
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
93
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
94 private Collection<File> getArtifactPathsByFileExtension(List<ArtifactsCollection> artifactsCollections, String fileExtension){
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
95 final Collection<File> result = new HashSet<File>();
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
96 for(ArtifactsCollection artifactsCollection : artifactsCollections){
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
97 if(artifactsCollection.isEmpty()) continue;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
98 for (File artifact : artifactsCollection.getFilePathMap().keySet()){
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
99 if(FileUtil.getExtension(artifact.getPath()).equalsIgnoreCase(fileExtension))
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
100 result.add(artifact);
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
101 }
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
102 }
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
103 return result;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
104 }
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
105
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
106 private File dumpSymbolSignatures(Collection<File> files, File targetDir) throws IOException {
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
107 final File tempFile = FileUtil.createTempFile(targetDir, "symbol-signatures-", ".xml", false);
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
108 runTool(DUMP_SYMBOL_SIGN_CMD, files, tempFile);
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
109 return tempFile;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
110 }
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
111
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
112 private File dumpBinarySignatures(Collection<File> files, File targetDir) throws IOException {
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
113 final File tempFile = FileUtil.createTempFile(targetDir, "binary-signatures-", ".xml", false);
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
114 runTool(DUMP_BIN_SIGN_CMD, files, tempFile);
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
115 return tempFile;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
116 }
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
117
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
118 private void runTool(String cmd, Collection<File> files, File output){
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
119 final GeneralCommandLine commandLine = new GeneralCommandLine();
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
120 commandLine.setExePath(myNativeToolPath.getPath());
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
121 commandLine.addParameter(cmd);
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
122 commandLine.addParameter(String.format("/o=\"%s\"", output.getPath()));
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
123 for(File file : files){
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
124 commandLine.addParameter(file.getPath());
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
125 }
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
126 final ExecResult execResult = SimpleCommandLineProcessRunner.runCommand(commandLine, null);
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
127 if (execResult.getExitCode() == 0) return;
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
128 LOG.warn(String.format("%s ends with non-zero exit code.", SYMBOLS_EXE));
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
129 }
c6ca0a26d93e initial implementation of agent-side symbol indexer
Evgeniy.Koshkin
parents:
diff changeset
130 }