Создание фильтра транзакций в PHP для создания объекта GetTransactionsRequest - PullRequest
1 голос
/ 08 марта 2019

Я пишу клиент, который отправляет запросы в книгу DA. Я следую совету, который получил в предыдущем посте Выполнение CRUD на регистре DA через клиента gRPC .
Мне нужно запустить RPT «GetTransactions». Для этого требуется объект GetTransactionsRequest. У объекта GetTransactionsRequest есть обязательное свойство с именем 'filter', которое имеет тип TransactionFilter. У меня проблемы с созданием фильтра транзакций для удовлетворения моих потребностей. Файл .proto для него:

// Used for filtering Transaction and Active Contract Set streams.
// Determines which on-ledger events will be served to the client.

message TransactionFilter {

  // Keys of the map determine which parties' on-ledger transactions are being queried.
  // Values of the map determine which events are disclosed in the stream per party.
  // At the minimum, a party needs to set an empty Filters message to receive any events.
  // Required
  map<string, Filters> filters_by_party = 1;
}

требуется одно-единственное поле 'filters_by_party'. Установка этого поля в php требует следующей функции:

/**
     * Keys of the map determine which parties' on-ledger transactions are being queried.
     * Values of the map determine which events are disclosed in the stream per party.
     * At the minimum, a party needs to set an empty Filters message to receive any events.
     * Required
     *
     * Generated from protobuf field <code>map<string, .com.digitalasset.ledger.api.v1.Filters> filters_by_party = 1;</code>
     * @param array|\Google\Protobuf\Internal\MapField $var
     * @return $this
     */
    public function setFiltersByParty($var)
    {
        $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::MESSAGE, \Com\Digitalasset\Ledger\Api\V1\Filters::class);
        $this->filters_by_party = $arr;

        return $this;
    }

Функция php для установки значений в объекте mapFiled:

/**
     * Assign the element at the given key.
     *
     * This will also be called for: $arr[$key] = $value
     *
     * @param object $key The key of the element to be fetched.
     * @param object $value The element to be assigned.
     * @return void
     * @throws ErrorException Invalid type for key.
     * @throws ErrorException Invalid type for value.
     * @throws ErrorException Non-existing key.
     */
    public function offsetSet($key, $value)
    {
        $this->checkKey($this->key_type, $key);

        switch ($this->value_type) {
            case GPBType::SFIXED32:
            case GPBType::SINT32:
            case GPBType::INT32:
            case GPBType::ENUM:
                GPBUtil::checkInt32($value);
                break;
            case GPBType::FIXED32:
            case GPBType::UINT32:
                GPBUtil::checkUint32($value);
                break;
            case GPBType::SFIXED64:
            case GPBType::SINT64:
            case GPBType::INT64:
                GPBUtil::checkInt64($value);
                break;
            case GPBType::FIXED64:
            case GPBType::UINT64:
                GPBUtil::checkUint64($value);
                break;
            case GPBType::FLOAT:
                GPBUtil::checkFloat($value);
                break;
            case GPBType::DOUBLE:
                GPBUtil::checkDouble($value);
                break;
            case GPBType::BOOL:
                GPBUtil::checkBool($value);
                break;
            case GPBType::STRING:
                GPBUtil::checkString($value, true);
                break;
            case GPBType::MESSAGE:
                if (is_null($value)) {
                  trigger_error("Map element cannot be null.", E_USER_ERROR);
                }
                GPBUtil::checkMessage($value, $this->klass);
                break;
            default:
                break;
        }

        $this->container[$key] = $value;
    }

Как мне, например, настроить имена сторон "торговец1" и "дилер2" в качестве моих партий для filters_by_party. Я попробовал следующий код:

$parties= new Google\Protobuf\Internal\MapField(Google\Protobuf\Internal\GPBType::STRING,Google\Protobuf\Internal\GPBType::MESSAGE); 
$parties->offsetSet(0,"dealer1"); 
$parties->offsetSet(1,"dealer2"); 

приводит к следующей ошибке:

PHP Fatal error:  Given value is not message. in /home/vantage/damlprojects/loaner_car/php/ledger_client.php on line 85

Я не понимаю, почему «сообщение» требуется функцией set_by_party filter_by_party. Я не знаю, как написать имя дилера в форме «сообщения». Кажется, делать что-то, что должно быть простым, очень сложно. Как правильно настроить входную переменную $ var для функции 'setFiltersByParty'?

Ответы [ 2 ]

1 голос
/ 09 марта 2019

Может быть, вы можете найти некоторую информацию здесь: https://developers.google.com/protocol-buffers/docs/reference/php-generated#fields

Для поля карты, я думаю, это будет выглядеть примерно так:

$m->getFiltersByParty()["string"] = new Filters();
0 голосов
/ 12 марта 2019

Код для установки параметров дилера1 и дилера2 должен выглядеть следующим образом:

$parties= new Google\Protobuf\Internal\MapField(Google\Protobuf\Internal\GPBType::STRING,
   Google\Protobuf\Internal\GPBType::MESSAGE, "Com\Digitalasset\Ledger\Api\V1\Filters");

$partyIdentifier = new Com\Digitalasset\Ledger\Api\V1\Identifier();
$partyIdentifier->setPackageId($the_package_id); //last one from ListPackages()
$partyIdentifier->setEntityName("<Module>");  //from DAML code
$partyIdentifier->setModuleName("<Template>"); //from DAML code


$partyInclusiveFilters = new Com\Digitalasset\Ledger\Api\V1\InclusiveFilters();
$partyInclusiveFilters->setTemplateIds(array($partyIdentifier));

$partyFilters = new Com\Digitalasset\Ledger\Api\V1\Filters();
$partyFilters->setInclusive($partyInclusiveFilters);

$parties->offsetSet("dealer1",$partyFilters);
$parties->offsetSet("dealer2",$partyFilters);

Важно установить третий параметр конструктора MapField равным «Com \ Digitalasset \ Ledger \ Api \».V1 \ Filters».Как показывает файл protobuf:

message TransactionFilter {

          // Keys of the map determine which parties' on-ledger transactions are being queried.
          // Values of the map determine which events are disclosed in the stream per party.
          // At the minimum, a party needs to set an empty Filters message to receive any events.
          // Required
          map<string, Filters> filters_by_party = 1;
        }

Filter_by_party - это MapField, который имеет тип_значения «Фильтр».«Фильтр» - это тип сообщения (см. Ваш файлaction_filter.proto), поэтому конструктор MapField должен знать, какой это тип сообщения.

Имя дилера не записывается в форме «сообщения», а является ключом-значением в MapField «filters_by_party», которое соответствует объекту «Фильтр».А «Фильтр» - это тип сообщения.Я думаю, «простой» - это относительный термин.

...