All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.yahoo.vespa.model.builder.xml.dom.DomRoutingBuilder Maven / Gradle / Ivy

There is a newer version: 8.409.18
Show newest version
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.builder.xml.dom;

import com.yahoo.config.application.Xml;
import com.yahoo.config.application.api.ApplicationPackage;
import com.yahoo.config.model.ConfigModelContext;
import com.yahoo.config.model.builder.xml.ConfigModelBuilder;
import com.yahoo.config.model.builder.xml.ConfigModelId;
import com.yahoo.messagebus.routing.ApplicationSpec;
import com.yahoo.messagebus.routing.HopSpec;
import com.yahoo.messagebus.routing.RouteSpec;
import com.yahoo.messagebus.routing.RoutingSpec;
import com.yahoo.messagebus.routing.RoutingTableSpec;
import com.yahoo.text.XML;
import com.yahoo.vespa.model.routing.Routing;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.util.List;

/**
 * Builds the Routing plugin
 *
 * @author vegardh
 */
public class DomRoutingBuilder extends ConfigModelBuilder {

    public DomRoutingBuilder() {
        super(Routing.class);
    }

    @Override
    public List handlesElements() {
        return List.of(ConfigModelId.fromName("routing"));
    }

    // Overrides ConfigModelBuilder.
    @Override
    public void doBuild(Routing plugin, Element spec, ConfigModelContext modelContext) {
        ApplicationSpec app = null;
        RoutingSpec routing = null;
        if (spec != null) {
            app = new ApplicationSpec();
            for (Element node : Xml.mergeElems(spec, "services", modelContext.getApplicationPackage(), ApplicationPackage.ROUTINGTABLES_DIR)) {
                addServices(app, node);
            }
            routing = new RoutingSpec();
            for (Element node : Xml.mergeElems(spec, "routingtable", modelContext.getApplicationPackage(), ApplicationPackage.ROUTINGTABLES_DIR)) {
                addRoutingTable(routing, node);
            }
        }
        plugin.setExplicitApplicationSpec(app);
        plugin.setExplicitRoutingSpec(routing);
    }

    /**
     * This function updates the given application with the data contained in the given xml element.
     *
     * @param app The application to update.
     * @param element The element to base the services on.
     */
    private static void addServices(ApplicationSpec app, Element element) {
        String protocol = element.getAttribute("protocol");
        for (Element node : XML.getChildren(element, "service")) {
            app.addService(protocol, node.getAttribute("name"));
        }
    }

    /**
     * This function updates the given routing spec with the data contained in the given xml element.
     *
     * @param routing The routing spec to update.
     * @param element The element to base the route config on.
     */
    private static void addRoutingTable(RoutingSpec routing, Element element) {
        boolean verify = shouldVerify(element);
        RoutingTableSpec table = new RoutingTableSpec(element.getAttribute("protocol"), verify);

        NodeList children = element.getChildNodes();
        for (int i = 0; i < children.getLength(); i++) {
            Node node = children.item(i);
            if ("hop".equals(node.getNodeName())) {
                table.addHop(createHopSpec((Element)node));
            } else if ("route".equals(node.getNodeName())) {
                table.addRoute(createRouteSpec((Element)node));
            }
        }

        routing.addTable(table);
    }

    /**
     * This function creates a route from the content of the given xml element.
     *
     * @param element The element to base the route config on.
     * @return The corresponding route spec.
     */
    private static RouteSpec createRouteSpec(Element element) {
        boolean verify = shouldVerify(element);
        RouteSpec route = new RouteSpec(element.getAttribute("name"), verify);
        String hops = element.getAttribute("hops");
        int from = 0;
        for (int to = 0, depth = 0, len = hops.length(); to < len; ++to) {
            if (hops.charAt(to) == '[') {
                ++depth;
            } else if (hops.charAt(to) == ']') {
                --depth;
            } else if (hops.charAt(to) == ' ' && depth == 0) {
                if (to > from) {
                    route.addHop(hops.substring(from, to));
                }
                from = to + 1;
            }
        }
        if (from < hops.length()) {
            route.addHop(hops.substring(from));
        }
        return route;
    }

    /**
     * This function creates a hop from the content of the given xml element.
     *
     * @param element The element to base the hop config on.
     * @return The corresponding hop spec.
     */
    private static HopSpec createHopSpec(Element element) {
        boolean verify = shouldVerify(element);
        HopSpec hop = new HopSpec(element.getAttribute("name"), element.getAttribute("selector"), verify);
        if (Boolean.parseBoolean(element.getAttribute("ignore-result"))) {
            hop.setIgnoreResult(true);
        }
        NodeList children = element.getElementsByTagName("recipient");
        for (int i = 0; i < children.getLength(); i++) {
            Element node = (Element)children.item(i);
            hop.addRecipient(node.getAttribute("session"));
        }
        return hop;
    }

    private static boolean shouldVerify(Element element) {
        return !element.hasAttribute("verify") || Boolean.parseBoolean(element.getAttribute("verify"));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy