package ee.elinyo.teamcity.plugins.ansible.logparser;
import ee.elinyo.teamcity.plugins.ansible.logparser.domain.Play;
import ee.elinyo.teamcity.plugins.ansible.logparser.domain.Playbook;
import ee.elinyo.teamcity.plugins.ansible.logparser.domain.Task;
import ee.elinyo.teamcity.plugins.utils.Pair;
public class AnsibleOutputProcessor {
private Playbook playbook;
private LogProcessingContext currentContext;
private Play currentPlay;
private Task currentTask;
private int taskCounter = 0;
private Pair<Long, String> lastLine;
public void onLine(String line) {
if (!isIgnore(line)) {
Pair<Long, String> undecorated = DateDecorator.undecorate(line);
if (undecorated != null && !isIgnore(undecorated.getRight())) {
process(undecorated.getLeft(), undecorated.getRight());
}
lastLine = undecorated;
}
}
private void process(long date, String line) {
if (playbook == null) {
playbook = new Playbook();
playbook.setStartedAt(date);
}
if (AnsibleLogUtils.isTaskStart(line) || AnsibleLogUtils.isNotified(line)) {
nextTask(line, date);
currentContext = new TaskContext(currentTask, currentPlay);
} else if (AnsibleLogUtils.isPlayStart(line)) {
nextPlay(line, date);
} else if (AnsibleLogUtils.isGatheringFactStart(line)) {
currentContext = new GatheringFactsContext(currentPlay);
} else if (AnsibleLogUtils.isRecapStart(line)) {
recap(date);
currentContext = new RecapContext(playbook);
} else if (AnsibleLogUtils.isError(line)) {
playbook.setErrorMessage(line);
} else if (AnsibleLogUtils.isPlaySkip(line)) {
currentPlay.setSkipped(true);
} else if (AnsibleLogUtils.isBuildMeta(line)) {
playbook.addBuildMeta(line);
} else if (currentContext != null) {
currentContext.process(line);
}
}
private void nextPlay(String line, long date) {
Play newPlay = Play.fromOutputLine(line, date);
if (currentPlay != null) {
currentPlay.setFinishedAt(date);
}
if (currentTask != null) {
currentTask.setFinishedAt(date);
}
currentTask = null;
currentPlay = newPlay;
playbook.getPlays().add(currentPlay);
}
private void nextTask(String line, long date) {
Task newTask = Task.fromOutputLine(line, date);
newTask.setOrder(taskCounter++);
if (currentTask != null) {
currentTask.setFinishedAt(date);
}
currentTask = newTask;
}
private void recap(long date) {
if (currentTask != null) {
currentTask.setFinishedAt(date);
}
currentTask = null;
if (currentPlay != null) {
currentPlay.setFinishedAt(date);
}
currentPlay = null;
playbook.setFinishedAt(date);
}
private boolean isIgnore(String line) {
return line == null || line.trim().isEmpty() ;
}
public Playbook finish() {
//not properly started, e.g. due to syntax problems in ansible playbook
if (playbook.getFinishedAt() == 0) {
playbook.setFinishedAt(lastLine.getLeft());
}
return playbook;
}
}