private Pair<Integer, Double> findBestRegex(final List<List<String>> candidates) { // choose the candidate role regex with the maximal "role score" return IntStream.range(0, candidates.size()) .mapToObj(i -> new Pair<>(i, computeRoleScore(regexTokensToRegex(candidates.get(i))))) .max(Comparator.comparingDouble(Pair::getSecond)) .orElseThrow(() -> new BatfishException("this exception should not be reachable")); }
boolean commonRegexFound = inferCommonRegex(_nodes); List<List<String>> candidateRegexes = possibleRoleGroups(); Pair<Integer, Double> bestRegexAndScore = findBestRegex(candidateRegexes); toPrimaryNodeRoleDimensionIfAboveThreshold(bestRegexAndScore, candidateRegexes); boolean bestIsAboveThreshold = optResult.isPresent(); if (bestIsAboveThreshold) { allDims = createRoleDimensions(candidateRegexes); possibleSecondRoleGroups(candidateRegexes.get(bestRegexAndScore.getFirst())); toNodeRoleDimension( findBestRegex(candidateRegexes), candidateRegexes, NodeRoleDimension.AUTO_DIMENSION_PRIMARY));
case ALNUM_PLUS: List<String> regexCopy = new ArrayList<>(_regex); regexCopy.set(i, group(plus(ALPHABETIC_REGEX)) + star(ALPHANUMERIC_REGEX)); Pattern newp = Pattern.compile(regexTokensToRegex(regexCopy), _patternFlags); int numMatches = 0; for (String node : _matchingNodes) { case ALPHA_PLUS_DIGIT_PLUS: List<String> regexCopy2 = new ArrayList<>(_regex); regexCopy2.set(i, group(plus(ALPHABETIC_REGEX)) + plus(DIGIT_REGEX)); candidateRegexes.add(regexCopy2); break;
@Override public InferRolesAnswerElement answer() { InferRolesQuestion question = (InferRolesQuestion) _question; InferRolesAnswerElement answerElement = new InferRolesAnswerElement(null, null); // collect relevant nodes in a list. Set<String> nodes = question.getNodeRegex().getMatchingNodes(_batfish); SortedSet<NodeRoleDimension> roleDimensions = new InferRoles(nodes, _batfish.getEnvironmentTopology(), question.getCaseSensitive()) .inferRoles(); answerElement.getRoleDimensions().addAll(roleDimensions); for (NodeRoleDimension dimension : roleDimensions) { SortedMap<String, SortedSet<String>> roleNodesMap = dimension.createRoleNodesMap(nodes); SortedSet<String> matchingNodes = new TreeSet<>(); for (SortedSet<String> nodeSet : roleNodesMap.values()) { matchingNodes.addAll(nodeSet); } answerElement.getMatchingNodesCount().put(dimension.getName(), matchingNodes.size()); } return answerElement; } }
private static List<List<String>> possibleSecondRoleGroups(List<String> tokens) { List<List<String>> candidateRegexes = new ArrayList<>(); for (int i = 0; i < tokens.size(); i++) { String token = tokens.get(i); // skip the token if it's a delimiter or the primary group if (token.startsWith("\\Q") || token.startsWith("(")) { continue; } List<String> regexCopy = new ArrayList<>(tokens); regexCopy.set(i, group(token)); candidateRegexes.add(regexCopy); } return candidateRegexes; }
private void updateSnapshotNodeRoles() { // Compute new auto role data and updates existing auto data with it NetworkId networkId = _settings.getContainer(); SnapshotId snapshotId = _settings.getTestrig(); NodeRolesId snapshotNodeRolesId = _idResolver.getSnapshotNodeRolesId(networkId, snapshotId); Set<String> nodeNames = loadConfigurations().keySet(); Topology rawLayer3Topology = _topologyProvider.getRawLayer3Topology(getNetworkSnapshot()); SortedSet<NodeRoleDimension> autoRoles = new InferRoles(nodeNames, rawLayer3Topology).inferRoles(); NodeRolesData.Builder snapshotNodeRoles = NodeRolesData.builder(); try { if (!autoRoles.isEmpty()) { snapshotNodeRoles.setDefaultDimension(autoRoles.first().getName()); snapshotNodeRoles.setRoleDimensions(autoRoles); } _storage.storeNodeRoles(snapshotNodeRoles.build(), snapshotNodeRolesId); } catch (IOException e) { _logger.warnf("Could not update node roles: %s", e); } }
@Test public void inferRolesOnExampleTopology() throws JsonProcessingException { SortedSet<NodeRoleDimension> roles = new InferRoles(EXAMPLE_NODES, EXAMPLE_TOPOLOGY).inferRoles(); assertThat(BatfishObjectMapper.writePrettyString(roles), roles, hasSize(2)); NodeRoleDimension d1 = roles.first(); assertThat( d1.createRoleNodesMap(EXAMPLE_NODES), equalTo( ImmutableMap.of( "border", filterSet(EXAMPLE_NODES, s -> s.toLowerCase().contains("border")), "core", filterSet(EXAMPLE_NODES, s -> s.toLowerCase().contains("core")), "dept", filterSet(EXAMPLE_NODES, s -> s.toLowerCase().contains("dept")), "dist", filterSet(EXAMPLE_NODES, s -> s.toLowerCase().contains("dist"))))); NodeRoleDimension d2 = roles.last(); assertThat( d2.createRoleNodesMap(EXAMPLE_NODES), equalTo( ImmutableMap.of( "as", filterSet(EXAMPLE_NODES, s -> s.toLowerCase().startsWith("as"))))); }
@Test public void inferCaseSensitiveRolesOnExampleTopology() throws JsonProcessingException { SortedSet<NodeRoleDimension> roles = new InferRoles(EXAMPLE_NODES, EXAMPLE_TOPOLOGY, true).inferRoles();
@Test public void inferRolesOnExampleTopology() throws JsonProcessingException { SortedSet<NodeRoleDimension> roles = new InferRoles(EXAMPLE_NODES, EXAMPLE_TOPOLOGY).inferRoles(); assertThat(BatfishObjectMapper.writePrettyString(roles), roles, hasSize(2)); // Note: currently we do not find a "host" role because it does not match the majority // tokenization. If we had as1host1, e.g., we would. NodeRoleDimension d1 = roles.first(); assertThat( d1.createRoleNodesMap(EXAMPLE_NODES), equalTo( ImmutableMap.of( "border", filterSet(EXAMPLE_NODES, s -> s.contains("border")), "core", filterSet(EXAMPLE_NODES, s -> s.contains("core")), "dept", filterSet(EXAMPLE_NODES, s -> s.contains("dept")), "dist", filterSet(EXAMPLE_NODES, s -> s.contains("dist"))))); NodeRoleDimension d2 = roles.last(); assertThat( d2.createRoleNodesMap(EXAMPLE_NODES), equalTo(ImmutableMap.of("as", filterSet(EXAMPLE_NODES, s -> s.startsWith("as"))))); } }