Skip to content

Commit

Permalink
dev: streamlin e xml config generator
Browse files Browse the repository at this point in the history
  • Loading branch information
sunsingerus committed Oct 10, 2024
1 parent eb46090 commit 8287079
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 53 deletions.
22 changes: 8 additions & 14 deletions pkg/apis/clickhouse.altinity.com/v1/type_setting_scalar.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,16 @@ const (
)

func parseSettingScalarValue(untyped any) (string, bool) {
var scalarValue string
var isKnownType bool

typeOf := reflect.TypeOf(untyped)
if typeOf == nil {
// Unable to determine type of the value
return "", false
}

switch untyped.(type) {
case fmt.Stringer:
stringer := untyped.(fmt.Stringer)
return fmt.Sprintf("%s", stringer), true
case // scalar
int, uint,
int8, uint8,
Expand All @@ -73,8 +73,7 @@ func parseSettingScalarValue(untyped any) (string, bool) {
int64, uint64,
bool,
string:
scalarValue = fmt.Sprintf("%v", untyped)
isKnownType = true
return fmt.Sprintf("%v", untyped), true
case // scalar
float32:
floatVal := untyped.(float32)
Expand All @@ -83,13 +82,12 @@ func parseSettingScalarValue(untyped any) (string, bool) {
_, frac := math.Modf(float64(floatVal))
if frac > ignoreThreshold {
// Consider it float
scalarValue = fmt.Sprintf("%f", untyped)
return fmt.Sprintf("%f", untyped), true
} else {
// Consider it int
intVal := int64(floatVal)
scalarValue = fmt.Sprintf("%v", intVal)
return fmt.Sprintf("%v", intVal), true
}
isKnownType = true
case // scalar
float64:
floatVal := untyped.(float64)
Expand All @@ -98,18 +96,14 @@ func parseSettingScalarValue(untyped any) (string, bool) {
_, frac := math.Modf(floatVal)
if frac > ignoreThreshold {
// Consider it float
scalarValue = fmt.Sprintf("%f", untyped)
return fmt.Sprintf("%f", untyped), true
} else {
// Consider it int
intVal := int64(floatVal)
scalarValue = fmt.Sprintf("%v", intVal)
return fmt.Sprintf("%v", intVal), true
}
isKnownType = true
}

if isKnownType {
return scalarValue, true
}
return "", false
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/model/chi/config/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ func (c *Generator) getRemoteServersReplica(host *chi.Host, b *bytes.Buffer) {
// getRemoteServers creates "remote_servers.xml" content and calculates data generation parameters for other sections
func (c *Generator) getRemoteServers(selector *config.HostSelector) string {
if selector == nil {
selector = defaultIncludeAllSelector()
selector = defaultSelectorIncludeAll()
}

b := &bytes.Buffer{}
Expand Down
2 changes: 1 addition & 1 deletion pkg/model/chi/config/generator_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@ type GeneratorOptions struct {
Files *api.Settings
}

func defaultIncludeAllSelector() *config.HostSelector {
func defaultSelectorIncludeAll() *config.HostSelector {
return config.NewHostSelector()
}
39 changes: 11 additions & 28 deletions pkg/model/chk/config/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,10 @@ package config
import (
"bytes"
"fmt"
"github.com/altinity/clickhouse-operator/pkg/model/common/config"
"strings"

log "github.com/altinity/clickhouse-operator/pkg/announcer"
chi "github.com/altinity/clickhouse-operator/pkg/apis/clickhouse.altinity.com/v1"
"github.com/altinity/clickhouse-operator/pkg/interfaces"
"github.com/altinity/clickhouse-operator/pkg/model/common/config"
"github.com/altinity/clickhouse-operator/pkg/util"
)

Expand Down Expand Up @@ -75,48 +73,33 @@ func (c *Generator) getSectionFromFiles(section chi.SettingsSection, includeUnsp
// getRaftConfig builds raft config for the chk
func (c *Generator) getRaftConfig(selector *config.HostSelector) string {
if selector == nil {
selector = defaultIncludeAllSelector()
selector = defaultSelectorIncludeAll()
}

// Prepare empty placeholder for RAFT config which will be replaced later with real raft config
// <raft_configuration>
// <server></server>
// </raft_configuration>
config := chi.NewSettings().Set("keeper_server/raft_configuration/server", chi.NewSettingScalar("")).ClickHouseConfig()

// Prepare RAFT config
// 3-rd level (keeper_server/raft_configuration/server) by 4 spaces
raftIndent := 12
// Prepare RAFT config for injection into main config
// Indent is 12 = 3-rd level (clickhouse/keeper_server/raft_configuration) by 4 spaces
i := 12
raft := &bytes.Buffer{}
c.cr.WalkHosts(func(host *chi.Host) error {
msg := fmt.Sprintf("SKIP host from RAFT servers: %s", host.GetName())
if selector.Include(host) {
util.Iline(raft, raftIndent, "<server>")
util.Iline(raft, raftIndent, " <id>%d</id>", getServerId(host))
util.Iline(raft, raftIndent, " <hostname>%s</hostname>", c.namer.Name(interfaces.NameInstanceHostname, host))
util.Iline(raft, raftIndent, " <port>%d</port>", host.RaftPort.Value())
util.Iline(raft, raftIndent, "</server>")
util.Iline(raft, i, "<server>")
util.Iline(raft, i, " <id>%d</id>", getServerId(host))
util.Iline(raft, i, " <hostname>%s</hostname>", c.namer.Name(interfaces.NameInstanceHostname, host))
util.Iline(raft, i, " <port>%d</port>", host.RaftPort.Value())
util.Iline(raft, i, "</server>")
msg = fmt.Sprintf("Add host to RAFT servers: %s", host.GetName())
}
log.V(1).M(host).Info(msg)
return nil
})

// Inject RAFT config
// Replace empty placeholder for RAFT config with actual RAFT config value
// <raft_configuration>
// <server></server>
// </raft_configuration>
// TODO use raftIndent value here instead of spaces
return strings.Replace(config, " <server></server>\n", raft.String(), 1)
return chi.NewSettings().Set("keeper_server/raft_configuration", chi.MustNewSettingScalarFromAny(raft)).ClickHouseConfig()
}

// getHostServerId builds server id config for the host
func (c *Generator) getHostServerId(host *chi.Host) string {
settings := chi.NewSettings()
settings.Set("keeper_server/server_id", chi.MustNewSettingScalarFromAny(getServerId(host)))
return settings.ClickHouseConfig()
return chi.NewSettings().Set("keeper_server/server_id", chi.MustNewSettingScalarFromAny(getServerId(host))).ClickHouseConfig()
}

func getServerId(host *chi.Host) int {
Expand Down
2 changes: 1 addition & 1 deletion pkg/model/chk/config/generator_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ type GeneratorOptions struct {
Files *api.Settings
}

func defaultIncludeAllSelector() *config.HostSelector {
func defaultSelectorIncludeAll() *config.HostSelector {
return config.NewHostSelector()
}
32 changes: 24 additions & 8 deletions pkg/xml/xml.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"regexp"
"sort"
"strings"

"github.com/altinity/clickhouse-operator/pkg/util"
)

type xmlNode struct {
Expand Down Expand Up @@ -182,16 +184,30 @@ func (n *xmlNode) writeTagNoValue(w io.Writer, attributes string, indent, tabSiz
// writeTagWithValue prints tag with value. But it must have no children,
// and children are not printed
// <tag>value</tag>
// OR
// <tag>
// long value NB - printed w/o indent
// </tag>
func (n *xmlNode) writeTagWithValue(w io.Writer, value string, attributes string, indent, tabSize uint8) {
// TODO fix this properly
// Used in tests
if value == "_removed_" || value == "_remove_" {
attributes = " remove=\"1\""
value = ""
}
n.writeTagOpen(w, indent, attributes, noEol)
n.writeValue(w, value)
n.writeTagClose(w, 0, eol)
if len(value) < 10 {
// <tag>value</tag>
n.writeTagOpen(w, indent, attributes, noEol)
n.writeValue(w, value)
n.writeTagClose(w, 0, eol)
} else {
// <tag>
// long value NB - printed w/o indent
// </tag>
n.writeTagOpen(w, indent, attributes, eol)
n.writeValue(w, value)
n.writeTagClose(w, indent, eol)
}
}

// writeTagOpen prints open XML tag into io.Writer
Expand All @@ -217,24 +233,24 @@ func (n *xmlNode) writeTag(w io.Writer, indent uint8, attributes string, openTag
if openTag {
// pattern would be: %4s<%s%s>%s
pattern = fmt.Sprintf("%%%ds<%%s%%s>%%s", indent)
_, _ = fmt.Fprintf(w, pattern, " ", n.tag, attributes, eol)
util.Fprintf(w, pattern, " ", n.tag, attributes, eol)
} else {
// pattern would be: %4s</%s>%s
pattern = fmt.Sprintf("%%%ds</%%s>%%s", indent)
_, _ = fmt.Fprintf(w, pattern, " ", n.tag, eol)
util.Fprintf(w, pattern, " ", n.tag, eol)
}
} else {
if openTag {
// pattern would be: <%s%s>%s
_, _ = fmt.Fprintf(w, "<%s%s>%s", n.tag, attributes, eol)
util.Fprintf(w, "<%s%s>%s", n.tag, attributes, eol)
} else {
// pattern would be: </%s>%s
_, _ = fmt.Fprintf(w, "</%s>%s", n.tag, eol)
util.Fprintf(w, "</%s>%s", n.tag, eol)
}
}
}

// writeValue prints XML value into io.Writer
func (n *xmlNode) writeValue(w io.Writer, value string) {
_, _ = fmt.Fprintf(w, "%s", value)
util.Fprintf(w, "%s", value)
}

0 comments on commit 8287079

Please sign in to comment.