Skip to content

Commit

Permalink
Handle protojson formatting on server side
Browse files Browse the repository at this point in the history
Signed-off-by: Matt Lord <[email protected]>
  • Loading branch information
mattlord committed May 17, 2024
1 parent 98ba421 commit edb127e
Show file tree
Hide file tree
Showing 5 changed files with 10 additions and 212 deletions.
66 changes: 0 additions & 66 deletions go/cmd/vtctldclient/cli/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ import (

"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"

"vitess.io/vitess/go/stats"
)

const (
Expand Down Expand Up @@ -79,67 +77,3 @@ func MarshalJSONPretty(obj any) ([]byte, error) {
marshalOptions.UseEnumNumbers = false
return MarshalJSON(obj, marshalOptions)
}

// ConvertToSnakeCase converts strings to snake_case. This is useful when converting
// generic JSON data marshalled to a map[string]interface{} for printing so that we
// retain the snake_case used with protobufs and protojson.
func ConvertToSnakeCase(val any) (any, error) {
switch val := val.(type) {
case string:
skval := stats.GetSnakeName(val)
return skval, nil
case map[string]any:
for k, v := range val {
sk := stats.GetSnakeName(k)
// We need to recurse into the map to convert nested maps
// to snake_case.
sv, err := ConvertToSnakeCase(v)
if err != nil {
return nil, err
}
delete(val, k)
val[sk] = sv
}
return val, nil
case map[any]any:
for k, v := range val {
// We need to recurse into the key to support more complex
// key types.
sk, err := ConvertToSnakeCase(k)
if err != nil {
return nil, err
}
// We need to recurse into the map to convert nested types
// to snake_case.
sv, err := ConvertToSnakeCase(v)
if err != nil {
return nil, err
}
delete(val, k)
val[sk] = sv
}
return val, nil
case []string:
for i, v := range val {
// We need to recurse into the slice to convert nested maps
// to snake_case.
sk := stats.GetSnakeName(v)
val[i] = sk
}
return val, nil
case []any:
for i, v := range val {
// We need to recurse into the slice to convert complex types
// to snake_case.
sv, err := ConvertToSnakeCase(v)
if err != nil {
return nil, err
}
val[i] = sv
}
return val, nil
default:
// No need to do any conversion for things like bool.
return val, nil
}
}
129 changes: 0 additions & 129 deletions go/cmd/vtctldclient/cli/json_test.go

This file was deleted.

16 changes: 1 addition & 15 deletions go/cmd/vtctldclient/command/topology.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@ limitations under the License.
package command

import (
"encoding/json"
"fmt"

"github.com/pkg/errors"
"github.com/spf13/cobra"

"vitess.io/vitess/go/cmd/vtctldclient/cli"
Expand Down Expand Up @@ -63,19 +61,7 @@ func commandGetTopologyPath(cmd *cobra.Command, args []string) error {
if resp.GetCell() == nil || resp.GetCell().GetData() == "" {
return fmt.Errorf("no data found for path %s", path)
}
m := make(map[string]any)
if err := json.Unmarshal([]byte(resp.GetCell().GetData()), &m); err != nil {
return errors.Wrap(err, "failed to unmarshal node data as JSON")
}
skm, err := cli.ConvertToSnakeCase(m)
if err != nil {
return errors.Wrap(err, "failed to convert names to snake case")
}
js, err := json.MarshalIndent(skm, "", " ")
if err != nil {
return errors.Wrap(err, "failed to marshal JSON data")
}
fmt.Println(string(js))
fmt.Println(resp.GetCell().GetData())
return nil
}

Expand Down
9 changes: 8 additions & 1 deletion go/vt/topo/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,14 @@ func DecodeContent(filename string, data []byte, json bool) (string, error) {
var marshalled []byte
var err error
if json {
marshalled, err = protojson.Marshal(p)
// Maintain snake_case for the JSON output as this keeps the output consistent across
// vtctldclient commands and it is needed if the returned value is used as input to
// vtctldclient, e.g. for ApplyRoutingRules.
pm := protojson.MarshalOptions{
Indent: " ",
UseProtoNames: true,
}
marshalled, err = pm.Marshal(p)
} else {
marshalled, err = prototext.Marshal(p)
}
Expand Down
2 changes: 1 addition & 1 deletion go/vt/vtctl/grpcvtctldserver/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7859,7 +7859,7 @@ func TestGetTopologyPath(t *testing.T) {
Cell: &vtctldatapb.TopologyCell{
Name: "Tablet",
Path: "/cell1/tablets/cell1-0000000100/Tablet",
Data: `{"alias":{"cell":"cell1","uid":100},"hostname":"localhost","keyspace":"keyspace1","mysqlHostname":"localhost","mysqlPort":17100}`,
Data: "{\n \"alias\": {\n \"cell\": \"cell1\",\n \"uid\": 100\n },\n \"hostname\": \"localhost\",\n \"keyspace\": \"keyspace1\",\n \"mysql_hostname\": \"localhost\",\n \"mysql_port\": 17100\n}",
},
},
},
Expand Down

0 comments on commit edb127e

Please sign in to comment.