How I Built a Groovy Script to Parse Zookeeper XML Configs for MySQL

After completing a DOM‑based XML parsing class, I tackled the messy Zookeeper configuration hierarchy for MySQL services, exposing unexpected node structures, missing values, and hundreds of database settings, and finally crafted a Groovy script that traverses the XML, filters relevant keys, and logs the extracted configuration details.

FunTester
FunTester
FunTester
How I Built a Groovy Script to Parse Zookeeper XML Configs for MySQL

Yesterday I finished a DOM‑based XML parsing class and immediately put it to work on the Zookeeper configuration used by many services, only to discover a large number of hidden pitfalls.

The configuration hierarchy follows a root node, then service nodes, each containing version nodes, followed by change and unchange nodes. Under these, every child is a zknode element, and many entries lack a value attribute, making extraction non‑trivial.

Below are screenshots of the Zookeeper configuration tree:

ZK configuration screenshot 1
ZK configuration screenshot 1
ZK configuration screenshot 2
ZK configuration screenshot 2

Extracted XML fragments reveal dozens of zknode entries such as datadb.username, db.host.r, DB_CONNECTION, and many MySQL‑related keys. The author notes that the file contains over a hundred different database configuration items.

After repeated attempts, a Groovy script was created to automate the extraction:

package com.fun.ztest.groovy

import com.fun.frame.httpclient.FanLibrary
import com.fun.utils.XMLUtil
import org.slf4j.Logger
import org.slf4j.LoggerFactory

class Td extends FanLibrary {
    private static Logger logger = LoggerFactory.getLogger(Td.class)

    public static void main(String[] args) {
        def xml = XMLUtil.parseXml("/Users/fv/Downloads/d.xml", "root")
        xml.get(0).getChildren().each {
            logger.error("服务名:{}", it.getAttrs().get(0).getValue())
            def children = it.getChildren()
            children.each { child ->
                def attr1 = child.getAttrs()
                def name = attr1.get(0).getValue()
                if (name ==~ /[vV]\d.\d+/) {
                    logger.error("zk版本:${name}")
                    def children1 = child.getChildren()
                    children1.each { sub ->
                        def children2 = sub.getChildren()
                        children2.each { leaf ->
                            def attrs = leaf.getAttrs()
                            if (attrs.size() > 1) {
                                def var = attrs.get(0).getValue()
                                def value = attrs.get(1).getValue()
                                if (!(value ==~ /\d+/)) {
                                    if (var.contains("druid") || var.contains("db") || var.contains("user") ||
                                        value.contains("mysql") || value.contains("neworiental")) {
                                        if (!value.contains("{") && !value.contains(".txt") &&
                                            !var.contains("service") && !var.contains("maill") &&
                                            !var.contains("host") && !var.contains("driver") &&
                                            !var.contains("filters") && !var.contains("center") &&
                                            !var.contains("rabbit") && !var.contains("order") &&
                                            !value.contains("http")) {
                                            logger.info("key: {},value: {}", var, value)
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        testOver()
    }
}

The script loads the XML file, iterates through each service version, and then walks the nested zknode elements. It filters keys that contain keywords like “druid”, “db”, or “user” while excluding entries that appear to be placeholders, file references, or unrelated configuration items. Matching key‑value pairs are logged for further processing.

In the end, the author acknowledges the frustration of dealing with such a chaotic configuration but confirms that the script resolves the problem, humorously noting the need for a widescreen monitor to handle the output.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Configuration ManagementZooKeepermysqlGroovyXML parsing
FunTester
Written by

FunTester

10k followers, 1k articles | completely useless

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.