@Test public void testAnswerBadQuestion() { Batfish batfish = BatfishTestUtils.getBatfish( new TestStorageProvider() { @Override public String loadQuestion( NetworkId network, QuestionId analysis, AnalysisId question) { return "{" + "\"differential\": false," + "\"instance\": {" + "\"description\": \"Outputs cases where undefined structures (e.g., ACL, routemaps) " + "are referenced.\"," + "\"instanceName\": \"undefinedReferences\"," + "\"longDescription\": \"Such occurrences indicate configuration errors and can have" + "serious consequences with some vendors.\"," + "\"tags\": [\"default\"]," + "\"variables\": {\"nodeRegex\": {" + "\"description\": \"Only check nodes whose name matches this regex\"," + "\"type\": \"javaRegex\"," + "\"value\": \".*\"" + "}}" + "}," + "\"nodeRegex\": \"${nodeRegex}\"" + "}"; } }, new TestIdResolver()); Answer answer = batfish.answer(); assertThat(answer.getQuestion(), is(nullValue())); assertEquals(answer.getStatus(), AnswerStatus.FAILURE); assertEquals(answer.getAnswerElements().size(), 1); assertThat( answer.getAnswerElements().get(0).toString(), containsString("Could not parse question")); }
public Answer answer() { Question question = null; Span span = GlobalTracer.get().buildSpan("Parse question span").start(); try (Scope scope = GlobalTracer.get().scopeManager().activate(span)) { assert scope != null; String rawQuestionStr; try { rawQuestionStr = _storage.loadQuestion( _settings.getContainer(), _settings.getQuestionName(), _settings.getAnalysisName()); } catch (Exception e) { Answer answer = new Answer(); BatfishException exception = new BatfishException("Could not read question", e); answer.setStatus(AnswerStatus.FAILURE); answer.addAnswerElement(exception.getBatfishStackTrace()); return answer; } try { question = Question.parseQuestion(rawQuestionStr); } 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; } } finally { span.finish(); } LOGGER.info("Answering question {}", question.getClass().getSimpleName()); if (GlobalTracer.get().scopeManager().activeSpan() != null) { Span activeSpan = GlobalTracer.get().scopeManager().activeSpan(); activeSpan .setTag("container-name", getContainerName().getId()) .setTag("testrig_name", getSnapshot().getSnapshot().getId()); if (question.getInstance() != null) { activeSpan.setTag("question-name", question.getInstance().getInstanceName()); } } if (_settings.getDifferential()) { question.setDifferential(true); } boolean dp = question.getDataPlane(); boolean diff = question.getDifferential(); _settings.setDiffQuestion(diff); loadConfigurations(getSnapshot()); Span initQuestionSpan = GlobalTracer.get().buildSpan("Init question env").start(); try (Scope scope = GlobalTracer.get().scopeManager().activate(span)) { assert scope != null; prepareToAnswerQuestions(diff, dp); } finally { initQuestionSpan.finish(); } AnswerElement answerElement = null; BatfishException exception = null; Span getAnswerSpan = GlobalTracer.get().buildSpan("Get answer").start(); try (Scope scope = GlobalTracer.get().scopeManager().activate(span)) { assert scope != null; if (question.getDifferential()) { answerElement = Answerer.create(question, this).answerDiff(getSnapshot(), getReferenceSnapshot()); } else { answerElement = Answerer.create(question, this).answer(getSnapshot()); } } catch (Exception e) { exception = new BatfishException("Failed to answer question", e); } finally { getAnswerSpan.finish(); } Answer answer = new Answer(); answer.setQuestion(question); if (exception == null) { LOGGER.info("Question answered successfully"); answer.setStatus(AnswerStatus.SUCCESS); answer.addAnswerElement(answerElement); } else { LOGGER.warn("Question execution failed", exception); answer.setStatus(AnswerStatus.FAILURE); answer.addAnswerElement(exception.getBatfishStackTrace()); } return answer; }
Batfish extends PluginConsumer implements IBatfish { public Answer answer() { Question question = null; Span span = GlobalTracer.get().buildSpan("Parse question span").start(); try (Scope scope = GlobalTracer.get().scopeManager().activate(span)) { assert scope != null; String rawQuestionStr; try { rawQuestionStr = _storage.loadQuestion( _settings.getContainer(), _settings.getQuestionName(), _settings.getAnalysisName()); } catch (Exception e) { Answer answer = new Answer(); BatfishException exception = new BatfishException("Could not read question", e); answer.setStatus(AnswerStatus.FAILURE); answer.addAnswerElement(exception.getBatfishStackTrace()); return answer; } try { question = Question.parseQuestion(rawQuestionStr); } 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; } } finally { span.finish(); } LOGGER.info("Answering question {}", question.getClass().getSimpleName()); if (GlobalTracer.get().scopeManager().activeSpan() != null) { Span activeSpan = GlobalTracer.get().scopeManager().activeSpan(); activeSpan .setTag("container-name", getContainerName().getId()) .setTag("testrig_name", getSnapshot().getSnapshot().getId()); if (question.getInstance() != null) { activeSpan.setTag("question-name", question.getInstance().getInstanceName()); } } if (_settings.getDifferential()) { question.setDifferential(true); } boolean dp = question.getDataPlane(); boolean diff = question.getDifferential(); _settings.setDiffQuestion(diff); loadConfigurations(getSnapshot()); Span initQuestionSpan = GlobalTracer.get().buildSpan("Init question env").start(); try (Scope scope = GlobalTracer.get().scopeManager().activate(span)) { assert scope != null; prepareToAnswerQuestions(diff, dp); } finally { initQuestionSpan.finish(); } AnswerElement answerElement = null; BatfishException exception = null; Span getAnswerSpan = GlobalTracer.get().buildSpan("Get answer").start(); try (Scope scope = GlobalTracer.get().scopeManager().activate(span)) { assert scope != null; if (question.getDifferential()) { answerElement = Answerer.create(question, this).answerDiff(getSnapshot(), getReferenceSnapshot()); } else { answerElement = Answerer.create(question, this).answer(getSnapshot()); } } catch (Exception e) { exception = new BatfishException("Failed to answer question", e); } finally { getAnswerSpan.finish(); } Answer answer = new Answer(); answer.setQuestion(question); if (exception == null) { LOGGER.info("Question answered successfully"); answer.setStatus(AnswerStatus.SUCCESS); answer.addAnswerElement(answerElement); } else { LOGGER.warn("Question execution failed", exception); answer.setStatus(AnswerStatus.FAILURE); answer.addAnswerElement(exception.getBatfishStackTrace()); } return answer; } }
Batfish extends PluginConsumer implements IBatfish { public Answer answer() { Question question = null; Span span = GlobalTracer.get().buildSpan("Parse question span").start(); try (Scope scope = GlobalTracer.get().scopeManager().activate(span)) { assert scope != null; String rawQuestionStr; try { rawQuestionStr = _storage.loadQuestion( _settings.getContainer(), _settings.getQuestionName(), _settings.getAnalysisName()); } catch (Exception e) { Answer answer = new Answer(); BatfishException exception = new BatfishException("Could not read question", e); answer.setStatus(AnswerStatus.FAILURE); answer.addAnswerElement(exception.getBatfishStackTrace()); return answer; } try { question = Question.parseQuestion(rawQuestionStr); } 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; } } finally { span.finish(); } LOGGER.info("Answering question {}", question.getClass().getSimpleName()); if (GlobalTracer.get().scopeManager().activeSpan() != null) { Span activeSpan = GlobalTracer.get().scopeManager().activeSpan(); activeSpan .setTag("container-name", getContainerName().getId()) .setTag("testrig_name", getSnapshot().getSnapshot().getId()); if (question.getInstance() != null) { activeSpan.setTag("question-name", question.getInstance().getInstanceName()); } } if (_settings.getDifferential()) { question.setDifferential(true); } boolean dp = question.getDataPlane(); boolean diff = question.getDifferential(); _settings.setDiffQuestion(diff); loadConfigurations(getSnapshot()); Span initQuestionSpan = GlobalTracer.get().buildSpan("Init question env").start(); try (Scope scope = GlobalTracer.get().scopeManager().activate(span)) { assert scope != null; prepareToAnswerQuestions(diff, dp); } finally { initQuestionSpan.finish(); } AnswerElement answerElement = null; BatfishException exception = null; Span getAnswerSpan = GlobalTracer.get().buildSpan("Get answer").start(); try (Scope scope = GlobalTracer.get().scopeManager().activate(span)) { assert scope != null; if (question.getDifferential()) { answerElement = Answerer.create(question, this).answerDiff(getSnapshot(), getReferenceSnapshot()); } else { answerElement = Answerer.create(question, this).answer(getSnapshot()); } } catch (Exception e) { exception = new BatfishException("Failed to answer question", e); } finally { getAnswerSpan.finish(); } Answer answer = new Answer(); answer.setQuestion(question); if (exception == null) { LOGGER.info("Question answered successfully"); answer.setStatus(AnswerStatus.SUCCESS); answer.addAnswerElement(answerElement); } else { LOGGER.warn("Question execution failed", exception); answer.setStatus(AnswerStatus.FAILURE); answer.addAnswerElement(exception.getBatfishStackTrace()); } return answer; } Batfish(
      Settings settings,
      Cache<NetworkSnapshot, SortedMap<String, Configuration>> cachedConfigurations,
      Cache<NetworkSnapshot, DataPlane> cachedDataPlanes,
      Map<NetworkSnapshot, SortedMap<String, BgpAdvertisementsByVrf>> cachedEnvironmentBgpTables,
      Cache<NetworkSnapshot, Map<String, VendorConfiguration>> cachedVendorConfigurations,
      @Nullable StorageProvider alternateStorageProvider,
      @Nullable IdResolver alternateIdResolver); }
