Можно ли проверить значение enum в файле proto? - PullRequest
0 голосов
/ 05 июня 2019

Я хотел бы проверить значения перечисления в сгенерированном коде Java. У меня есть следующий файл прото:

syntax = "proto3";

import "google/protobuf/empty.proto";

option java_multiple_files = true;
option java_package = "com.package";

package helloworld;

service SomeService {
    rpc DoAction (Request) returns (google.protobuf.Empty) { }
}

enum Currency {
    EUR = 0;
    GBP = 1;
    USD = 2;
}

message Request {
    string id = 1;
    Currency currency = 2;
}

Я хотел бы получить некоторую проверку перечисления Currency в коде, который генерируется с помощью protobuf, и удалить сообщение об ошибке в случае, если значение не применимо к предоставленному перечислению (например: invalid currency). Возможно ли это?

1 Ответ

0 голосов
/ 07 июня 2019

Вы можете проверить его, но вы также должны знать о нюансах перечислений Protobuf. * ​​1001 *

  1. Всегда включайте значение перечисления UNKNOWN = 0; для каждого перечисления. Когда Protobuf не знает, чему соответствует значение enum, он устанавливает его в значение по умолчанию. Это позволяет определить, когда новый клиент с новыми кодами использует значение, которое сервер не понимает. Кроме того, если поле не установлено, оно, естественно, равно UNKNOWN, что позволяет проверить, отсутствует ли поле. (Если вы хотите разрешить отсутствующие перечисления, оберните их в message{}).

  2. В обработчике приложения вашего сервера вы должны проверить, какое из поддерживаемых значений предоставил клиент. В случае, если это не один из них, вы должны выйти из строя RPC с кодом состояния INVALID_ARGUMENT:

    out: {
      switch (req.getCurrency()) {
        case EUR: 
        case GBP:
        case USD: break out;
        case UNKNOWN:
          responseObserver.onError(
              Status.INVALID_ARGUMENT
                  .withDescription("bad currency " + req.getCurrency())
                  .asRuntimeException());
          return;
      }
      throw new AssertionError("missed case!");
    }
    // keep handling the request

Этот код проверяет, является ли этот код одним из поддерживаемых. Если поступит неподдерживаемый код, он будет обработан в случае UNKNOWN и вернет ошибку раньше. В случае, если вы изменяете свой прото и добавляете больше случаев, статический анализ обнаружит отсутствующий случай (или выдаст ошибку AssertionError). Обратите внимание, что не произойдет , если клиент обновит свой прото. Избегайте использования кейса default, потому что его можно легко пропустить при модификации proto. Кроме того, вы можете поместить все поддерживаемые случаи в карту и проверить, присутствует ли она.

...