public void streamLog(String jobId, String logRetrievalScope, String logRetrievalType, Writer writer,
Map<String, String[]> params) throws IOException, BaseEngineException, CommandException {
Date startTime = null;
Date endTime = null;
XLogFilter filter = new XLogFilter(new XLogUserFilterParam(params));
filter.setParameter(DagXLogInfoService.JOB, jobId);
if (logRetrievalScope != null && logRetrievalType != null) {
// if coordinator action logs are to be retrieved based on action id range
if (logRetrievalType.equals(RestConstants.JOB_LOG_ACTION)) {
// Use set implementation that maintains order or elements to achieve reproducibility:
Set<String> actionSet = new LinkedHashSet<String>();
String[] list = logRetrievalScope.split(",");
for (String s : list) {
s = s.trim();
if (s.contains("-")) {
String[] range = s.split("-");
if (range.length != 2) {
throw new CommandException(ErrorCode.E0302, "format is wrong for action's range '" + s
+ "'");
}
int start;
int end;
try {
start = Integer.parseInt(range[0].trim());
} catch (NumberFormatException ne) {
throw new CommandException(ErrorCode.E0302, "could not parse " + range[0].trim() + "into an integer",
ne);
}
try {
end = Integer.parseInt(range[1].trim());
} catch (NumberFormatException ne) {
throw new CommandException(ErrorCode.E0302, "could not parse " + range[1].trim() + "into an integer",
ne);
}
if (start > end) {
throw new CommandException(ErrorCode.E0302, "format is wrong for action's range '" + s + "'");
}
for (int i = start; i <= end; i++) {
actionSet.add(jobId + "@" + i);
}
}
else {
try {
Integer.parseInt(s);
}
catch (NumberFormatException ne) {
throw new CommandException(ErrorCode.E0302, "format is wrong for action id'" + s
+ "'. Integer only.");
}
actionSet.add(jobId + "@" + s);
}
}
if (actionSet.size() >= maxNumActionsForLog) {
throw new CommandException(ErrorCode.E0302,
"Retrieving log of too many coordinator actions. Max count is "
+ maxNumActionsForLog + " actions");
}
Iterator<String> actionsIterator = actionSet.iterator();
StringBuilder orSeparatedActions = new StringBuilder("");
boolean orRequired = false;
while (actionsIterator.hasNext()) {
if (orRequired) {
orSeparatedActions.append("|");
}
orSeparatedActions.append(actionsIterator.next().toString());
orRequired = true;
}
if (actionSet.size() > 1 && orRequired) {
orSeparatedActions.insert(0, "(");
orSeparatedActions.append(")");
}
filter.setParameter(DagXLogInfoService.ACTION, orSeparatedActions.toString());
if (actionSet != null && actionSet.size() == 1) {
CoordinatorActionBean actionBean = getCoordAction(actionSet.iterator().next());
startTime = actionBean.getCreatedTime();
endTime = actionBean.getStatus().equals(CoordinatorAction.Status.RUNNING) ? new Date() : actionBean
.getLastModifiedTime();
filter.setActionList(true);
}
else if (actionSet != null && actionSet.size() > 0) {
List<String> tempList = new ArrayList<String>(actionSet);
Collections.sort(tempList, new Comparator<String>() {
public int compare(String a, String b) {
return Integer.valueOf(a.substring(a.lastIndexOf("@") + 1)).compareTo(
Integer.valueOf(b.substring(b.lastIndexOf("@") + 1)));
}
});
startTime = getCoordAction(tempList.get(0)).getCreatedTime();
endTime = CoordActionsInDateRange.getCoordActionsLastModifiedDate(jobId, tempList.get(0),
tempList.get(tempList.size() - 1));
filter.setActionList(true);
}
}
// if coordinator action logs are to be retrieved based on date range
// this block gets the corresponding list of coordinator actions to be used by the log filter
if (logRetrievalType.equalsIgnoreCase(RestConstants.JOB_LOG_DATE)) {
List<String> coordActionIdList = null;
try {
coordActionIdList = CoordActionsInDateRange.getCoordActionIdsFromDates(jobId, logRetrievalScope);
}
catch (XException xe) {
throw new CommandException(ErrorCode.E0302, "Error in date range for coordinator actions", xe);
}
if(coordActionIdList.size() >= maxNumActionsForLog) {
throw new CommandException(ErrorCode.E0302,
"Retrieving log of too many coordinator actions. Max count is "
+ maxNumActionsForLog + " actions");
}
StringBuilder orSeparatedActions = new StringBuilder("");
boolean orRequired = false;
for (String coordActionId : coordActionIdList) {
if (orRequired) {
orSeparatedActions.append("|");
}
orSeparatedActions.append(coordActionId);
orRequired = true;
}
if (coordActionIdList.size() > 1 && orRequired) {
orSeparatedActions.insert(0, "(");
orSeparatedActions.append(")");
}
filter.setParameter(DagXLogInfoService.ACTION, orSeparatedActions.toString());
if (coordActionIdList != null && coordActionIdList.size() == 1) {
CoordinatorActionBean actionBean = getCoordAction(coordActionIdList.get(0));
startTime = actionBean.getCreatedTime();
endTime = actionBean.getStatus().equals(CoordinatorAction.Status.RUNNING) ? new Date() : actionBean
.getLastModifiedTime();
filter.setActionList(true);
}
else if (coordActionIdList != null && coordActionIdList.size() > 0) {
Collections.sort(coordActionIdList, new Comparator<String>() {
public int compare(String a, String b) {
return Integer.valueOf(a.substring(a.lastIndexOf("@") + 1)).compareTo(
Integer.valueOf(b.substring(b.lastIndexOf("@") + 1)));
}
});
startTime = getCoordAction(coordActionIdList.get(0)).getCreatedTime();
endTime = CoordActionsInDateRange.getCoordActionsLastModifiedDate(jobId, coordActionIdList.get(0),
coordActionIdList.get(coordActionIdList.size() - 1));
filter.setActionList(true);
}
}
}
if (startTime == null || endTime == null) {
CoordinatorJobBean job = getCoordJobWithNoActionInfo(jobId);