Batfish extends PluginConsumer implements IBatfish { public Answer answer() { Question question = null; Span span = GlobalTracer.get().buildSpan("Parse question span").start(); try (Scope scope = GlobalTracer.get().scopeManager().activate(span)) { assert scope != null; String rawQuestionStr; try { rawQuestionStr = _storage.loadQuestion( _settings.getContainer(), _settings.getQuestionName(), _settings.getAnalysisName()); } catch (Exception e) { Answer answer = new Answer(); BatfishException exception = new BatfishException("Could not read question", e); answer.setStatus(AnswerStatus.FAILURE); answer.addAnswerElement(exception.getBatfishStackTrace()); return answer; } try { question = Question.parseQuestion(rawQuestionStr); } 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; } } finally { span.finish(); } LOGGER.info("Answering question {}", question.getClass().getSimpleName()); if (GlobalTracer.get().scopeManager().activeSpan() != null) { Span activeSpan = GlobalTracer.get().scopeManager().activeSpan(); activeSpan .setTag("container-name", getContainerName().getId()) .setTag("testrig_name", getSnapshot().getSnapshot().getId()); if (question.getInstance() != null) { activeSpan.setTag("question-name", question.getInstance().getInstanceName()); } } if (_settings.getDifferential()) { question.setDifferential(true); } boolean dp = question.getDataPlane(); boolean diff = question.getDifferential(); _settings.setDiffQuestion(diff); loadConfigurations(getSnapshot()); Span initQuestionSpan = GlobalTracer.get().buildSpan("Init question env").start(); try (Scope scope = GlobalTracer.get().scopeManager().activate(span)) { assert scope != null; prepareToAnswerQuestions(diff, dp); } finally { initQuestionSpan.finish(); } AnswerElement answerElement = null; BatfishException exception = null; Span getAnswerSpan = GlobalTracer.get().buildSpan("Get answer").start(); try (Scope scope = GlobalTracer.get().scopeManager().activate(span)) { assert scope != null; if (question.getDifferential()) { answerElement = Answerer.create(question, this).answerDiff(getSnapshot(), getReferenceSnapshot()); } else { answerElement = Answerer.create(question, this).answer(getSnapshot()); } } catch (Exception e) { exception = new BatfishException("Failed to answer question", e); } finally { getAnswerSpan.finish(); } Answer answer = new Answer(); answer.setQuestion(question); if (exception == null) { LOGGER.info("Question answered successfully"); answer.setStatus(AnswerStatus.SUCCESS); answer.addAnswerElement(answerElement); } else { LOGGER.warn("Question execution failed", exception); answer.setStatus(AnswerStatus.FAILURE); answer.addAnswerElement(exception.getBatfishStackTrace()); } return answer; } Batfish(
      Settings settings,
      Cache<NetworkSnapshot, SortedMap<String, Configuration>> cachedConfigurations,
      Cache<NetworkSnapshot, DataPlane> cachedDataPlanes,
      Map<NetworkSnapshot, SortedMap<String, BgpAdvertisementsByVrf>> cachedEnvironmentBgpTables,
      Cache<NetworkSnapshot, Map<String, VendorConfiguration>> cachedVendorConfigurations,
      @Nullable StorageProvider alternateStorageProvider,
      @Nullable IdResolver alternateIdResolver); static Flattener flatten(
      String input,
      BatfishLogger logger,
      Settings settings,
      Warnings warnings,
      ConfigurationFormat format,
      String header); static void logWarnings(BatfishLogger logger, Warnings warnings); static ParserRuleContext parse(
      BatfishCombinedParser<?, ?> parser, BatfishLogger logger, GrammarSettings settings); Answer answer(); static Warnings buildWarnings(Settings settings); @Override DataPlaneAnswerElement computeDataPlane(NetworkSnapshot snapshot); @Override boolean debugFlagEnabled(String flag); @Override Map<Location, LocationInfo> getLocationInfo(NetworkSnapshot snapshot); Map<String, Configuration> getConfigurations(
      Map<String, VendorConfiguration> vendorConfigurations,
      SnapshotRuntimeData runtimeData,
      ConvertConfigurationAnswerElement answerElement); @Override NetworkId getContainerName(); @Override DataPlanePlugin getDataPlanePlugin(); @Override Environment getEnvironment(); @Override BatfishLogger getLogger(); @Override NodeRolesData getNodeRolesData(); @Override Optional<NodeRoleDimension> getNodeRoleDimension(@Nullable String dimension); @Override Map<String, String> getQuestionTemplates(boolean verbose); @Override @Nullable ReferenceLibrary getReferenceLibraryData(); Settings getSettings(); @Override ImmutableConfiguration getSettingsConfiguration(); @Override NetworkSnapshot getSnapshot(); @Override NetworkSnapshot getReferenceSnapshot(); @Override String getTaskId(); String getTerminatingExceptionMessage(); @Nonnull @Override TopologyProvider getTopologyProvider(); @Override PluginClientType getType(); @Override InitInfoAnswerElement initInfo(
      NetworkSnapshot snapshot, boolean summary, boolean verboseError); @Override InitInfoAnswerElement initInfoBgpAdvertisements(
      NetworkSnapshot snapshot, boolean summary, boolean verboseError); @Override SortedMap<String, Configuration> loadConfigurations(NetworkSnapshot snapshot); @Override ConvertConfigurationAnswerElement loadConvertConfigurationAnswerElementOrReparse(
      NetworkSnapshot snapshot); @Override DataPlane loadDataPlane(NetworkSnapshot snapshot); @Override SortedMap<String, BgpAdvertisementsByVrf> loadEnvironmentBgpTables(
      NetworkSnapshot snapshot); ParseEnvironmentBgpTablesAnswerElement loadParseEnvironmentBgpTablesAnswerElement(
      NetworkSnapshot snapshot); @Override ParseVendorConfigurationAnswerElement loadParseVendorConfigurationAnswerElement(
      NetworkSnapshot snapshot); @Override Map<String, VendorConfiguration> loadVendorConfigurations(NetworkSnapshot snapshot); @Override AtomicInteger newBatch(String description, int jobs); @VisibleForTesting @Nonnull static AwsConfiguration parseAwsConfigurations(
      Map<String, String> configurationData, ParseVendorConfigurationAnswerElement pvcae); @Override Set<BgpAdvertisement> loadExternalBgpAnnouncements(
      NetworkSnapshot snapshot, Map<String, Configuration> configurations); @Override SortedMap<Flow, List<Trace>> buildFlows(
      NetworkSnapshot snapshot, Set<Flow> flows, boolean ignoreFilters); @Override TracerouteEngine getTracerouteEngine(NetworkSnapshot snapshot); @Override @Nullable String readExternalBgpAnnouncementsFile(NetworkSnapshot snapshot); @Override void registerAnswerer(
      String questionName,
      String questionClassName,
      BiFunction<Question, IBatfish, Answerer> answererCreator); @Override void registerBgpTablePlugin(BgpTableFormat format, BgpTablePlugin bgpTablePlugin); @Override void registerExternalBgpAdvertisementPlugin(
      ExternalBgpAdvertisementPlugin externalBgpAdvertisementPlugin); @MustBeClosed @Nonnull @Override InputStream getNetworkObject(NetworkId networkId, String key); @MustBeClosed @Nonnull @Override InputStream getSnapshotInputObject(NetworkSnapshot snapshot, String key); Answer run(NetworkSnapshot snapshot); @Override void registerDataPlanePlugin(DataPlanePlugin plugin, String name); void setTerminatingExceptionMessage(String terminatingExceptionMessage); @Override SpecifierContext specifierContext(NetworkSnapshot networkSnapshot); @Override BidirectionalReachabilityResult bidirectionalReachability(
      NetworkSnapshot snapshot, BDDPacket bddPacket, ReachabilityParameters parameters); @Override AnswerElement standard(
      NetworkSnapshot snapshot, ReachabilityParameters reachabilityParameters); AnswerElement bddSingleReachability(
      NetworkSnapshot snapshot, ReachabilityParameters parameters); @Override Set<Flow> bddLoopDetection(NetworkSnapshot snapshot); @Override Set<Flow> bddMultipathConsistency(
      NetworkSnapshot snapshot, MultipathConsistencyParameters parameters); @Nonnull IpSpaceAssignment getAllSourcesInferFromLocationIpSpaceAssignment(
      NetworkSnapshot snapshot); BDDReachabilityAnalysis getBddReachabilityAnalysis(
      NetworkSnapshot snapshot,
      BDDPacket pkt,
      IpSpaceAssignment srcIpSpaceAssignment,
      AclLineMatchExpr initialHeaderSpace,
      Set<String> forbiddenTransitNodes,
      Set<String> requiredTransitNodes,
      Set<String> finalNodes,
      Set<FlowDisposition> actions,
      boolean ignoreFilters,
      boolean useInterfaceRoots); @Override DifferentialReachabilityResult bddDifferentialReachability(
      NetworkSnapshot snapshot,
      NetworkSnapshot reference,
      DifferentialReachabilityParameters parameters); @Override @Nullable Answerer createAnswerer(@Nonnull Question question); }
