diff --git a/src/main/proto/api-linter.yaml b/src/main/proto/api-linter.yaml new file mode 100644 index 000000000..3a0ea4723 --- /dev/null +++ b/src/main/proto/api-linter.yaml @@ -0,0 +1,20 @@ +# Copyright 2022 The Cross-Media Measurement Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- included_paths: + - 'wfa/measurement/api/v2alpha/**/*.proto' + disabled_rules: + - 'core::0191::java-package' + - 'core::0127::http-annotation' + - 'core::0133::http-uri-parent' diff --git a/src/main/proto/wfa/measurement/api/v2alpha/BUILD.bazel b/src/main/proto/wfa/measurement/api/v2alpha/BUILD.bazel index 6c6ad597e..a86b30f43 100644 --- a/src/main/proto/wfa/measurement/api/v2alpha/BUILD.bazel +++ b/src/main/proto/wfa/measurement/api/v2alpha/BUILD.bazel @@ -23,6 +23,7 @@ proto_library( srcs = ["certificate.proto"], strip_import_prefix = IMPORT_PREFIX, deps = [ + "@com_google_googleapis//google/api:field_behavior_proto", "@com_google_googleapis//google/api:resource_proto", ], ) @@ -33,6 +34,7 @@ proto_library( strip_import_prefix = IMPORT_PREFIX, deps = [ ":crypto_proto", + "@com_google_googleapis//google/api:field_behavior_proto", "@com_google_googleapis//google/api:resource_proto", ], ) @@ -43,6 +45,7 @@ proto_library( strip_import_prefix = IMPORT_PREFIX, deps = [ "//src/main/proto/wfa/measurement/api/v2alpha:time_interval_proto", + "@com_google_googleapis//google/api:field_behavior_proto", "@com_google_googleapis//google/api:resource_proto", ], ) @@ -55,6 +58,7 @@ proto_library( ":crypto_proto", ":measurement_proto", ":protocol_config_proto", + "@com_google_googleapis//google/api:field_behavior_proto", "@com_google_googleapis//google/api:resource_proto", ], ) @@ -83,6 +87,7 @@ proto_library( strip_import_prefix = IMPORT_PREFIX, deps = [ ":crypto_proto", + "@com_google_googleapis//google/api:field_behavior_proto", "@com_google_googleapis//google/api:resource_proto", ], ) @@ -94,6 +99,7 @@ proto_library( deps = [ ":crypto_proto", ":measurement_consumer_proto", + "@com_google_googleapis//google/api:field_behavior_proto", "@com_google_googleapis//google/api:resource_proto", ], ) @@ -150,7 +156,6 @@ proto_library( strip_import_prefix = IMPORT_PREFIX, deps = [ ":differential_privacy_proto", - "@com_google_googleapis//google/api:resource_proto", ], ) @@ -161,6 +166,7 @@ proto_library( deps = [ ":crypto_proto", ":protocol_config_proto", + "@com_google_googleapis//google/api:field_behavior_proto", "@com_google_googleapis//google/api:resource_proto", "@com_google_protobuf//:duration_proto", ], @@ -171,6 +177,7 @@ proto_library( srcs = ["duchy.proto"], strip_import_prefix = IMPORT_PREFIX, deps = [ + "@com_google_googleapis//google/api:field_behavior_proto", "@com_google_googleapis//google/api:resource_proto", ], ) @@ -212,6 +219,7 @@ proto_library( strip_import_prefix = IMPORT_PREFIX, deps = [ ":model_suite_proto", + "@com_google_googleapis//google/api:client_proto", "@com_google_googleapis//google/api:field_behavior_proto", "@com_google_googleapis//google/api:resource_proto", ], @@ -259,6 +267,7 @@ proto_library( deps = [ ":model_rollout_proto", "//src/main/proto/wfa/measurement/api/v2alpha:time_interval_proto", + "@com_google_googleapis//google/api:client_proto", "@com_google_googleapis//google/api:field_behavior_proto", "@com_google_googleapis//google/api:resource_proto", "@com_google_protobuf//:empty_proto", @@ -283,6 +292,7 @@ proto_library( strip_import_prefix = IMPORT_PREFIX, deps = [ ":model_release_proto", + "@com_google_googleapis//google/api:client_proto", "@com_google_googleapis//google/api:field_behavior_proto", "@com_google_googleapis//google/api:resource_proto", ], @@ -293,10 +303,8 @@ proto_library( srcs = ["model_shard.proto"], strip_import_prefix = IMPORT_PREFIX, deps = [ - "//src/main/proto/wfa/measurement/api/v2alpha:time_interval_proto", "@com_google_googleapis//google/api:field_behavior_proto", "@com_google_googleapis//google/api:resource_proto", - "@com_google_protobuf//:any_proto", "@com_google_protobuf//:timestamp_proto", ], ) @@ -307,7 +315,6 @@ proto_library( strip_import_prefix = IMPORT_PREFIX, deps = [ ":model_shard_proto", - "//src/main/proto/wfa/measurement/api/v2alpha:time_interval_proto", "@com_google_googleapis//google/api:field_behavior_proto", "@com_google_googleapis//google/api:resource_proto", "@com_google_protobuf//:empty_proto", @@ -354,6 +361,7 @@ proto_library( srcs = ["exchange.proto"], strip_import_prefix = IMPORT_PREFIX, deps = [ + "@com_google_googleapis//google/api:field_behavior_proto", "@com_google_googleapis//google/api:resource_proto", "@com_google_googleapis//google/type:date_proto", ], @@ -364,6 +372,7 @@ proto_library( srcs = ["exchange_step.proto"], strip_import_prefix = IMPORT_PREFIX, deps = [ + "@com_google_googleapis//google/api:field_behavior_proto", "@com_google_googleapis//google/api:resource_proto", "@com_google_googleapis//google/type:date_proto", ], @@ -374,6 +383,7 @@ proto_library( srcs = ["exchange_step_attempt.proto"], strip_import_prefix = IMPORT_PREFIX, deps = [ + "@com_google_googleapis//google/api:field_behavior_proto", "@com_google_googleapis//google/api:resource_proto", "@com_google_protobuf//:timestamp_proto", ], @@ -410,6 +420,8 @@ proto_library( srcs = ["api_keys_service.proto"], deps = [ ":api_key_proto", + "@com_google_googleapis//google/api:client_proto", + "@com_google_googleapis//google/api:field_behavior_proto", "@com_google_googleapis//google/api:resource_proto", ], ) @@ -431,6 +443,7 @@ proto_library( strip_import_prefix = IMPORT_PREFIX, deps = [ ":requisition_proto", + "@com_google_googleapis//google/api:field_behavior_proto", "@com_google_googleapis//google/api:resource_proto", ], ) @@ -501,6 +514,8 @@ proto_library( srcs = ["recurring_exchanges_service.proto"], deps = [ ":recurring_exchange_proto", + "@com_google_googleapis//google/api:client_proto", + "@com_google_googleapis//google/api:field_behavior_proto", "@com_google_googleapis//google/api:resource_proto", ], ) diff --git a/src/main/proto/wfa/measurement/api/v2alpha/account.proto b/src/main/proto/wfa/measurement/api/v2alpha/account.proto index a172d8e39..dae64a36b 100644 --- a/src/main/proto/wfa/measurement/api/v2alpha/account.proto +++ b/src/main/proto/wfa/measurement/api/v2alpha/account.proto @@ -27,6 +27,7 @@ message Account { option (google.api.resource) = { type: "halo.wfanet.org/Account" pattern: "accounts/{account}" + plural: "accounts" }; enum View { diff --git a/src/main/proto/wfa/measurement/api/v2alpha/api_key.proto b/src/main/proto/wfa/measurement/api/v2alpha/api_key.proto index e37924cd5..ecb6f8d1c 100644 --- a/src/main/proto/wfa/measurement/api/v2alpha/api_key.proto +++ b/src/main/proto/wfa/measurement/api/v2alpha/api_key.proto @@ -27,6 +27,7 @@ message ApiKey { option (google.api.resource) = { type: "halo.wfanet.org/ApiKey" pattern: "measurementConsumers/{measurement_consumer}/apiKeys/{api_key}" + plural: "apiKeys" }; string name = 1; diff --git a/src/main/proto/wfa/measurement/api/v2alpha/api_keys_service.proto b/src/main/proto/wfa/measurement/api/v2alpha/api_keys_service.proto index 70cd69e8d..7113789c1 100644 --- a/src/main/proto/wfa/measurement/api/v2alpha/api_keys_service.proto +++ b/src/main/proto/wfa/measurement/api/v2alpha/api_keys_service.proto @@ -16,6 +16,8 @@ syntax = "proto3"; package wfa.measurement.api.v2alpha; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; import "google/api/resource.proto"; import "wfa/measurement/api/v2alpha/api_key.proto"; @@ -29,29 +31,38 @@ service ApiKeys { // // Results in PERMISSION_DENIED if the authenticated caller does not own the // `MeasurementConsumer` the `ApiKey` is being created for. - rpc CreateApiKey(CreateApiKeyRequest) returns (ApiKey) {} + rpc CreateApiKey(CreateApiKeyRequest) returns (ApiKey) { + option (google.api.method_signature) = "parent,api_key"; + } // Deletes an `ApiKey`. // // Results in PERMISSION_DENIED if the authenticated caller does not own the // `MeasurementConsumer` the `ApiKey` is being used for. - rpc DeleteApiKey(DeleteApiKeyRequest) returns (ApiKey) {} + rpc DeleteApiKey(DeleteApiKeyRequest) returns (ApiKey) { + option (google.api.method_signature) = "name"; + } } // Request message for `CreateApiKey` method. message CreateApiKeyRequest { - // Name of the parent `MeasurementConsumer`. Required. - string parent = 1 - [(google.api.resource_reference).child_type = "halo.wfanet.org/ApiKey"]; + // Name of the parent `MeasurementConsumer`. + string parent = 1 [ + (google.api.resource_reference).child_type = "halo.wfanet.org/ApiKey", + (google.api.field_behavior) = REQUIRED + ]; - // The `ApiKey` to create. Required. + // The `ApiKey` to create. // // The `name` field will be ignored, and the system will assign an ID. - ApiKey apiKey = 2; + ApiKey api_key = 2 [(google.api.field_behavior) = REQUIRED]; } +// Request message for `DeleteApiKey` method. message DeleteApiKeyRequest { - // Resource name of the `ApiKey` to delete. Required. - string name = 1 - [(google.api.resource_reference).type = "halo.wfanet.org/ApiKey"]; + // Resource name of the `ApiKey` to delete. + string name = 1 [ + (google.api.resource_reference).type = "halo.wfanet.org/ApiKey", + (google.api.field_behavior) = REQUIRED + ]; } diff --git a/src/main/proto/wfa/measurement/api/v2alpha/certificate.proto b/src/main/proto/wfa/measurement/api/v2alpha/certificate.proto index 23124ffd9..a4c809ef2 100644 --- a/src/main/proto/wfa/measurement/api/v2alpha/certificate.proto +++ b/src/main/proto/wfa/measurement/api/v2alpha/certificate.proto @@ -16,6 +16,7 @@ syntax = "proto3"; package wfa.measurement.api.v2alpha; +import "google/api/field_behavior.proto"; import "google/api/resource.proto"; option java_package = "org.wfanet.measurement.api.v2alpha"; @@ -30,6 +31,8 @@ message Certificate { pattern: "duchies/{duchy}/certificates/{certificate}" pattern: "measurementConsumers/{measurement_consumer}/certificates/{certificate}" pattern: "modelProviders/{model_provider}/certificates/{certificate}" + singular: "certificate" + plural: "certificates" }; // Resource name. @@ -39,12 +42,16 @@ message Certificate { string name = 1; // X.509 certificate in DER format. Required. Immutable. - bytes x509_der = 2; + bytes x509_der = 2 [ + (google.api.field_behavior) = REQUIRED, + (google.api.field_behavior) = IMMUTABLE + ]; // RFC 5280 revocation state. // // This is *not* a resource state as defined by https://google.aip.dev/216. enum RevocationState { + // Default value used if the revocation state is omitted. REVOCATION_STATE_UNSPECIFIED = 0; // Certificate is on hold and therefore invalid, possibly temporarily. @@ -53,11 +60,12 @@ message Certificate { // Certificate has been revoked. Terminal state. REVOKED = 2; } - // Revocation state of the certificate reported by an API caller. Output-only. + // Revocation state of the certificate reported by an API caller. // // If specified, it means that the certificate is not currently valid. // // Note that this is not guaranteed to reflect the actual revocation state // determined by the issuing certificate authority. - RevocationState revocation_state = 3; + RevocationState revocation_state = 3 + [(google.api.field_behavior) = OUTPUT_ONLY]; } diff --git a/src/main/proto/wfa/measurement/api/v2alpha/data_provider.proto b/src/main/proto/wfa/measurement/api/v2alpha/data_provider.proto index a88510b4b..439c4b926 100644 --- a/src/main/proto/wfa/measurement/api/v2alpha/data_provider.proto +++ b/src/main/proto/wfa/measurement/api/v2alpha/data_provider.proto @@ -16,6 +16,7 @@ syntax = "proto3"; package wfa.measurement.api.v2alpha; +import "google/api/field_behavior.proto"; import "google/api/resource.proto"; import "wfa/measurement/api/v2alpha/crypto.proto"; @@ -29,6 +30,7 @@ message DataProvider { option (google.api.resource) = { type: "halo.wfanet.org/DataProvider" pattern: "dataProviders/{data_provider}" + plural: "dataProviders" }; // Resource name. @@ -54,11 +56,6 @@ message DataProvider { // The list of duchies that must be included in all computations involving // this `DataProvider` - repeated string required_external_duchy_ids = 6; -} - -// Wrapper for a list of `DataProvider` resource names. -message DataProviderList { - repeated string data_provider = 1 - [(google.api.resource_reference).type = "halo.wfanet.org/DataProvider"]; + repeated string required_external_duchy_ids = 6 + [(google.api.field_behavior) = UNORDERED_LIST]; } diff --git a/src/main/proto/wfa/measurement/api/v2alpha/duchy.proto b/src/main/proto/wfa/measurement/api/v2alpha/duchy.proto index f2d4a19c2..1a08fdf87 100644 --- a/src/main/proto/wfa/measurement/api/v2alpha/duchy.proto +++ b/src/main/proto/wfa/measurement/api/v2alpha/duchy.proto @@ -16,6 +16,7 @@ syntax = "proto3"; package wfa.measurement.api.v2alpha; +import "google/api/field_behavior.proto"; import "google/api/resource.proto"; option java_package = "org.wfanet.measurement.api.v2alpha"; @@ -27,19 +28,21 @@ message Duchy { option (google.api.resource) = { type: "halo.wfanet.org/Duchy" pattern: "duchies/{duchy}" + singular: "duchy" + plural: "duchies" }; // Resource name. string name = 1; // The *preferred* X.509 certificate belonging to this `Duchy` in DER format. - // Required. - bytes preferred_certificate_der = 2; + bytes preferred_certificate_der = 2 [(google.api.field_behavior) = REQUIRED]; // Resource name of the *preferred* `Certificate` belonging to this `Duchy`. - // Output-only. // // The `x509_der` field of this resource matches `preferred_certificate_der`. - string preferred_certificate = 3 - [(google.api.resource_reference).type = "halo.wfanet.org/Certificate"]; + string preferred_certificate = 3 [ + (google.api.resource_reference).type = "halo.wfanet.org/Certificate", + (google.api.field_behavior) = OUTPUT_ONLY + ]; } diff --git a/src/main/proto/wfa/measurement/api/v2alpha/event_annotations.proto b/src/main/proto/wfa/measurement/api/v2alpha/event_annotations.proto index 9b2acd02d..a3ced40ef 100644 --- a/src/main/proto/wfa/measurement/api/v2alpha/event_annotations.proto +++ b/src/main/proto/wfa/measurement/api/v2alpha/event_annotations.proto @@ -12,6 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. +// (-- +// api-linter: core::0123::resource-annotation=disabled +// api-linter: core::0203::required=disabled +// api-linter: core::0203::immutable=disabled +// aip.dev/not-precedent: These are protobuf annotations, not API messages. +// --) + syntax = "proto3"; package wfa.measurement.api.v2alpha; @@ -20,6 +27,7 @@ import "google/protobuf/descriptor.proto"; option java_package = "org.wfanet.measurement.api.v2alpha"; option java_multiple_files = true; +option java_outer_classname = "EventAnnotationsProto"; // Descriptor for a field inside of an event template message. message EventFieldDescriptor { diff --git a/src/main/proto/wfa/measurement/api/v2alpha/event_group.proto b/src/main/proto/wfa/measurement/api/v2alpha/event_group.proto index 888590aab..22b7d235d 100644 --- a/src/main/proto/wfa/measurement/api/v2alpha/event_group.proto +++ b/src/main/proto/wfa/measurement/api/v2alpha/event_group.proto @@ -31,15 +31,21 @@ message EventGroup { option (google.api.resource) = { type: "halo.wfanet.org/EventGroup" pattern: "dataProviders/{data_provider}/eventGroups/{event_group}" + singular: "eventGroup" + plural: "eventGroups" }; // Resource name. string name = 1; // Resource name of the `MeasurementConsumer` associated with this - // `EventGroup`. Required. Immutable. - string measurement_consumer = 2 [(google.api.resource_reference).type = - "halo.wfanet.org/MeasurementConsumer"]; + // `EventGroup`. + string measurement_consumer = 2 [ + (google.api.resource_reference).type = + "halo.wfanet.org/MeasurementConsumer", + (google.api.field_behavior) = REQUIRED, + (google.api.field_behavior) = IMMUTABLE + ]; // Resource name of the `Certificate` belonging to `measurement_consumer`. // Must be set if `measurement_consumer_public_key` is set. @@ -56,29 +62,39 @@ message EventGroup { string event_group_reference_id = 5; // The set of VID model lines used to label events in this `EventGroup`. - // Required. - repeated string vid_model_lines = 6; + repeated string vid_model_lines = 6 [ + (google.api.resource_reference).type = "halo.wfanet.org/ModelLine", + (google.api.field_behavior) = UNORDERED_LIST + ]; + // Template for an event message. message EventTemplate { // The type of the Event Template. A fully-qualified protobuf message type. - // Required. - string type = 1; + string type = 1 [(google.api.field_behavior) = REQUIRED]; } // The `EventTemplate`s that events associated with this `EventGroup` conform // to. - repeated EventTemplate event_templates = 7; + repeated EventTemplate event_templates = 7 + [(google.api.field_behavior) = UNORDERED_LIST]; // Wrapper for per-EDP EventGroup metadata. message Metadata { // The resource name of the metadata descriptor. - string event_group_metadata_descriptor = 1 - [(google.api.resource_reference).type = - "halo.wfanet.org/EventGroupMetadataDescriptor"]; + string event_group_metadata_descriptor = 1 [ + (google.api.resource_reference).type = + "halo.wfanet.org/EventGroupMetadataDescriptor", + (google.api.field_behavior) = REQUIRED + ]; // A message of a type described by the descriptor along with its type URL, // encoded as an `Any` message. - google.protobuf.Any metadata = 2; + // + // See https://protobuf.dev/programming-guides/techniques/#self-description + // + // (-- api-linter: core::0146::any=disabled + // aip.dev/not-precedent: This is a self-describing message. --) + google.protobuf.Any metadata = 2 [(google.api.field_behavior) = REQUIRED]; } // Encrypted serialized `Metadata`. The encryption uses @@ -95,6 +111,6 @@ message EventGroup { // have all mutable optional fields cleared. This state is terminal. DELETED = 2; } - // Event Group state. Output-only. + // Event Group state. State state = 9 [(google.api.field_behavior) = OUTPUT_ONLY]; } diff --git a/src/main/proto/wfa/measurement/api/v2alpha/event_group_metadata_descriptor.proto b/src/main/proto/wfa/measurement/api/v2alpha/event_group_metadata_descriptor.proto index 275fe4c81..ab7762d99 100644 --- a/src/main/proto/wfa/measurement/api/v2alpha/event_group_metadata_descriptor.proto +++ b/src/main/proto/wfa/measurement/api/v2alpha/event_group_metadata_descriptor.proto @@ -33,6 +33,8 @@ message EventGroupMetadataDescriptor { option (google.api.resource) = { type: "halo.wfanet.org/EventGroupMetadataDescriptor" pattern: "dataProviders/{data_provider}/eventGroupMetadataDescriptors/{event_group_metadata_descriptor}" + singular: "eventGroupMetadataDescriptor" + plural: "eventGroupMetadataDescriptors" }; // Resource name. diff --git a/src/main/proto/wfa/measurement/api/v2alpha/exchange.proto b/src/main/proto/wfa/measurement/api/v2alpha/exchange.proto index cc97f488f..4c14c245b 100644 --- a/src/main/proto/wfa/measurement/api/v2alpha/exchange.proto +++ b/src/main/proto/wfa/measurement/api/v2alpha/exchange.proto @@ -16,6 +16,7 @@ syntax = "proto3"; package wfa.measurement.api.v2alpha; +import "google/api/field_behavior.proto"; import "google/api/resource.proto"; import "google/type/date.proto"; @@ -30,6 +31,8 @@ message Exchange { pattern: "recurringExchanges/{recurring_exchange}/exchanges/{exchange}" pattern: "dataProviders/{data_provider}/recurringExchanges/{recurring_exchange}/exchanges/{exchange}" pattern: "modelProviders/{data_provider}/recurringExchanges/{recurring_exchange}/exchanges/{exchange}" + singular: "exchange" + plural: "exchanges" }; // Resource name. @@ -38,7 +41,9 @@ message Exchange { // Must be a complete date (no field can be unset/zero). google.type.Date date = 2; + // State of an `Exchange`. enum State { + // Default value used if the state is omitted. STATE_UNSPECIFIED = 0; // The exchange is has not yet reached a terminal state. @@ -50,9 +55,8 @@ message Exchange { // The exchange has failed. FAILED = 3; } - - // State of the Exchange. Output-only. - State state = 3; + // State of this `Exchange`. + State state = 3 [(google.api.field_behavior) = OUTPUT_ONLY]; // SHA256 hash of the audit trail, if uploaded. bytes audit_trail_hash = 4; @@ -61,7 +65,6 @@ message Exchange { // relationship between all steps. // // See https://graphviz.org/doc/info/lang.html for the language specification. - // - // Output only. - string graphviz_representation = 5; + string graphviz_representation = 5 + [(google.api.field_behavior) = OUTPUT_ONLY]; } diff --git a/src/main/proto/wfa/measurement/api/v2alpha/exchange_step.proto b/src/main/proto/wfa/measurement/api/v2alpha/exchange_step.proto index 40cd7f642..86304b1c4 100644 --- a/src/main/proto/wfa/measurement/api/v2alpha/exchange_step.proto +++ b/src/main/proto/wfa/measurement/api/v2alpha/exchange_step.proto @@ -16,6 +16,7 @@ syntax = "proto3"; package wfa.measurement.api.v2alpha; +import "google/api/field_behavior.proto"; import "google/api/resource.proto"; import "google/type/date.proto"; @@ -30,13 +31,15 @@ message ExchangeStep { pattern: "recurringExchanges/{recurring_exchange}/exchanges/{exchange}/steps/{exchange_step}" pattern: "dataProviders/{data_provider}/recurringExchanges/{recurring_exchange}/exchanges/{exchange}/steps/{exchange_step}" pattern: "modelProviders/{data_provider}/recurringExchanges/{recurring_exchange}/exchanges/{exchange}/steps/{exchange_step}" + singular: "exchangeStep" + plural: "exchangeSteps" }; // Resource name. string name = 1; - // Output-only. - State state = 2; + // State of this `ExchangeStep`. + State state = 2 [(google.api.field_behavior) = OUTPUT_ONLY]; // Serialized ExchangeWorkflow that this ExchangeStep corresponds to. bytes serialized_exchange_workflow = 3; @@ -48,7 +51,9 @@ message ExchangeStep { // Current index of the step inside the serialized_exchange_workflow. int32 step_index = 5; + // State of an `ExchangeStep`. enum State { + // Default value used if the state is omitted. STATE_UNSPECIFIED = 0; // Some predecessor ExchangeStep is not in state SUCCEEDED. @@ -56,6 +61,7 @@ message ExchangeStep { // All predecessor ExchangeSteps are in state `SUCCEEDED` and there are no // associated ExchangeStepAttempts. + // (-- api-linter: core::0216::value-synonyms=disabled --) READY = 2; // All predecessor ExchangeSteps are in state `SUCCEEDED` and there is at diff --git a/src/main/proto/wfa/measurement/api/v2alpha/exchange_step_attempt.proto b/src/main/proto/wfa/measurement/api/v2alpha/exchange_step_attempt.proto index e0fd2fe89..1c98af9bf 100644 --- a/src/main/proto/wfa/measurement/api/v2alpha/exchange_step_attempt.proto +++ b/src/main/proto/wfa/measurement/api/v2alpha/exchange_step_attempt.proto @@ -16,6 +16,7 @@ syntax = "proto3"; package wfa.measurement.api.v2alpha; +import "google/api/field_behavior.proto"; import "google/api/resource.proto"; import "google/protobuf/timestamp.proto"; @@ -30,6 +31,8 @@ message ExchangeStepAttempt { pattern: "recurringExchanges/{recurring_exchange}/exchanges/{exchange}/steps/{exchange_step}/attempts/{exchange_step_attempt}" pattern: "dataProviders/{data_provider}/recurringExchanges/{recurring_exchange}/exchanges/{exchange}/steps/{exchange_step}/attempts/{exchange_step_attempt}" pattern: "modelProviders/{data_provider}/recurringExchanges/{recurring_exchange}/exchanges/{exchange}/steps/{exchange_step}/attempts/{exchange_step_attempt}" + singular: "exchangeStepAttempt" + plural: "exchangeStepAttempts" }; // Resource name. @@ -37,10 +40,11 @@ message ExchangeStepAttempt { // An ExchangeStep can have multiple ExchangeStepAttempts. When sorted by // `start_time`, these form a contiguous sequence of integers starting at 1. - // Output-only. - int32 attempt_number = 2; + int32 attempt_number = 2 [(google.api.field_behavior) = OUTPUT_ONLY]; + // State of an `ExchangeStepAttempt`. enum State { + // The default value if the state is omitted. STATE_UNSPECIFIED = 0; // The attempt is has not yet reached a terminal state. @@ -59,11 +63,14 @@ message ExchangeStepAttempt { FAILED_STEP = 4; } - // State of the ExchangeStepAttempt. Output-only. - State state = 3; + // State of this `ExchangeStepAttempt`. + State state = 3 [(google.api.field_behavior) = OUTPUT_ONLY]; + // Entry of debug log. message DebugLog { // When the log entry was made. + // (-- api-linter: core::0142::time-field-names=disabled + // aip.dev/not-precedent: Legacy field name. --) google.protobuf.Timestamp time = 1; // Human-readable debug message. This should NOT include any user data. @@ -72,9 +79,11 @@ message ExchangeStepAttempt { // Warnings, errors, and other messages for debugging purposes. Append-only. repeated DebugLog debug_log_entries = 4; - // When the ExchangeStepAttempt was created. Output-only. - google.protobuf.Timestamp start_time = 5; + // When the ExchangeStepAttempt was created. + google.protobuf.Timestamp start_time = 5 + [(google.api.field_behavior) = OUTPUT_ONLY]; - // When the ExchangeStepAttempt was last updated. Output-only. - google.protobuf.Timestamp update_time = 6; + // When the ExchangeStepAttempt was last updated. + google.protobuf.Timestamp update_time = 6 + [(google.api.field_behavior) = OUTPUT_ONLY]; } diff --git a/src/main/proto/wfa/measurement/api/v2alpha/measurement.proto b/src/main/proto/wfa/measurement/api/v2alpha/measurement.proto index e79e0d266..387339fdc 100644 --- a/src/main/proto/wfa/measurement/api/v2alpha/measurement.proto +++ b/src/main/proto/wfa/measurement/api/v2alpha/measurement.proto @@ -16,6 +16,7 @@ syntax = "proto3"; package wfa.measurement.api.v2alpha; +import "google/api/field_behavior.proto"; import "google/api/resource.proto"; import "google/protobuf/duration.proto"; import "wfa/measurement/api/v2alpha/crypto.proto"; @@ -25,69 +26,85 @@ option java_package = "org.wfanet.measurement.api.v2alpha"; option java_multiple_files = true; option java_outer_classname = "MeasurementProto"; +// A measurement from a set of `DataProvider`s requested by a +// `MeasurementConsumer`. message Measurement { option (google.api.resource) = { type: "halo.wfanet.org/Measurement" pattern: "measurementConsumers/{measurement_consumer}/measurements/{measurement}" + singular: "measurement" + plural: "measurements" }; // Resource name. string name = 1; // Resource name of the `Certificate` belonging to the parent - // `MeasurementConsumer`. Required. Immutable. - string measurement_consumer_certificate = 2 - [(google.api.resource_reference).type = "halo.wfanet.org/Certificate"]; + // `MeasurementConsumer`. + string measurement_consumer_certificate = 2 [ + (google.api.resource_reference).type = "halo.wfanet.org/Certificate", + (google.api.field_behavior) = REQUIRED, + (google.api.field_behavior) = IMMUTABLE + ]; // Serialized `MeasurementSpec` for requisitions, which can be verified using - // `measurement_consumer_certificate`. Required. Immutable. - SignedData measurement_spec = 3; - - // TODO(b/175707034): Consider adding a field to hold the private keys which - // is encrypted with some private/symmetric key belonging to the - // `MeasurementConsumer`. This way the `MeasurementConsumer` need not store - // the private keys for each `Measurement`. + // `measurement_consumer_certificate`. + SignedData measurement_spec = 3 [ + (google.api.field_behavior) = REQUIRED, + (google.api.field_behavior) = IMMUTABLE + ]; + // Entry for `data_providers` map. message DataProviderEntry { - // Key of the map entry, which is a `DataProvider` resource name. Required. - string key = 1 - [(google.api.resource_reference).type = "halo.wfanet.org/DataProvider"]; + // Key of the map entry, which is a `DataProvider` resource name. + string key = 1 [ + (google.api.resource_reference).type = "halo.wfanet.org/DataProvider", + (google.api.field_behavior) = REQUIRED + ]; + // Value of a map entry. message Value { // Resource name of the `Certificate` belonging to `data_provider`. - // Required. - string data_provider_certificate = 1 - [(google.api.resource_reference).type = - "halo.wfanet.org/Certificate"]; + string data_provider_certificate = 1 [ + (google.api.resource_reference).type = "halo.wfanet.org/Certificate", + (google.api.field_behavior) = REQUIRED + ]; // Pre-shared serialized `EncryptionPublicKey`, which can be verified - // using `data_provider_certificate`. Required. - SignedData data_provider_public_key = 2; + // using `data_provider_certificate`. + SignedData data_provider_public_key = 2 + [(google.api.field_behavior) = REQUIRED]; // Encrypted `SignedData` containing the serialized `RequisitionSpec` for // this entry, which can be verified using - // `measurement_consumer_certificate`. Required. + // `measurement_consumer_certificate`. // // The encryption uses `data_provider_public_key` as the recipient public // key. - bytes encrypted_requisition_spec = 3; + bytes encrypted_requisition_spec = 3 + [(google.api.field_behavior) = REQUIRED]; // SHA256 hash of the `nonce` from `encrypted_requisition_spec`, where the // nonce value has big-endian byte ordering. - bytes nonce_hash = 4; + bytes nonce_hash = 4 [(google.api.field_behavior) = REQUIRED]; } - // Value of the map entry. Required. - Value value = 2; + // Value of the map entry. + Value value = 2 [(google.api.field_behavior) = REQUIRED]; } - // Map of `DataProvider` name to parameters for that `DataProvider`. Required. - // Immutable. - repeated DataProviderEntry data_providers = 4; + // Map of `DataProvider` name to parameters for that `DataProvider`. + repeated DataProviderEntry data_providers = 4 [ + (google.api.field_behavior) = REQUIRED, + (google.api.field_behavior) = IMMUTABLE + ]; // The `ProtocolConfig` selected for this measurement according to the - // `measurement_spec`. Output-only. Immutable. - ProtocolConfig protocol_config = 5; + // `measurement_spec`. + ProtocolConfig protocol_config = 5 + [(google.api.field_behavior) = OUTPUT_ONLY]; + // State for a `Measurement`. enum State { + // Default value used if the state is omitted. STATE_UNSPECIFIED = 0; // Waiting for all linked `Requisition`s to be fulfilled. AWAITING_REQUISITION_FULFILLMENT = 1; @@ -100,16 +117,20 @@ message Measurement { // Cancelled by Measurement Consumer. Terminal state. CANCELLED = 5; } - State state = 6; + // State of this `Measurement`. + State state = 6 [(google.api.field_behavior) = OUTPUT_ONLY]; // The result of a `Measurement`. message Result { + // A reach result. message Reach { // Number of unique users exposed. int64 value = 1; } + // The reach result. Reach reach = 1; + // A frequency result. message Frequency { // Map of frequency to reach ratio. For example, an entry // {key: 4 value: 0.333} means that 33.3% of users were exposed exactly 4 @@ -117,21 +138,27 @@ message Measurement { // means that 33.3% of users were exposed at least 4 times. map relative_frequency_distribution = 1; } + // The frequency result. Frequency frequency = 2; + // An impression result. message Impression { // Number of total impressions. int64 value = 1; } + // The impressio result. Impression impression = 3; + // A watch duration result. message WatchDuration { // Total duration. google.protobuf.Duration value = 1; } + // The watch duration result. WatchDuration watch_duration = 4; } + // Pair of `Result` to `Certificate`. message ResultPair { // Encrypted `SignedData` containing the serialized `Result` // which can be verified using `certificate`. @@ -146,15 +173,21 @@ message Measurement { [(google.api.resource_reference).type = "halo.wfanet.org/Certificate"]; } - // List of `ResultPair`. Output-only. Only set if `state` is `SUCCEEDED`. - repeated ResultPair results = 8; + // Results of this `Measurement`. Only set if `state` is `SUCCEEDED`. + repeated ResultPair results = 8 [ + (google.api.field_behavior) = OUTPUT_ONLY, + (google.api.field_behavior) = UNORDERED_LIST + ]; // ID referencing the `Measurement` in an external system, provided by the - // Measurement Consumer. - string measurement_reference_id = 9; + // `MeasurementConsumer`. + string measurement_reference_id = 9 [(google.api.field_behavior) = IMMUTABLE]; + // Information about a failure. message Failure { + // Reason for a `Failure`. enum Reason { + // Default value used if the reason is omitted. REASON_UNSPECIFIED = 0; // An associated certificate was revoked. CERTIFICATE_REVOKED = 1; @@ -163,11 +196,13 @@ message Measurement { // ComputationParticipant state was set to FAILED. COMPUTATION_PARTICIPANT_FAILED = 3; } - Reason reason = 1; + // Reason for this `Failure`. + Reason reason = 1 [(google.api.field_behavior) = REQUIRED]; // Human-readable message. This should not contain any sensitive // information. string message = 2; } - // Set when the state is set to FAILED. Output-only. - Failure failure = 10; + // Information about the failure of this `Measurement`. Set when the `state` + // is set to `FAILED`. + Failure failure = 10 [(google.api.field_behavior) = OUTPUT_ONLY]; } diff --git a/src/main/proto/wfa/measurement/api/v2alpha/measurement_consumer.proto b/src/main/proto/wfa/measurement/api/v2alpha/measurement_consumer.proto index d7ba798e3..215178338 100644 --- a/src/main/proto/wfa/measurement/api/v2alpha/measurement_consumer.proto +++ b/src/main/proto/wfa/measurement/api/v2alpha/measurement_consumer.proto @@ -16,6 +16,7 @@ syntax = "proto3"; package wfa.measurement.api.v2alpha; +import "google/api/field_behavior.proto"; import "google/api/resource.proto"; import "wfa/measurement/api/v2alpha/crypto.proto"; @@ -52,8 +53,11 @@ message MeasurementConsumer { string display_name = 5; // Resource names of owner `Account`s. Output-only. - repeated string owners = 6 - [(google.api.resource_reference).type = "halo.wfanet.org/Account"]; + repeated string owners = 6 [ + (google.api.resource_reference).type = "halo.wfanet.org/Account", + (google.api.field_behavior) = OUTPUT_ONLY, + (google.api.field_behavior) = UNORDERED_LIST + ]; // Token to create a `MeasurementConsumer` resource. Required. Input-only. string measurement_consumer_creation_token = 7; diff --git a/src/main/proto/wfa/measurement/api/v2alpha/model_releases_service.proto b/src/main/proto/wfa/measurement/api/v2alpha/model_releases_service.proto index ab7addae7..1ab95a1fd 100644 --- a/src/main/proto/wfa/measurement/api/v2alpha/model_releases_service.proto +++ b/src/main/proto/wfa/measurement/api/v2alpha/model_releases_service.proto @@ -16,6 +16,7 @@ syntax = "proto3"; package wfa.measurement.api.v2alpha; +import "google/api/client.proto"; import "google/api/field_behavior.proto"; import "google/api/resource.proto"; import "wfa/measurement/api/v2alpha/model_release.proto"; @@ -24,18 +25,26 @@ option java_package = "org.wfanet.measurement.api.v2alpha"; option java_multiple_files = true; option java_outer_classname = "ModelReleasesServiceProto"; +// Service for interacting with `ModelRelease` resources. service ModelReleases { // Creates a new `ModelRelease`. - rpc CreateModelRelease(CreateModelReleaseRequest) returns (ModelRelease); + rpc CreateModelRelease(CreateModelReleaseRequest) returns (ModelRelease) { + option (google.api.method_signature) = "parent,model_release"; + } // Returns a single `ModelRelease`. - rpc GetModelRelease(GetModelReleaseRequest) returns (ModelRelease); + rpc GetModelRelease(GetModelReleaseRequest) returns (ModelRelease) { + option (google.api.method_signature) = "name"; + } // Lists `ModelRelease`s. rpc ListModelReleases(ListModelReleasesRequest) - returns (ListModelReleasesResponse); + returns (ListModelReleasesResponse) { + option (google.api.method_signature) = "parent"; + } } +// Request message for `CreateModelRelease` method. message CreateModelReleaseRequest { // Resource name of the parent `ModelSuite`. string parent = 1 [ @@ -48,6 +57,7 @@ message CreateModelReleaseRequest { ModelRelease model_release = 2 [(google.api.field_behavior) = REQUIRED]; } +// Request message for `GetModelRelease` method. message GetModelReleaseRequest { // Resource name. string name = 1 [ @@ -56,6 +66,7 @@ message GetModelReleaseRequest { ]; } +// Request message for `ListModelReleases` method. message ListModelReleasesRequest { // Resource name of the parent `ModelSuite`. string parent = 1 [ @@ -78,9 +89,10 @@ message ListModelReleasesRequest { string page_token = 3; } +// Response message for `ListModelReleases` method. message ListModelReleasesResponse { - // List of `ModelRelease`s. - repeated ModelRelease model_release = 1; + // Resources. + repeated ModelRelease model_releases = 1; // A token, which can be sent as `page_token` to retrieve the next page. // If this field is omitted, there are no subsequent pages. diff --git a/src/main/proto/wfa/measurement/api/v2alpha/model_rollouts_service.proto b/src/main/proto/wfa/measurement/api/v2alpha/model_rollouts_service.proto index e4b0a3b16..40fcfa199 100644 --- a/src/main/proto/wfa/measurement/api/v2alpha/model_rollouts_service.proto +++ b/src/main/proto/wfa/measurement/api/v2alpha/model_rollouts_service.proto @@ -16,6 +16,7 @@ syntax = "proto3"; package wfa.measurement.api.v2alpha; +import "google/api/client.proto"; import "google/api/field_behavior.proto"; import "google/api/resource.proto"; import "google/protobuf/empty.proto"; @@ -27,15 +28,20 @@ option java_package = "org.wfanet.measurement.api.v2alpha"; option java_multiple_files = true; option java_outer_classname = "ModelRolloutsServiceProto"; +// Service for interacting with `ModelRollout` resources. service ModelRollouts { // Creates a new `ModelRollout`. 'rollout_start_time' must be sufficiently in // the future to allow for EDPs to sync with the Kingdom. - rpc CreateModelRollout(CreateModelRolloutRequest) returns (ModelRollout); + rpc CreateModelRollout(CreateModelRolloutRequest) returns (ModelRollout) { + option (google.api.method_signature) = "parent,model_rollout"; + } // Lists `ModelRollout`s for a given ModelLine. It returns an sorted list by // rollout_start_time ASC. rpc ListModelRollouts(ListModelRolloutsRequest) - returns (ListModelRolloutsResponse); + returns (ListModelRolloutsResponse) { + option (google.api.method_signature) = "parent"; + } // Sets the `rollout_freeze_time` of a `ModelRollout`. rpc ScheduleModelRolloutFreeze(ScheduleModelRolloutFreezeRequest) @@ -44,9 +50,12 @@ service ModelRollouts { // Deletes a `ModelRollout`. Results in FAILED_PRECONDITION if the request is // received after 'ModelRollout.rollout_period.start_time`. rpc DeleteModelRollout(DeleteModelRolloutRequest) - returns (google.protobuf.Empty) {} + returns (google.protobuf.Empty) { + option (google.api.method_signature) = "name"; + } } +// Request message for `CreateModelRollout` method. message CreateModelRolloutRequest { // Resource name of the parent `ModelLine`. string parent = 1 [ @@ -59,6 +68,7 @@ message CreateModelRolloutRequest { ModelRollout model_rollout = 2 [(google.api.field_behavior) = REQUIRED]; } +// Request message for `ListModelRollouts` method. message ListModelRolloutsRequest { // Resource name of the parent `ModelLine`. string parent = 1 [ @@ -80,24 +90,29 @@ message ListModelRolloutsRequest { // token. string page_token = 3; - // Filter criteria. + // Filter criteria for a `ListModelRolloutsRequest`. message Filter { // Only 'ModelRollout's having 'rollout_period' overlapping // 'rollout_period_overlapping' are returned. TimeInterval rollout_period_overlapping = 1; } + // Filter criteria for this request. + // (-- api-linter: core::0132::request-field-types=disabled + // aip.dev/not-precedent: This API uses structured filters. --) Filter filter = 4; } +// Response message for `ListModelRollouts` method. message ListModelRolloutsResponse { - // List of `ModelRollout`s. - repeated ModelRollout model_rollout = 1; + // Resources. + repeated ModelRollout model_rollouts = 1; // A token, which can be sent as `page_token` to retrieve the next page. // If this field is omitted, there are no subsequent pages. string next_page_token = 2; } +// Request message for `ScheduleModelRolloutFreeze` method. message ScheduleModelRolloutFreezeRequest { // Resource name. string name = 1 [ @@ -110,6 +125,7 @@ message ScheduleModelRolloutFreezeRequest { google.protobuf.Timestamp rollout_freeze_time = 2; } +// Request message for `DeleteModelRollout` method. message DeleteModelRolloutRequest { // The name of `ModelRollout` to delete. // Format: diff --git a/src/main/proto/wfa/measurement/api/v2alpha/model_shard.proto b/src/main/proto/wfa/measurement/api/v2alpha/model_shard.proto index d89ef009d..afa57a4f9 100644 --- a/src/main/proto/wfa/measurement/api/v2alpha/model_shard.proto +++ b/src/main/proto/wfa/measurement/api/v2alpha/model_shard.proto @@ -18,9 +18,7 @@ package wfa.measurement.api.v2alpha; import "google/api/field_behavior.proto"; import "google/api/resource.proto"; -import "google/protobuf/any.proto"; import "google/protobuf/timestamp.proto"; -import "wfa/measurement/api/v2alpha/time_interval.proto"; option java_package = "org.wfanet.measurement.api.v2alpha"; option java_multiple_files = true; @@ -31,6 +29,7 @@ message ModelShard { type: "halo.wfanet.org/ModelShard" pattern: "dataProviders/{data_provider}/modelShards/{model_shard}" }; + string name = 1; // The ModelRelease resource this ModelShard references to. diff --git a/src/main/proto/wfa/measurement/api/v2alpha/model_shards_service.proto b/src/main/proto/wfa/measurement/api/v2alpha/model_shards_service.proto index 15ad03e4f..998e65a51 100644 --- a/src/main/proto/wfa/measurement/api/v2alpha/model_shards_service.proto +++ b/src/main/proto/wfa/measurement/api/v2alpha/model_shards_service.proto @@ -20,7 +20,6 @@ import "google/api/field_behavior.proto"; import "google/api/resource.proto"; import "google/protobuf/empty.proto"; import "wfa/measurement/api/v2alpha/model_shard.proto"; -import "wfa/measurement/api/v2alpha/time_interval.proto"; option java_package = "org.wfanet.measurement.api.v2alpha"; option java_multiple_files = true; diff --git a/src/main/proto/wfa/measurement/api/v2alpha/model_suites_service.proto b/src/main/proto/wfa/measurement/api/v2alpha/model_suites_service.proto index 9feb5ab06..a2d763ca4 100644 --- a/src/main/proto/wfa/measurement/api/v2alpha/model_suites_service.proto +++ b/src/main/proto/wfa/measurement/api/v2alpha/model_suites_service.proto @@ -16,6 +16,7 @@ syntax = "proto3"; package wfa.measurement.api.v2alpha; +import "google/api/client.proto"; import "google/api/field_behavior.proto"; import "google/api/resource.proto"; import "wfa/measurement/api/v2alpha/model_suite.proto"; @@ -27,15 +28,21 @@ option java_outer_classname = "ModelSuitesServiceProto"; // Service for interacting with `ModelSuite` resources. service ModelSuites { // Creates a new `ModelSuite` - rpc CreateModelSuite(CreateModelSuiteRequest) returns (ModelSuite); + rpc CreateModelSuite(CreateModelSuiteRequest) returns (ModelSuite) { + option (google.api.method_signature) = "parent,model_suite"; + } // Returns the `ModelSuite` with the specified resource key. rpc GetModelSuite(GetModelSuiteRequest) returns (ModelSuite); // Lists `ModelSuite`s. - rpc ListModelSuites(ListModelSuitesRequest) returns (ListModelSuitesResponse); + rpc ListModelSuites(ListModelSuitesRequest) + returns (ListModelSuitesResponse) { + option (google.api.method_signature) = "parent"; + } } +// Request message for `CreateModelSuite` method. message CreateModelSuiteRequest { // Resource name of the parent `ModelProvider`. string parent = 1 [ @@ -48,12 +55,14 @@ message CreateModelSuiteRequest { ModelSuite model_suite = 2 [(google.api.field_behavior) = REQUIRED]; } +// Request message for `GetModelSuite` method. message GetModelSuiteRequest { // Resource name. string name = 1 [(google.api.resource_reference).type = "halo.wfanet.org/ModelSuite"]; } +// Request message for `ListModelSuites` method. message ListModelSuitesRequest { // Resource name of the parent `ModelProvider`. string parent = 1 [ @@ -76,8 +85,8 @@ message ListModelSuitesRequest { } message ListModelSuitesResponse { - // List of `ModelSuite`s. - repeated ModelSuite model_suite = 1; + // Resources. + repeated ModelSuite model_suites = 1; // A token, which can be sent as `page_token` to retrieve the next page. // If this field is omitted, there are no subsequent pages. diff --git a/src/main/proto/wfa/measurement/api/v2alpha/protocol_config.proto b/src/main/proto/wfa/measurement/api/v2alpha/protocol_config.proto index fdd8305ab..8b4ae66a2 100644 --- a/src/main/proto/wfa/measurement/api/v2alpha/protocol_config.proto +++ b/src/main/proto/wfa/measurement/api/v2alpha/protocol_config.proto @@ -16,7 +16,6 @@ syntax = "proto3"; package wfa.measurement.api.v2alpha; -import "google/api/resource.proto"; import "wfa/measurement/api/v2alpha/differential_privacy.proto"; option java_package = "org.wfanet.measurement.api.v2alpha"; diff --git a/src/main/proto/wfa/measurement/api/v2alpha/public_key.proto b/src/main/proto/wfa/measurement/api/v2alpha/public_key.proto index 131504a06..36e13bcfd 100644 --- a/src/main/proto/wfa/measurement/api/v2alpha/public_key.proto +++ b/src/main/proto/wfa/measurement/api/v2alpha/public_key.proto @@ -16,6 +16,7 @@ syntax = "proto3"; package wfa.measurement.api.v2alpha; +import "google/api/field_behavior.proto"; import "google/api/resource.proto"; import "wfa/measurement/api/v2alpha/crypto.proto"; @@ -29,19 +30,22 @@ message PublicKey { type: "halo.wfanet.org/PublicKey" pattern: "dataProviders/{data_provider}/publicKey" pattern: "measurementConsumers/{measurement_consumer}/publicKey" + singular: "publicKey" + plural: "publicKeys" }; // Resource name. string name = 1; // Serialized `EncryptionPublicKey` for the parent resource, which can be - // verified using `certificate`. Required. - SignedData public_key = 2; + // verified using `certificate`. + SignedData public_key = 2 [(google.api.field_behavior) = REQUIRED]; // Resource name of the `Certificate` that can be used to verify `public_key`. - // Required. // // This must have the same parent as the `PublicKey`. - string certificate = 3 - [(google.api.resource_reference).type = "halo.wfanet.org/Certificate"]; + string certificate = 3 [ + (google.api.resource_reference).type = "halo.wfanet.org/Certificate", + (google.api.field_behavior) = REQUIRED + ]; } diff --git a/src/main/proto/wfa/measurement/api/v2alpha/recurring_exchanges_service.proto b/src/main/proto/wfa/measurement/api/v2alpha/recurring_exchanges_service.proto index cd6a6f589..db7a0832b 100644 --- a/src/main/proto/wfa/measurement/api/v2alpha/recurring_exchanges_service.proto +++ b/src/main/proto/wfa/measurement/api/v2alpha/recurring_exchanges_service.proto @@ -16,6 +16,8 @@ syntax = "proto3"; package wfa.measurement.api.v2alpha; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; import "google/api/resource.proto"; import "wfa/measurement/api/v2alpha/recurring_exchange.proto"; @@ -27,11 +29,15 @@ option java_outer_classname = "RecurringExchangesServiceProto"; service RecurringExchanges { // Returns the `RecurringExchange` with the specified resource key. rpc GetRecurringExchange(GetRecurringExchangeRequest) - returns (RecurringExchange); + returns (RecurringExchange) { + option (google.api.method_signature) = "name"; + } // Creates a `RecurringExchange`. rpc CreateRecurringExchange(CreateRecurringExchangeRequest) - returns (RecurringExchange); + returns (RecurringExchange) { + option (google.api.method_signature) = "recurring_exchange"; + } // Lists `RecurringExchanges`. rpc ListRecurringExchanges(ListRecurringExchangesRequest) @@ -45,15 +51,18 @@ service RecurringExchanges { // Request message for `GetRecurringExchange` method. message GetRecurringExchangeRequest { // Resource name. - string name = 1 [(google.api.resource_reference).type = - "halo.wfanet.org/RecurringExchange"]; + string name = 1 [ + (google.api.resource_reference).type = "halo.wfanet.org/RecurringExchange", + (google.api.field_behavior) = REQUIRED + ]; } // Request message for `CreateRecurringExchange` method. message CreateRecurringExchangeRequest { - // The `RecurringExchange` to create. Required. The `key` field will be + // The `RecurringExchange` to create. Required. The `name` field will be // ignored, and the system will assign an ID. - RecurringExchange recurring_exchange = 1; + RecurringExchange recurring_exchange = 1 + [(google.api.field_behavior) = REQUIRED]; } // Request message for `ListRecurringExchanges` method. @@ -75,8 +84,10 @@ message ListRecurringExchangesRequest { // Limits the results to those that match ALL of the specified criteria. Unset // fields are ignored (i.e. treated like wildcards). message Filter { + // Resource name of `DataProvider` to filter by. string data_provider = 1 [(google.api.resource_reference).type = "halo.wfanet.org/DataProvider"]; + // Resource name of `ModelProvider` to filter by. string model_provider = 2 [(google.api.resource_reference).type = "halo.wfanet.org/ModelProvider"]; } @@ -84,18 +95,22 @@ message ListRecurringExchangesRequest { // Restrictions on the RecurringExchanges listed. It is an error to request // RecurringExchanges that are not associated with the caller, so at least // one of `data_provider` or `model_provider` should be specified. + // (-- api-linter: core::0132::request-field-types=disabled + // aip.dev/not-precedent: This API uses structured filters. --) Filter filter = 3; } +// Response message for `ListRecurringExchanges` method. message ListRecurringExchangesResponse { // Page of `RecurringExchange`s. - repeated RecurringExchange resources = 1; + repeated RecurringExchange recurring_exchanges = 1; // A token, which can be sent as `page_token` to retrieve the next page. // If this field is omitted, there are no subsequent pages. string next_page_token = 2; } +// Request message for `RetireRecurringExchange` method. message RetireRecurringExchangeRequest { // Resource name. string name = 1 [(google.api.resource_reference).type = diff --git a/src/main/proto/wfa/measurement/api/v2alpha/requisition.proto b/src/main/proto/wfa/measurement/api/v2alpha/requisition.proto index e1da63d9a..9924bf5e0 100644 --- a/src/main/proto/wfa/measurement/api/v2alpha/requisition.proto +++ b/src/main/proto/wfa/measurement/api/v2alpha/requisition.proto @@ -16,6 +16,7 @@ syntax = "proto3"; package wfa.measurement.api.v2alpha; +import "google/api/field_behavior.proto"; import "google/api/resource.proto"; import "wfa/measurement/api/v2alpha/crypto.proto"; import "wfa/measurement/api/v2alpha/measurement.proto"; @@ -97,7 +98,8 @@ message Requisition { Value value = 2; } // Map of `Duchy` name to parameters for that `Duchy`. Required. Immutable. - repeated DuchyEntry duchies = 9; + repeated DuchyEntry duchies = 9 + [(google.api.field_behavior) = UNORDERED_LIST]; // State of a `Requisition`. enum State { diff --git a/src/main/proto/wfa/measurement/api/v2alpha/requisition_fulfillment_service.proto b/src/main/proto/wfa/measurement/api/v2alpha/requisition_fulfillment_service.proto index 5f954cad7..3b02cb830 100644 --- a/src/main/proto/wfa/measurement/api/v2alpha/requisition_fulfillment_service.proto +++ b/src/main/proto/wfa/measurement/api/v2alpha/requisition_fulfillment_service.proto @@ -16,6 +16,7 @@ syntax = "proto3"; package wfa.measurement.api.v2alpha; +import "google/api/field_behavior.proto"; import "google/api/resource.proto"; import "wfa/measurement/api/v2alpha/requisition.proto"; @@ -33,26 +34,32 @@ service RequisitionFulfillment { // Request message for `FulfillRequisition` method. message FulfillRequisitionRequest { // The header message for this streaming request. + // (-- api-linter: core::0123::resource-annotation=disabled + // aip.dev/not-precedent: This is not a resource message. --) message Header { - // Resource name of the `Requisition`. Required. - string name = 1 - [(google.api.resource_reference).type = "halo.wfanet.org/Requisition"]; + // Resource name of the `Requisition`. + string name = 1 [ + (google.api.resource_reference).type = "halo.wfanet.org/Requisition", + (google.api.field_behavior) = REQUIRED + ]; - // The fingerprint of the `Requisition`. Required. + // The fingerprint of the `Requisition`. // // This is defined as the SHA256 hash of the concatenation of: // 1. The `data` in `measurement_spec` from the `Requisition`. // 2. The SHA256 hash of `encrypted_requisition_spec` from the // `Requisition`. - bytes requisition_fingerprint = 2; + bytes requisition_fingerprint = 2 [(google.api.field_behavior) = REQUIRED]; - // The `nonce` value from the `encrypted_requisition_spec`. Required. - fixed64 nonce = 3; + // The `nonce` value from the `encrypted_requisition_spec`. + // (-- api-linter: core::0141::forbidden-types=disabled + // aip.dev/not-precedent: This is a random 64-bit value. --) + fixed64 nonce = 3 [(google.api.field_behavior) = REQUIRED]; } // The chunk message for this streaming request. message BodyChunk { - // The portion of the data for this `BodyChunk`. Required. + // The portion of the data for this `BodyChunk`. // // The format of the data depends on the corresponding `MeasurementSpec`. If // the `Requisition` is for an encrypted sketch, this is the register @@ -64,7 +71,7 @@ message FulfillRequisitionRequest { // The optimal size of this field is one that would result in the // `FulfillRequisitionRequest` message being between 16KiB and 64KiB. // See https://github.com/grpc/grpc.github.io/issues/371 - bytes data = 1; + bytes data = 1 [(google.api.field_behavior) = REQUIRED]; } // Request message payload. Exactly one of these must be specified. @@ -82,5 +89,5 @@ message FulfillRequisitionRequest { // Response message for `FulfillRequisition` method. message FulfillRequisitionResponse { // Resulting state of the `Requisition`. - Requisition.State state = 1; + Requisition.State state = 1 [(google.api.field_behavior) = OUTPUT_ONLY]; } diff --git a/src/main/proto/wfa/measurement/api/v2alpha/requisition_spec.proto b/src/main/proto/wfa/measurement/api/v2alpha/requisition_spec.proto index 08283ea6b..f397b09ad 100644 --- a/src/main/proto/wfa/measurement/api/v2alpha/requisition_spec.proto +++ b/src/main/proto/wfa/measurement/api/v2alpha/requisition_spec.proto @@ -16,6 +16,7 @@ syntax = "proto3"; package wfa.measurement.api.v2alpha; +import "google/api/field_behavior.proto"; import "google/api/resource.proto"; import "wfa/measurement/api/v2alpha/time_interval.proto"; @@ -32,34 +33,51 @@ message RequisitionSpec { // each event template. string expression = 1; } + // Entry for `event_groups` map. message EventGroupEntry { - // Key of the map entry, which is an `EventGroup` resource name. Required. - string key = 1 - [(google.api.resource_reference).type = "halo.wfanet.org/EventGroup"]; + // Key of the map entry, which is an `EventGroup` resource name. + string key = 1 [ + (google.api.resource_reference).type = "halo.wfanet.org/EventGroup", + (google.api.field_behavior) = REQUIRED + ]; + // Value of an `EventGroupEntry`. message Value { - // Time interval over which the event data should be collected. Required. - TimeInterval collection_interval = 1; + // Time interval over which the event data should be collected. + TimeInterval collection_interval = 1 + [(google.api.field_behavior) = REQUIRED]; - // Optional filter to apply to events. + // Filter to apply to events. If not specified then all events will be + // matched. EventFilter filter = 2; } - // Value of the map entry. Required. - Value value = 2; + // Value of this `EventGroupEntry`. + Value value = 2 [(google.api.field_behavior) = REQUIRED]; } - // Map of `EventGroup` name to parameters for that `EventGroup`. Required. + // Map of `EventGroup` name to parameters for that `EventGroup`. // // All of the `EventGroup`s must belong to the same parent `DataProvider` // as this `Requisition`. - repeated EventGroupEntry event_groups = 1; + repeated EventGroupEntry event_groups = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.field_behavior) = IMMUTABLE + ]; // Serialized `EncryptionPublicKey` for the `Measurement` that this - // `RequisitionSpec` is associated with. Required. + // `RequisitionSpec` is associated with. // // This is serialized so it can be easily compared with the same field in // `MeasurementSpec`. - bytes measurement_public_key = 2; + bytes measurement_public_key = 2 [ + (google.api.field_behavior) = REQUIRED, + (google.api.field_behavior) = IMMUTABLE + ]; - // Non-zero cryptographic nonce for this `RequisitionSpec`. Required. - fixed64 nonce = 3; + // Non-zero cryptographic nonce for this `RequisitionSpec`. + // (-- api-linter: core::0141::forbidden-types=disabled + // aip.dev/not-precedent: This is a random 64-bit value. --) + fixed64 nonce = 3 [ + (google.api.field_behavior) = REQUIRED, + (google.api.field_behavior) = IMMUTABLE + ]; } diff --git a/tools/api-lint b/tools/api-lint new file mode 100755 index 000000000..b6ad4e77d --- /dev/null +++ b/tools/api-lint @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +set -eu -o pipefail + +readonly PROTO_PATH='src/main/proto' + +declare bazel_bin +bazel_bin="$(bazel info bazel-bin)" + +bazel build //... + +find "$PROTO_PATH" -name '*.proto' -printf '%P\0' | + xargs -0 api-linter --proto-path "$PROTO_PATH" \ + --config "$PROTO_PATH/api-linter.yaml" \ + --descriptor-set-in "${bazel_bin}/external/com_github_protocolbuffers_protobuf/descriptor_proto-descriptor-set.proto.bin" \ + --descriptor-set-in "${bazel_bin}/external/com_google_googleapis/google/type/date_proto-descriptor-set.proto.bin" \ + --descriptor-set-in "${bazel_bin}/external/com_google_googleapis/google/api/resource_proto-descriptor-set.proto.bin" \ + --descriptor-set-in "${bazel_bin}/external/com_google_googleapis/google/api/field_behavior_proto-descriptor-set.proto.bin" \ + --descriptor-set-in "${bazel_bin}/external/com_google_googleapis/google/api/client_proto-descriptor-set.proto.bin" \ + "$@"