Eclipseplugins
DbAndBinaryOperation.java
1 package com.proalpha.pds.gitutils.external;
2 
3 import java.io.BufferedReader;
4 import java.io.File;
5 import java.io.IOException;
6 import java.io.InputStreamReader;
7 import java.io.Reader;
8 import java.lang.ProcessBuilder.Redirect;
9 import java.lang.reflect.InvocationTargetException;
10 import java.nio.file.Files;
11 import java.nio.file.Path;
12 import java.nio.file.Paths;
13 import java.text.MessageFormat;
14 import java.util.ArrayList;
15 import java.util.List;
16 
17 import org.apache.commons.lang.StringUtils;
18 import org.eclipse.core.runtime.SubMonitor;
19 import org.eclipse.jgit.lib.Repository;
20 import org.eclipse.swt.custom.BusyIndicator;
21 import org.eclipse.swt.widgets.Display;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24 
25 import com.proalpha.pds.gitutils.Activator;
26 import com.proalpha.pds.gitutils.mylyn.ActionResult;
27 import com.proalpha.pds.gitutils.mylyn.ReconcileActionSettings;
28 
37 public class DbAndBinaryOperation {
38 
39  private final Logger logger = LoggerFactory.getLogger(DbAndBinaryOperation.class);
40 
41  private Repository repository;
42  private ReconcileActionSettings recoActionSettings;
43  private List<ActionResult> actionResults = new ArrayList<>();
44  private SubMonitor monitor;
45 
51  public DbAndBinaryOperation(Repository repository, ReconcileActionSettings recoSettings) {
52  this.repository = repository;
53  this.recoActionSettings = recoSettings;
54  }
55 
63  public void execute() {
64  Runnable runnable = new Runnable() {
65 
66  @Override
67  public void run() {
68  ArrayList<String> stages = (ArrayList<String>) recoActionSettings.getPaUpdateStages();
69  monitor.setWorkRemaining(stages.size());
70  String gitDir = repository.getDirectory().getAbsolutePath();
71  File parentDir = new File(gitDir.substring(0, gitDir.lastIndexOf(File.separator)));
72 
73  try {
74  for (String stage : stages) {
75  monitor.setTaskName("Running action: " + stage);
76  runPaUpdateStage(parentDir, stage, monitor.newChild(1));
77  }
78  } catch (Exception e) {
79  runPaUpdateStage(parentDir, "restore_repository", monitor.newChild(1));
80  } finally {
81  deleteReconcileFile(parentDir);
82  }
83  }
84 
85  private void deleteReconcileFile(File parentDir) {
86  Path reconcileFile = Paths.get(parentDir.getAbsolutePath(), "reconcile");
87  if (reconcileFile.toFile().exists()) {
88  try {
89  Files.delete(reconcileFile);
90  } catch (Exception e) {
91  logger.error("an error occured while deleting reconcilefile in {}", reconcileFile);
92  }
93  }
94  }
95  };
96 
97  BusyIndicator.showWhile(Display.getCurrent(), runnable);
98 
99  }
100 
109  private void runPaUpdateStage(File parentDir, String stage, SubMonitor subMonitor) {
110 
111  Integer callExitValue;
112  String errorMsg = "";
113  ActionResult actionStageResult = new ActionResult(stage);
114  ProcessBuilder builder = new ProcessBuilder();
115 
116  builder.command("python", "-u", "-m", "pa_installer.reconcile", "--stage", stage, "--topodir", parentDir.toString(), "--env",
117  "dev");
118  builder.directory(parentDir);
119  builder.redirectErrorStream(true);
120  builder.redirectInput(Redirect.PIPE);
121  builder.redirectOutput(Redirect.PIPE);
122 
123  try {
124  final Process p = builder.start();
125 
126  logger.info("Start reconcile action: Running '{}' in {}", builder.command(), parentDir);
127  parseOutputStream(subMonitor, actionStageResult, p);
128  subMonitor.worked(1);
129 
130  // Store the result of the call to display
131  callExitValue = p.waitFor();
132 
133  if (callExitValue > 0) {
134  parseErrorStream(actionStageResult, p);
135  errorMsg = MessageFormat.format(
136  "Error while running stage {0} of python package pa_installer.reconcile with exitcode {1}", stage,
137  callExitValue);
138  Activator.logToConsole(errorMsg);
139  logError(errorMsg, actionStageResult);
140  }
141 
142  } catch (IOException e) {
143  callExitValue = 1;
144  errorMsg = MessageFormat.format(
145  "Exception while running stage {0} of python package pa_installer.reconcile with exitcode {1} and {2}", stage,
146  callExitValue, e.getMessage());
147  logError(errorMsg, actionStageResult);
148  } catch (InterruptedException e) {
149  errorMsg = MessageFormat.format("Error {0} occured", e.getMessage());
150  logError(errorMsg, actionStageResult);
151  Thread.currentThread().interrupt();
152  } finally {
153  subMonitor.done();
154  actionResults.add(actionStageResult);
155  }
156  }
157 
158  private void logError(String errorMsg, ActionResult actionStageResult) {
159  actionStageResult.addToLog(errorMsg);
160  actionStageResult.setStatus("FAIL");
161  logger.error(errorMsg);
162  }
163 
164  public void parseErrorStream(ActionResult actionStageResult, final Process p) throws IOException {
165  Reader rErr = new InputStreamReader(p.getErrorStream());
166  try (BufferedReader inErr = new BufferedReader(rErr)) {
167  String line;
168  do {
169  line = inErr.readLine();
170  if (line != null) {
171  actionStageResult.addToLog(line);
172  Activator.logToConsole(line);
173  }
174  } while (line != null);
175  }
176  }
177 
178  public void parseOutputStream(SubMonitor subMonitor, ActionResult actionStageResult, final Process p)
179  throws IOException {
180  try (Reader rOut = new InputStreamReader(p.getInputStream()); BufferedReader inOut = new BufferedReader(rOut)) {
181 
182  String line;
183  do {
184  line = inOut.readLine();
185  if (line != null) {
186  int indexOfFourthSpace = StringUtils.ordinalIndexOf(line, " ", 4);
187  if (indexOfFourthSpace > -1) {
188  subMonitor.setTaskName(line.substring(indexOfFourthSpace));
189  }
190  actionStageResult.addToLog(line);
191  Activator.logToConsole(line);
192  }
193  } while (line != null);
194  }
195  }
196 
197  public void setProgressMonitor(SubMonitor monitor) {
198  this.monitor = monitor;
199  }
200 
201  public List<ActionResult> getActionResults() {
202  return actionResults;
203  }
204 }
DbAndBinaryOperation(Repository repository, ReconcileActionSettings recoSettings)