Golang protojson:protoregistry.GlobalTypes 如何加载类型?

问题描述 投票:0回答:1

我正在尝试将 Envoy 配置从 JSON 解组为 Golang 原型结构。 JSON 有一个包含类型信息的 Any 字段。我知道 protojson 以某种方式神奇地确定了二进制文件中的 proto 定义。在下面的情况下,我收到错误。

Error:          Expected nil, but got: &errors.prefixError{s:"(line 23:46): unable to resolve \"type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog\": \"not found\""}

package play

import (
    "testing"

    "github.com/stretchr/testify/require"
    "google.golang.org/protobuf/encoding/protojson"

    listener "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
    // _ "github.com/envoyproxy/go-control-plane/envoy/extensions/access_loggers/file/v3"
)

var listnerJSONWithAccessLog = `
{
    "name": "lis1",
    "address": {
        "socket_address": {
            "address": "127.0.0.1",
            "port_value": 9999
        }
    },
    "filter_chains": [
        {
            "filters": [
                {
                    "name": "envoy.filters.network.http_connection_manager",
                    "typed_config": {
                        "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
                        "codec_type": "AUTO",
                        "stat_prefix": "hcm_prefix",
                        "access_log": [
                            {
                                "name": "envoy.access_loggers.file",
                                "typed_config": {
                                    "@type": "type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog",
                                    "path": "/dev/stdout"
                                }
                            }
                        ],
                        "http_filters": [
                            {
                                "name": "envoy.filters.http.router",
                                "typed_config": {
                                    "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router"
                                }
                            }
                        ],
                        "route_config": {
                            "name": "lis1_route_config",
                            "virtual_hosts": [
                                {
                                    "name": "lis1_virtual_host",
                                    "domains": [
                                        "*"
                                    ],
                                    "routes": [
                                        {
                                            "match": {
                                                "prefix": "/direct"
                                            },
                                            "direct_response": {
                                                "status": 200,
                                                "body": {
                                                    "inline_string": "hello"
                                                }
                                            }
                                        }
                                    ]
                                }
                            ]
                        }
                    }
                }
            ]
        }
    ]
}

`

func TestJSONToPB(t *testing.T) {
    t.Run("json to pb", func(t *testing.T) {
        var lis listener.Listener
        err := protojson.Unmarshal([]byte(listnerJSONWithAccessLog), &lis)
        require.Nil(t, err)
    })
}

使用

//_ github...
取消注释该行可以修复该问题。这样做的正确方法是什么?我是否需要为我尝试解组的每个可能的结构添加这样的空导入?

go protocol-buffers envoyproxy
1个回答
0
投票

您需要 protoreflect.MessageDescriptor 来表示指定的消息,在您的情况下为

envoy.extensions.access_loggers.file.v3.FileAccessLog

您会看到,您可以从 FileAccessLog.ProtoReflect(或直接从已弃用的 FileAccessLog.Descriptor)获取该信息,但您需要一个 FileAccessLog。并且您可以通过反射获得,当二进制文件中不存在该结构时,这当然会失败。

所以你需要从

某个地方获取信息。反射通常是一种很好且方便的方法。您可以直接将包导入为_

,因为您不会直接使用它,但仍然依赖于它。

© www.soinside.com 2019 - 2024. All rights reserved.