use of io.opentracing.ActiveSpan in project batfish by batfish.
the class Batfish method answer.
public Answer answer() {
Question question = null;
// return right away if we cannot parse the question successfully
try (ActiveSpan parseQuestionSpan = GlobalTracer.get().buildSpan("Parse question").startActive()) {
// avoid not used warning
assert parseQuestionSpan != null;
question = Question.parseQuestion(_settings.getQuestionPath());
} catch (Exception e) {
Answer answer = new Answer();
BatfishException exception = new BatfishException("Could not parse question", e);
answer.setStatus(AnswerStatus.FAILURE);
answer.addAnswerElement(exception.getBatfishStackTrace());
return answer;
}
if (_settings.getDifferential()) {
question.setDifferential(true);
}
boolean dp = question.getDataPlane();
boolean diff = question.getDifferential();
boolean diffActive = _settings.getDiffActive() && !diff;
_settings.setDiffActive(diffActive);
_settings.setDiffQuestion(diff);
try (ActiveSpan loadConfigurationSpan = GlobalTracer.get().buildSpan("Load configurations").startActive()) {
// avoid not used warning
assert loadConfigurationSpan != null;
// Ensures configurations are parsed and ready
loadConfigurations();
}
try (ActiveSpan initQuestionEnvSpan = GlobalTracer.get().buildSpan("Init question environment").startActive()) {
// avoid not used warning
assert initQuestionEnvSpan != null;
initQuestionEnvironments(question, diff, diffActive, dp);
}
AnswerElement answerElement = null;
BatfishException exception = null;
try (ActiveSpan getAnswerSpan = GlobalTracer.get().buildSpan("Get answer").startActive()) {
// avoid not used warning
assert getAnswerSpan != null;
if (question.getDifferential()) {
answerElement = Answerer.create(question, this).answerDiff();
} else {
answerElement = Answerer.create(question, this).answer();
}
} catch (Exception e) {
exception = new BatfishException("Failed to answer question", e);
}
Answer answer = new Answer();
answer.setQuestion(question);
if (exception == null) {
// success
answer.setStatus(AnswerStatus.SUCCESS);
answer.addAnswerElement(answerElement);
} else {
// failure
answer.setStatus(AnswerStatus.FAILURE);
answer.addAnswerElement(exception.getBatfishStackTrace());
}
return answer;
}
use of io.opentracing.ActiveSpan in project batfish by batfish.
the class Batfish method serializeHostConfigs.
private SortedMap<String, VendorConfiguration> serializeHostConfigs(Path testRigPath, Path outputPath, ParseVendorConfigurationAnswerElement answerElement) {
SortedMap<Path, String> configurationData = readConfigurationFiles(testRigPath, BfConsts.RELPATH_HOST_CONFIGS_DIR);
// read the host files
SortedMap<String, VendorConfiguration> allHostConfigurations;
try (ActiveSpan parseHostConfigsSpan = GlobalTracer.get().buildSpan("Parse host configs").startActive()) {
// avoid unused warning
assert parseHostConfigsSpan != null;
allHostConfigurations = parseVendorConfigurations(configurationData, answerElement, ConfigurationFormat.HOST);
}
if (allHostConfigurations == null) {
throw new BatfishException("Exiting due to parser errors");
}
_logger.infof("Testrig:%s in container:%s has total number of host configs:%d", getTestrigName(), getContainerName(), allHostConfigurations.size());
// split into hostConfigurations and overlayConfigurations
SortedMap<String, VendorConfiguration> overlayConfigurations = allHostConfigurations.entrySet().stream().filter(e -> ((HostConfiguration) e.getValue()).getOverlay()).collect(toMap(Entry::getKey, Entry::getValue, (v1, v2) -> v1, TreeMap::new));
SortedMap<String, VendorConfiguration> nonOverlayHostConfigurations = allHostConfigurations.entrySet().stream().filter(e -> !((HostConfiguration) e.getValue()).getOverlay()).collect(toMap(Entry::getKey, Entry::getValue, (v1, v2) -> v1, TreeMap::new));
// read and associate iptables files for specified hosts
SortedMap<Path, String> iptablesData = new TreeMap<>();
readIptableFiles(testRigPath, allHostConfigurations, iptablesData, answerElement);
SortedMap<String, VendorConfiguration> iptablesConfigurations = parseVendorConfigurations(iptablesData, answerElement, ConfigurationFormat.IPTABLES);
for (VendorConfiguration vc : allHostConfigurations.values()) {
HostConfiguration hostConfig = (HostConfiguration) vc;
if (hostConfig.getIptablesFile() != null) {
Path path = Paths.get(testRigPath.toString(), hostConfig.getIptablesFile());
String relativePathStr = _testrigSettings.getBasePath().relativize(path).toString();
if (iptablesConfigurations.containsKey(relativePathStr)) {
hostConfig.setIptablesVendorConfig((IptablesVendorConfiguration) iptablesConfigurations.get(relativePathStr));
}
}
}
// now, serialize
_logger.info("\n*** SERIALIZING VENDOR CONFIGURATION STRUCTURES ***\n");
_logger.resetTimer();
CommonUtil.createDirectories(outputPath);
Map<Path, VendorConfiguration> output = new TreeMap<>();
nonOverlayHostConfigurations.forEach((name, vc) -> {
Path currentOutputPath = outputPath.resolve(name);
output.put(currentOutputPath, vc);
});
serializeObjects(output);
// serialize warnings
serializeObject(answerElement, _testrigSettings.getParseAnswerPath());
_logger.printElapsedTime();
return overlayConfigurations;
}
use of io.opentracing.ActiveSpan in project batfish by batfish.
the class Driver method runBatfish.
@SuppressWarnings("deprecation")
private static String runBatfish(final Settings settings) {
final BatfishLogger logger = settings.getLogger();
try {
final Batfish batfish = new Batfish(settings, CACHED_COMPRESSED_TESTRIGS, CACHED_TESTRIGS, CACHED_COMPRESSED_DATA_PLANES, CACHED_DATA_PLANES, CACHED_ENVIRONMENT_BGP_TABLES, CACHED_ENVIRONMENT_ROUTING_TABLES, CACHED_FORWARDING_ANALYSES);
@Nullable SpanContext runBatfishSpanContext = GlobalTracer.get().activeSpan() == null ? null : GlobalTracer.get().activeSpan().context();
Thread thread = new Thread() {
@Override
public void run() {
try (ActiveSpan runBatfishSpan = GlobalTracer.get().buildSpan("Run Batfish job in a new thread and get the answer").addReference(References.FOLLOWS_FROM, runBatfishSpanContext).startActive()) {
assert runBatfishSpan != null;
Answer answer = null;
try {
answer = batfish.run();
if (answer.getStatus() == null) {
answer.setStatus(AnswerStatus.SUCCESS);
}
} catch (CleanBatfishException e) {
String msg = "FATAL ERROR: " + e.getMessage();
logger.error(msg);
batfish.setTerminatingExceptionMessage(e.getClass().getName() + ": " + e.getMessage());
answer = Answer.failureAnswer(msg, null);
} catch (QuestionException e) {
String stackTrace = ExceptionUtils.getStackTrace(e);
logger.error(stackTrace);
batfish.setTerminatingExceptionMessage(e.getClass().getName() + ": " + e.getMessage());
answer = e.getAnswer();
answer.setStatus(AnswerStatus.FAILURE);
} catch (BatfishException e) {
String stackTrace = ExceptionUtils.getStackTrace(e);
logger.error(stackTrace);
batfish.setTerminatingExceptionMessage(e.getClass().getName() + ": " + e.getMessage());
answer = new Answer();
answer.setStatus(AnswerStatus.FAILURE);
answer.addAnswerElement(e.getBatfishStackTrace());
} catch (Throwable e) {
String stackTrace = ExceptionUtils.getStackTrace(e);
logger.error(stackTrace);
batfish.setTerminatingExceptionMessage(e.getClass().getName() + ": " + e.getMessage());
answer = new Answer();
answer.setStatus(AnswerStatus.FAILURE);
answer.addAnswerElement(new BatfishException("Batfish job failed", e).getBatfishStackTrace());
} finally {
try (ActiveSpan outputAnswerSpan = GlobalTracer.get().buildSpan("Outputting answer").startActive()) {
assert outputAnswerSpan != null;
if (settings.getAnswerJsonPath() != null) {
batfish.outputAnswerWithLog(answer);
}
}
}
}
}
};
thread.start();
thread.join(settings.getMaxRuntimeMs());
if (thread.isAlive()) {
// this is deprecated but we should be safe since we don't have
// locks and such
// AF: This doesn't do what you think it does, esp. not in Java 8.
// It needs to be replaced. TODO
thread.stop();
logger.error("Batfish worker took too long. Terminated.");
batfish.setTerminatingExceptionMessage("Batfish worker took too long. Terminated.");
}
return batfish.getTerminatingExceptionMessage();
} catch (Exception e) {
String stackTrace = ExceptionUtils.getStackTrace(e);
logger.error(stackTrace);
return stackTrace;
}
}
use of io.opentracing.ActiveSpan in project batfish by batfish.
the class WorkMgr method assignWork.
private void assignWork(QueuedWork work, String worker) {
_logger.infof("WM:AssignWork: Trying to assign %s to %s\n", work, worker);
boolean assignmentError = false;
boolean assigned = false;
Client client = null;
SpanContext queueWorkSpan = work.getWorkItem().getSourceSpan();
try (ActiveSpan assignWorkSpan = GlobalTracer.get().buildSpan("Assign Work").addReference(References.FOLLOWS_FROM, queueWorkSpan).startActive()) {
// avoid unused warning
assert assignWorkSpan != null;
// get the task and add other standard stuff
JSONObject task = new JSONObject(work.getWorkItem().getRequestParams());
Path containerDir = Main.getSettings().getContainersLocation().resolve(work.getWorkItem().getContainerName());
String testrigName = work.getWorkItem().getTestrigName();
Path testrigBaseDir = containerDir.resolve(Paths.get(BfConsts.RELPATH_TESTRIGS_DIR, testrigName)).toAbsolutePath();
task.put(BfConsts.ARG_CONTAINER_DIR, containerDir.toAbsolutePath().toString());
task.put(BfConsts.ARG_TESTRIG, testrigName);
task.put(BfConsts.ARG_LOG_FILE, testrigBaseDir.resolve(work.getId() + BfConsts.SUFFIX_LOG_FILE).toString());
task.put(BfConsts.ARG_ANSWER_JSON_PATH, testrigBaseDir.resolve(work.getId() + BfConsts.SUFFIX_ANSWER_JSON_FILE).toString());
client = CommonUtil.createHttpClientBuilder(_settings.getSslPoolDisable(), _settings.getSslPoolTrustAllCerts(), _settings.getSslPoolKeystoreFile(), _settings.getSslPoolKeystorePassword(), _settings.getSslPoolTruststoreFile(), _settings.getSslPoolTruststorePassword()).build();
String protocol = _settings.getSslPoolDisable() ? "http" : "https";
WebTarget webTarget = client.target(String.format("%s://%s%s/%s", protocol, worker, BfConsts.SVC_BASE_RSC, BfConsts.SVC_RUN_TASK_RSC)).queryParam(BfConsts.SVC_TASKID_KEY, UriComponent.encode(work.getId().toString(), UriComponent.Type.QUERY_PARAM_SPACE_ENCODED)).queryParam(BfConsts.SVC_TASK_KEY, UriComponent.encode(task.toString(), UriComponent.Type.QUERY_PARAM_SPACE_ENCODED));
Response response = webTarget.request(MediaType.APPLICATION_JSON).get();
if (response.getStatus() != Response.Status.OK.getStatusCode()) {
_logger.errorf("WM:AssignWork: Got non-OK response %s\n", response.getStatus());
} else {
String sobj = response.readEntity(String.class);
JSONArray array = new JSONArray(sobj);
_logger.info(String.format("WM:AssignWork: response: %s [%s] [%s]\n", array.toString(), array.get(0), array.get(1)));
if (!array.get(0).equals(BfConsts.SVC_SUCCESS_KEY)) {
_logger.error(String.format("ERROR in assigning task: %s %s\n", array.get(0), array.get(1)));
assignmentError = true;
} else {
assigned = true;
}
}
} catch (ProcessingException e) {
String stackTrace = ExceptionUtils.getStackTrace(e);
_logger.error(String.format("Unable to connect to worker at %s: %s\n", worker, stackTrace));
} catch (Exception e) {
String stackTrace = ExceptionUtils.getStackTrace(e);
_logger.error(String.format("Exception assigning work: %s\n", stackTrace));
} finally {
if (client != null) {
client.close();
}
}
if (work.getStatus() == WorkStatusCode.TERMINATEDBYUSER) {
if (assigned) {
killWork(work, worker);
}
return;
}
// mark the assignment results for both work and worker
if (assignmentError) {
try {
_workQueueMgr.markAssignmentError(work);
} catch (Exception e) {
String stackTrace = ExceptionUtils.getStackTrace(e);
_logger.errorf("Unable to markAssignmentError for work %s: %s\n", work, stackTrace);
}
} else if (assigned) {
try {
_workQueueMgr.markAssignmentSuccess(work, worker);
} catch (Exception e) {
String stackTrace = ExceptionUtils.getStackTrace(e);
_logger.errorf("Unable to markAssignmentSuccess for work %s: %s\n", work, stackTrace);
}
} else {
_workQueueMgr.markAssignmentFailure(work);
}
Main.getPoolMgr().markAssignmentResult(worker, assigned);
}
use of io.opentracing.ActiveSpan in project batfish by batfish.
the class WorkMgr method checkTask.
private void checkTask(QueuedWork work, String worker) {
_logger.infof("WM:CheckWork: Trying to check %s on %s\n", work, worker);
Task task = new Task(TaskStatus.UnreachableOrBadResponse);
Client client = null;
SpanContext queueWorkSpan = work.getWorkItem().getSourceSpan();
try (ActiveSpan checkTaskSpan = GlobalTracer.get().buildSpan("Checking Task Status").addReference(References.FOLLOWS_FROM, queueWorkSpan).startActive()) {
// avoid unused warning
assert checkTaskSpan != null;
client = CommonUtil.createHttpClientBuilder(_settings.getSslPoolDisable(), _settings.getSslPoolTrustAllCerts(), _settings.getSslPoolKeystoreFile(), _settings.getSslPoolKeystorePassword(), _settings.getSslPoolTruststoreFile(), _settings.getSslPoolTruststorePassword()).build();
String protocol = _settings.getSslPoolDisable() ? "http" : "https";
WebTarget webTarget = client.target(String.format("%s://%s%s/%s", protocol, worker, BfConsts.SVC_BASE_RSC, BfConsts.SVC_GET_TASKSTATUS_RSC)).queryParam(BfConsts.SVC_TASKID_KEY, UriComponent.encode(work.getId().toString(), UriComponent.Type.QUERY_PARAM_SPACE_ENCODED));
Response response = webTarget.request(MediaType.APPLICATION_JSON).get();
if (response.getStatus() != Response.Status.OK.getStatusCode()) {
_logger.errorf("WM:CheckTask: Got non-OK response %s\n", response.getStatus());
} else {
String sobj = response.readEntity(String.class);
JSONArray array = new JSONArray(sobj);
_logger.info(String.format("response: %s [%s] [%s]\n", array, array.get(0), array.get(1)));
if (!array.get(0).equals(BfConsts.SVC_SUCCESS_KEY)) {
_logger.error(String.format("got error while refreshing status: %s %s\n", array.get(0), array.get(1)));
} else {
String taskStr = array.get(1).toString();
task = BatfishObjectMapper.mapper().readValue(taskStr, Task.class);
if (task.getStatus() == null) {
_logger.error("did not see status key in json response\n");
}
}
}
} catch (ProcessingException e) {
String stackTrace = ExceptionUtils.getStackTrace(e);
_logger.error(String.format("unable to connect to %s: %s\n", worker, stackTrace));
} catch (Exception e) {
String stackTrace = ExceptionUtils.getStackTrace(e);
_logger.error(String.format("exception: %s\n", stackTrace));
} finally {
if (client != null) {
client.close();
}
}
if (work.getStatus() == WorkStatusCode.TERMINATEDBYUSER) {
return;
}
try {
_workQueueMgr.processTaskCheckResult(work, task);
} catch (Exception e) {
_logger.errorf("exception: %s\n", ExceptionUtils.getStackTrace(e));
}
// if the task ended, send a hint to the pool manager to look up worker status
if (task.getStatus().isTerminated()) {
Main.getPoolMgr().refreshWorkerStatus(worker);
}
}
Aggregations