Talk about NodeSelector of elastosearchrestclient.

  elasticsearch

Order

This article mainly studies NodeSelector of elastosearchrestclient.

NodeSelector

elasticsearch-7.0.1/client/rest/src/main/java/org/elasticsearch/client/NodeSelector.java

public interface NodeSelector {
    /**
     * Select the {@link Node}s to which to send requests. This is called with
     * a mutable {@link Iterable} of {@linkplain Node}s in the order that the
     * rest client would prefer to use them and implementers should remove
     * nodes from the that should not receive the request. Implementers may
     * iterate the nodes as many times as they need.
     * <p>
     * This may be called twice per request: first for "living" nodes that
     * have not been blacklisted by previous errors. If the selector removes
     * all nodes from the list or if there aren't any living nodes then the
     * {@link RestClient} will call this method with a list of "dead" nodes.
     * <p>
     * Implementers should not rely on the ordering of the nodes.
     */
    void select(Iterable<Node> nodes);
    /*
     * We were fairly careful with our choice of Iterable here. The caller has
     * a List but reordering the list is likely to break round robin. Luckily
     * Iterable doesn't allow any reordering.
     */

    /**
     * Selector that matches any node.
     */
    NodeSelector ANY = new NodeSelector() {
        @Override
        public void select(Iterable<Node> nodes) {
            // Intentionally does nothing
        }

        @Override
        public String toString() {
            return "ANY";
        }
    };

    /**
     * Selector that matches any node that has metadata and doesn't
     * have the {@code master} role OR it has the data {@code data}
     * role.
     */
    NodeSelector SKIP_DEDICATED_MASTERS = new NodeSelector() {
        @Override
        public void select(Iterable<Node> nodes) {
            for (Iterator<Node> itr = nodes.iterator(); itr.hasNext();) {
                Node node = itr.next();
                if (node.getRoles() == null) continue;
                if (node.getRoles().isMasterEligible()
                        && false == node.getRoles().isData()
                        && false == node.getRoles().isIngest()) {
                    itr.remove();
                }
            }
        }

        @Override
        public String toString() {
            return "SKIP_DEDICATED_MASTERS";
        }
    };
}
  • The NodeSelector interface defines the select method, which receives mutable Iterable, and then the specific implementation will selectively delete node; ; It defines two anonymous implementation classes, ANY and SKIP_DEDICATED_MASTERS, in which ANY’s select method does nothing; The select method of SKIP_DEDICATED_MASTERS deletes masternode with date false and ingest false; In addition, there are two implementation classes: HasAttributeNodeSelector and PreferHasAttributeNodeSelector.

HasAttributeNodeSelector

elasticsearch-7.0.1/client/rest/src/main/java/org/elasticsearch/client/HasAttributeNodeSelector.java

public final class HasAttributeNodeSelector implements NodeSelector {
    private final String key;
    private final String value;

    public HasAttributeNodeSelector(String key, String value) {
        this.key = key;
        this.value = value;
    }

    @Override
    public void select(Iterable<Node> nodes) {
        Iterator<Node> itr = nodes.iterator();
        while (itr.hasNext()) {
            Map<String, List<String>> allAttributes = itr.next().getAttributes();
            if (allAttributes == null) continue;
            List<String> values = allAttributes.get(key);
            if (values == null || false == values.contains(value)) {
                itr.remove();
            }
        }
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        HasAttributeNodeSelector that = (HasAttributeNodeSelector) o;
        return Objects.equals(key, that.key) &&
                Objects.equals(value, that.value);
    }

    @Override
    public int hashCode() {
        return Objects.hash(key, value);
    }

    @Override
    public String toString() {
        return key + "=" + value;
    }
}
  • HasAttributeNodeSelector implements NodeSelector interface, its constructor receives key and value parameters, and its select method will delete node whose attributes do not have the key or whose corresponding value is null.

PreferHasAttributeNodeSelector

elasticsearch-7.0.1/client/rest/src/main/java/org/elasticsearch/client/PreferHasAttributeNodeSelector.java

public final class PreferHasAttributeNodeSelector implements NodeSelector {
    private final String key;
    private final String value;

    public PreferHasAttributeNodeSelector(String key, String value) {
        this.key = key;
        this.value = value;
    }

    @Override
    public void select(Iterable<Node> nodes) {
        boolean foundAtLeastOne = false;

        for (Node node : nodes) {
            Map<String, List<String>> attributes = node.getAttributes();

            if (attributes == null) {
                continue;
            }

            List<String> values = attributes.get(key);

            if (values == null) {
                continue;
            }

            if (values.contains(value)) {
                foundAtLeastOne = true;
                break;
            }
        }

        if (foundAtLeastOne) {
            Iterator<Node> nodeIterator = nodes.iterator();
            while (nodeIterator.hasNext()) {
                Map<String, List<String>> attributes = nodeIterator.next().getAttributes();

                if (attributes == null) {
                    continue;
                }

                List<String> values = attributes.get(key);

                if (values == null || !values.contains(value)) {
                    nodeIterator.remove();
                }
            }
        }
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        PreferHasAttributeNodeSelector that = (PreferHasAttributeNodeSelector) o;
        return Objects.equals(key, that.key) &&
            Objects.equals(value, that.value);
    }

    @Override
    public int hashCode() {
        return Objects.hash(key, value);
    }

    @Override
    public String toString() {
        return key + "=" + value;
    }
}
  • Preferential PreferHasAttributeNodeSelector implements NodeSelector interface, its constructor receives key and value parameters, and its select method will first traverse nodes to set foundateastone. if foundateastone is true, node’s attributes will be deleted without the key or node with null value corresponding to the key.

Summary

  • The NodeSelector interface defines the select method, which receives mutable Iterable, and then the specific implementation will selectively delete node; ; It defines two anonymous implementation classes, ANY and SKIP_DEDICATED_MASTERS, in which ANY’s select method does nothing. The select method of SKIP_DEDICATED_MASTERS deletes master node with date false and ingest false.
  • HasAttributeNodeSelector implements NodeSelector interface, its constructor receives key and value parameters, and its select method will delete node whose attributes do not have the key or whose corresponding value is null.
  • Preferential PreferHasAttributeNodeSelector implements NodeSelector interface, its constructor receives key and value parameters, and its select method will first traverse nodes to set foundateastone. if foundateastone is true, node’s attributes will be deleted without the key or node with null value corresponding to the key.

doc