Batfish extends PluginConsumer implements IBatfish { public Answer answer() { Question question = null; Span span = GlobalTracer.get().buildSpan("Parse question span").start(); try (Scope scope = GlobalTracer.get().scopeManager().activate(span)) { assert scope != null; String rawQuestionStr; try { rawQuestionStr = _storage.loadQuestion( _settings.getContainer(), _settings.getQuestionName(), _settings.getAnalysisName()); } catch (Exception e) { Answer answer = new Answer(); BatfishException exception = new BatfishException("Could not read question", e); answer.setStatus(AnswerStatus.FAILURE); answer.addAnswerElement(exception.getBatfishStackTrace()); return answer; } try { question = Question.parseQuestion(rawQuestionStr); } 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; } } finally { span.finish(); } LOGGER.info("Answering question {}", question.getClass().getSimpleName()); if (GlobalTracer.get().scopeManager().activeSpan() != null) { Span activeSpan = GlobalTracer.get().scopeManager().activeSpan(); activeSpan .setTag("container-name", getContainerName().getId()) .setTag("testrig_name", getSnapshot().getSnapshot().getId()); if (question.getInstance() != null) { activeSpan.setTag("question-name", question.getInstance().getInstanceName()); } } if (_settings.getDifferential()) { question.setDifferential(true); } boolean dp = question.getDataPlane(); boolean diff = question.getDifferential(); _settings.setDiffQuestion(diff); loadConfigurations(getSnapshot()); Span initQuestionSpan = GlobalTracer.get().buildSpan("Init question env").start(); try (Scope scope = GlobalTracer.get().scopeManager().activate(span)) { assert scope != null; prepareToAnswerQuestions(diff, dp); } finally { initQuestionSpan.finish(); } AnswerElement answerElement = null; BatfishException exception = null; Span getAnswerSpan = GlobalTracer.get().buildSpan("Get answer").start(); try (Scope scope = GlobalTracer.get().scopeManager().activate(span)) { assert scope != null; if (question.getDifferential()) { answerElement = Answerer.create(question, this).answerDiff(getSnapshot(), getReferenceSnapshot()); } else { answerElement = Answerer.create(question, this).answer(getSnapshot()); } } catch (Exception e) { exception = new BatfishException("Failed to answer question", e); } finally { getAnswerSpan.finish(); } Answer answer = new Answer(); answer.setQuestion(question); if (exception == null) { LOGGER.info("Question answered successfully"); answer.setStatus(AnswerStatus.SUCCESS); answer.addAnswerElement(answerElement); } else { LOGGER.warn("Question execution failed", exception); answer.setStatus(AnswerStatus.FAILURE); answer.addAnswerElement(exception.getBatfishStackTrace()); } return answer; } Batfish(
      Settings settings,
      Cache<NetworkSnapshot, SortedMap<String, Configuration>> cachedConfigurations,
      Cache<NetworkSnapshot, DataPlane> cachedDataPlanes,
      Map<NetworkSnapshot, SortedMap<String, BgpAdvertisementsByVrf>> cachedEnvironmentBgpTables,
      Cache<NetworkSnapshot, Map<String, VendorConfiguration>> cachedVendorConfigurations,
      @Nullable StorageProvider alternateStorageProvider,
      @Nullable IdResolver alternateIdResolver); static Flattener flatten(
      String input,
      BatfishLogger logger,
      Settings settings,
      Warnings warnings,
      ConfigurationFormat format,
      String header); static void logWarnings(BatfishLogger logger, Warnings warnings); static ParserRuleContext parse(
      BatfishCombinedParser<?, ?> parser, BatfishLogger logger, GrammarSettings settings); Answer answer(); static Warnings buildWarnings(Settings settings); @Override DataPlaneAnswerElement computeDataPlane(NetworkSnapshot snapshot); @Override boolean debugFlagEnabled(String flag); @Override Map<Location, LocationInfo> getLocationInfo(NetworkSnapshot snapshot); Map<String, Configuration> getConfigurations(
      Map<String, VendorConfiguration> vendorConfigurations,
      SnapshotRuntimeData runtimeData,
      ConvertConfigurationAnswerElement answerElement); @Override NetworkId getContainerName(); @Override DataPlanePlugin getDataPlanePlugin(); @Override Environment getEnvironment(); @Override BatfishLogger getLogger(); @Override NodeRolesData getNodeRolesData(); @Override Optional<NodeRoleDimension> getNodeRoleDimension(@Nullable String dimension); @Override Map<String, String> getQuestionTemplates(boolean verbose); @Override @Nullable ReferenceLibrary getReferenceLibraryData(); Settings getSettings(); @Override ImmutableConfiguration getSettingsConfiguration(); @Override NetworkSnapshot getSnapshot(); @Override NetworkSnapshot getReferenceSnapshot(); @Override String getTaskId(); String getTerminatingExceptionMessage(); @Nonnull @Override TopologyProvider getTopologyProvider(); @Override PluginClientType getType(); @Override InitInfoAnswerElement initInfo(
      NetworkSnapshot snapshot, boolean summary, boolean verboseError); @Override InitInfoAnswerElement initInfoBgpAdvertisements(
      NetworkSnapshot snapshot, boolean summary, boolean verboseError); @Override SortedMap<String, Configuration> loadConfigurations(NetworkSnapshot snapshot); @Override ConvertConfigurationAnswerElement loadConvertConfigurationAnswerElementOrReparse(
      NetworkSnapshot snapshot); @Override DataPlane loadDataPlane(NetworkSnapshot snapshot); @Override SortedMap<String, BgpAdvertisementsByVrf> loadEnvironmentBgpTables(
      NetworkSnapshot snapshot); ParseEnvironmentBgpTablesAnswerElement loadParseEnvironmentBgpTablesAnswerElement(
      NetworkSnapshot snapshot); @Override ParseVendorConfigurationAnswerElement loadParseVendorConfigurationAnswerElement(
      NetworkSnapshot snapshot); @Override Map<String, VendorConfiguration> loadVendorConfigurations(NetworkSnapshot snapshot); @Override AtomicInteger newBatch(String description, int jobs); @VisibleForTesting @Nonnull static AwsConfiguration parseAwsConfigurations(
      Map<String, String> configurationData, ParseVendorConfigurationAnswerElement pvcae); @Override Set<BgpAdvertisement> loadExternalBgpAnnouncements(
      NetworkSnapshot snapshot, Map<String, Configuration> configurations); @Override SortedMap<Flow, List<Trace>> buildFlows(
      NetworkSnapshot snapshot, Set<Flow> flows, boolean ignoreFilters); @Override TracerouteEngine getTracerouteEngine(NetworkSnapshot snapshot); @Override @Nullable String readExternalBgpAnnouncementsFile(NetworkSnapshot snapshot); @Override void registerAnswerer(
      String questionName,
      String questionClassName,
      BiFunction<Question, IBatfish, Answerer> answererCreator); @Override void registerBgpTablePlugin(BgpTableFormat format, BgpTablePlugin bgpTablePlugin); @Override void registerExternalBgpAdvertisementPlugin(
      ExternalBgpAdvertisementPlugin externalBgpAdvertisementPlugin); @MustBeClosed @Nonnull @Override InputStream getNetworkObject(NetworkId networkId, String key); @MustBeClosed @Nonnull @Override InputStream getSnapshotInputObject(NetworkSnapshot snapshot, String key); Answer run(NetworkSnapshot snapshot); @Override void registerDataPlanePlugin(DataPlanePlugin plugin, String name); void setTerminatingExceptionMessage(String terminatingExceptionMessage); @Override SpecifierContext specifierContext(NetworkSnapshot networkSnapshot); @Override BidirectionalReachabilityResult bidirectionalReachability(
      NetworkSnapshot snapshot, BDDPacket bddPacket, ReachabilityParameters parameters); @Override AnswerElement standard(
      NetworkSnapshot snapshot, ReachabilityParameters reachabilityParameters); AnswerElement bddSingleReachability(
      NetworkSnapshot snapshot, ReachabilityParameters parameters); @Override Set<Flow> bddLoopDetection(NetworkSnapshot snapshot); @Override Set<Flow> bddMultipathConsistency(
      NetworkSnapshot snapshot, MultipathConsistencyParameters parameters); @Nonnull IpSpaceAssignment getAllSourcesInferFromLocationIpSpaceAssignment(
      NetworkSnapshot snapshot); BDDReachabilityAnalysis getBddReachabilityAnalysis(
      NetworkSnapshot snapshot,
      BDDPacket pkt,
      IpSpaceAssignment srcIpSpaceAssignment,
      AclLineMatchExpr initialHeaderSpace,
      Set<String> forbiddenTransitNodes,
      Set<String> requiredTransitNodes,
      Set<String> finalNodes,
      Set<FlowDisposition> actions,
      boolean ignoreFilters,
      boolean useInterfaceRoots); @Override DifferentialReachabilityResult bddDifferentialReachability(
      NetworkSnapshot snapshot,
      NetworkSnapshot reference,
      DifferentialReachabilityParameters parameters); @Override @Nullable Answerer createAnswerer(@Nonnull Question question);  }