Проверка сообщения PubSub на соответствие схеме AVRO JSON с несколькими типами объединения

У меня возникли проблемы с публикацией сообщений в новой теме pubsub, связанной со схемой AVRO. Я публикую сообщение из PHP с помощью библиотеки Google\Cloud\PubSub\PubSubClient и получаю сообщение об ошибке:

{
  "error": {
    "code": 400,
    "message": "Invalid data in message: Message failed schema validation.",
    "status": "INVALID_ARGUMENT",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "reason": "INVALID_JSON_AVRO_MESSAGE",
        "domain": "pubsub.googleapis.com",
        "metadata": {
          "message": "Message failed schema validation",
          "revisionInfo": "Could not validate message with any schema revision for schema: projects/foo-project/schemas/foo-schema, last checked revision: revision_id=foo-revision-id failed with status: Invalid data in message: JSON object with type string does not match schema which expected object."
        }
      }
    ]
  }
}

Я пытался проверить свое сообщение в Google Cloud Console https://console.cloud.google.com/cloudpubsub/schema/detail/foo-schema?project=foo-project с помощью сообщения UI Test, но все комбинации возвращают ошибку : Invalid JSON -encoded message against Avro schema. без подробностей.

Добавление необязательных полей со значением null не работает, перенос action_type внутри поля action не помогает. Добавление вложенного "name": null внутри account объекта также не помогает, как и любая комбинация вышеперечисленного. Я сейчас в полном отчаянии.

Интересный факт - Согласно avro_validator, сообщение имеет правильный формат.

Это мой пример сообщения:

{
    "action": "create",
    "url": "https://my-api.com/resource/new_resource_name",
    "operation": "created",
    "callback_url": "https://my-another-api/com/resource/new_resource_name",
    "name": "new_resource_name",
    "source": "service_name",
    "account": {"number": 2830602},
    "operation_metadata": "{\"created_on\":\"2024-06-24T08:47:14+00:00\"}"
}

Это схема, которую я создал в GCP:

{
  "fields": [
    {
      "name": "action",
      "type": [
        "null",
        {
          "name": "action_type",
          "symbols": [
            "create",
            "another_action_type",
            "another_action_type2",
            "another_action_type3"
          ],
          "type": "enum"
        }
      ]
    },
    {
      "name": "url",
      "type": "string"
    },
    {
      "name": "operation",
      "type": {
        "name": "operation_type",
        "symbols": [
          "created",
          "another_operation_type",
          "another_operation_type2",
          "another_operation_type3"
        ],
        "type": "enum"
      }
    },
    {
      "name": "callback_url",
      "type": "string"
    },
    {
      "name": "name",
      "type": "string"
    },
    {
      "default": "default_service_name",
      "name": "source",
      "type": {
        "name": "source_service",
        "symbols": [
          "service_name1",
          "service_name2"
        ],
        "type": "enum"
      }
    },
    {
      "default": null,
      "name": "homepage_url",
      "type": [
        "null",
        "string"
      ]
    },
    {
      "default": null,
      "name": "account",
      "type": [
        "null",
        {
          "fields": [
            {
              "default": null,
              "name": "number",
              "type": [
                "null",
                "int"
              ]
            },
            {
              "default": null,
              "name": "name",
              "type": [
                "null",
                "string"
              ]
            }
          ],
          "name": "account_record",
          "type": "record"
        }
      ]
    },
    {
      "default": null,
      "name": "cluster",
      "type": [
        "null",
        {
          "fields": [
            {
              "default": null,
              "name": "number",
              "type": [
                "null",
                "int"
              ]
            }
          ],
          "name": "cluster_record",
          "type": "record"
        }
      ]
    },
    {
      "default": null,
      "name": "type",
      "type": [
        "null",
        {
          "name": "environment_type",
          "symbols": [
            "DEVELOPMENT",
            "STAGING",
            "PRODUCTION"
          ],
          "type": "enum"
        }
      ]
    },
    {
      "default": null,
      "name": "error",
      "type": [
        "null",
        "string"
      ]
    },
    {
      "default": null,
      "name": "operation_metadata",
      "type": [
        "null",
        "string"
      ]
    }
  ],
  "name": "MyFooEvents",
  "type": "record"
}

Если у кого-то есть идеи, пожалуйста, дайте мне подсказку.

Привет @gregp! Похоже, этот вопрос требует дальнейшего изучения, поэтому, если у вас есть план поддержки, создайте новый запрос на поддержку GCP . В противном случае вы можете открыть новую проблему в трекере проблем с описанием вашей проблемы.

Dhiraj Singh 24.06.2024 15:32
Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
0
1
92
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В сообщении есть несколько проблем:

  1. Он не соответствует правилам кодирования JSON для сообщений Avro . При кодировании объединений необходимо указать тип как вложенный объект.
  2. "service_name" не является допустимым значением перечисления для поля "source".
  3. Не хватает нескольких полей. Даже если они имеют значение NULL, они должны присутствовать в JSON.

Вот действительная версия сообщения:

{
    "action": {
      "action_type": "create"
    },
    "url": "https://my-api.com/resource/new_resource_name",
    "operation": "created",
    "callback_url": "https://my-another-api/com/resource/new_resource_name",
    "homepage_url": null,
    "name": "new_resource_name",
    "source": "service_name1",
    "account": {
      "account_record": {
        "number": {
          "int": 2830602
        },
        "name": null
      }
    },
    "cluster": null,
    "type": null,
    "operation_metadata": {
      "string": "{\"created_on\":\"2024-06-24T08:47:14+00:00\"}"
    },
    "error": null
}

Другие вопросы по теме