diff --git a/src/main/proto/wfa/measurement/reporting/v2alpha/BUILD.bazel b/src/main/proto/wfa/measurement/reporting/v2alpha/BUILD.bazel index 09c17cf313c..34f5c5e4478 100644 --- a/src/main/proto/wfa/measurement/reporting/v2alpha/BUILD.bazel +++ b/src/main/proto/wfa/measurement/reporting/v2alpha/BUILD.bazel @@ -86,8 +86,8 @@ proto_library( deps = [ ":event_filter_proto", ":media_type_proto", - "@com_google_googleapis//google/api:field_behavior_proto", "@com_google_protobuf//:duration_proto", + "@com_google_googleapis//google/api:field_behavior_proto", ], ) diff --git a/src/main/proto/wfa/measurement/reporting/v2alpha/advanced_report.proto b/src/main/proto/wfa/measurement/reporting/v2alpha/advanced_report.proto new file mode 100644 index 00000000000..ff910d522f2 --- /dev/null +++ b/src/main/proto/wfa/measurement/reporting/v2alpha/advanced_report.proto @@ -0,0 +1,164 @@ +// Copyright 2024 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. + +syntax = "proto3"; + +package wfa.measurement.reporting.v2alpha; + +import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; +import "google/protobuf/timestamp.proto"; +import "wfa/measurement/reporting/v2alpha/media_type.proto"; +import "wfa/measurement/reporting/v2alpha/metric_frequency_spec.proto"; +import "wfa/measurement/reporting/v2alpha/reporting_impression_qualification_filter.proto"; +import "wfa/measurement/reporting/v2alpha/reporting_interval.proto"; + +option java_package = "org.wfanet.measurement.reporting.v2alpha"; +option java_multiple_files = true; +option java_outer_classname = "AdvancedReportProto"; + +// Resource representing a AdvancedReport. +// +// When an AdvancedReport is created a suite of metrics is precomputed. +// Once complete these are made available via the Query method. +message AdvancedReport { + option (google.api.resource) = { + type: "reporting.halo-cmm.org/AdvancedReport" + pattern: "measurementConsumers/{measurement_consumer}/advancedReports/{advanced_report}" + singular: "advancedReport" + plural: "advancedReports" + }; + + // Resource name. + string name = 1 [(google.api.field_behavior) = IDENTIFIER]; + + // Human readable title of the report. + string title = 2 [ + (google.api.field_behavior) = IMMUTABLE, + (google.api.field_behavior) = OPTIONAL + ]; + + // The set of Reporting Sets for which the Advanced Report is + // created. + // + // The Reporting Sets must be either primitive or be a union of Reporting Sets + // that are either primitive or unions of other Reporting Sets. Filters may + // not be specified. + // + // Upon creation of the Advanced Report, any metric for any subset of these + // may be queried. + repeated string reporting_sets = 3 [ + (google.api.resource_reference) = { + type: "reporting.halo-cmm.org/ReportingSet" + }, + (google.api.field_behavior) = IMMUTABLE, + (google.api.field_behavior) = REQUIRED + ]; + + // The interval that the Report spans + // + // The report_end is extended for live reports as new data + // becomes available. + ReportingInterval reporting_interval = 4 + [(google.api.field_behavior) = REQUIRED]; + + // Specifies how to calculate precomputed report metrics + // + // This spec places limits on how the report can be queried after + // it is created. For example if the metric_frequency_specs only + // includes `total` then no metrics are computed for any subinterval of + // the report. + message CalculationSpec { + // The set of Media Types to report on. If empty report on all + // MediaTypes. + repeated MediaType media_types = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.field_behavior) = IMMUTABLE, + (google.api.field_behavior) = UNORDERED_LIST + ]; + + // The set of impression qualification filters to be applied. + // + // Defaults are appended as the Measurement Policy requires. + repeated ReportingImpressionQualificationFilter + impression_qualification_filters = 2 [ + (google.api.field_behavior) = OPTIONAL, + (google.api.field_behavior) = IMMUTABLE + ]; + + // The metric subintervals to include in the report + repeated MetricFrequencySpec metric_frequency_specs = 3 + [(google.api.field_behavior) = IMMUTABLE]; + + // The maximum freuency to include in the report + int32 max_frequency = 4 [(google.api.field_behavior) = IMMUTABLE]; + } + // Specifies how to precompute report metrics. + CalculationSpec calculation_spec = 5; + + // Specifies whether and how the system tracks live campaigns. + // + // When live campaign tracking is enabled the system monitors the report's + // underlying Event Groups and appends new data as it becomes available. + message LiveCampaignTrackingSpec { + // Specifies whether and how to export data when new data arrives. + message ExportSpec { + // The PageTemplate to use for exporting results + // + // When instantiating the template, The ReportingUnit is taken to be + // the reporting_sets of the AdvancedReport. + string page_template = 1 [ + (google.api.resource_reference) = { + type: "reporting.halo-cmm.org/PageTemplate" + }, + (google.api.field_behavior) = IMMUTABLE, + (google.api.field_behavior) = REQUIRED + ]; + + // If true, the exported data set will include data from the + // report's reporting_interval.start_time to the present. If + // false only new data is exported. + bool include_history = 2 [ + (google.api.field_behavior) = IMMUTABLE, + (google.api.field_behavior) = OPTIONAL + ]; + } + // ExportSpec + ExportSpec export_spec = 1 [ + (google.api.field_behavior) = IMMUTABLE, + (google.api.field_behavior) = OPTIONAL + ]; + } + // Specifies that live campaign tracking is enabled and options for + // how to handle newly arriving data. + // + // When enabled, metrics are appended as they become available, + // and if an export spec is present they are automatically exported as well. + LiveCampaignTrackingSpec live_campaign_tracking_spec = 6 [ + (google.api.field_behavior) = IMMUTABLE, + (google.api.field_behavior) = OPTIONAL + ]; + + // The time when the resource was created. + google.protobuf.Timestamp create_time = 7 [ + (google.api.field_behavior) = IMMUTABLE, + (google.api.field_behavior) = OUTPUT_ONLY + ]; + + // The time when the resource was last updated. + google.protobuf.Timestamp update_time = 8 [ + (google.api.field_behavior) = IMMUTABLE, + (google.api.field_behavior) = OUTPUT_ONLY + ]; +} diff --git a/src/main/proto/wfa/measurement/reporting/v2alpha/advanced_reports_service.proto b/src/main/proto/wfa/measurement/reporting/v2alpha/advanced_reports_service.proto new file mode 100644 index 00000000000..846c847907c --- /dev/null +++ b/src/main/proto/wfa/measurement/reporting/v2alpha/advanced_reports_service.proto @@ -0,0 +1,250 @@ +// Copyright 2024 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. + +syntax = "proto3"; + +package wfa.measurement.reporting.v2alpha; + +import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; +import "google/protobuf/field_mask.proto"; +import "google/protobuf/timestamp.proto"; +import "wfa/measurement/reporting/v2alpha/advanced_report.proto"; +import "wfa/measurement/reporting/v2alpha/operation.proto"; +import "wfa/measurement/reporting/v2alpha/page.proto"; +import "wfa/measurement/reporting/v2alpha/reporting_interval.proto"; +import "wfa/measurement/reporting/v2alpha/reporting_unit.proto"; + +option java_package = "org.wfanet.measurement.reporting.v2alpha"; +option java_multiple_files = true; +option java_outer_classname = "AdvancedReportsServiceProto"; + +service AdvancedReports { + rpc CreateAdvancedReport(CreateAdvancedReportRequest) returns (Operation) { + option (google.api.http) = { + post: "/v2alpha/{parent=measurementConsumers/*}/advancedReports" + body: "advancedReport" + }; + option (google.api.method_signature) = "parent,advancedReport"; + } + + // Returns the `AdvancedReport` with the given resource key. + rpc GetAdvancedReport(GetAdvancedReportRequest) returns (AdvancedReport) { + option (google.api.http) = { + get: "/v2alpha/{name=measurementConsumers/*/advancedReports/*}" + }; + option (google.api.method_signature) = "name"; + } + + // Ordered by `create_time` ascending, `name` ascending. + rpc ListAdvancedReports(ListAdvancedReportsRequest) + returns (ListAdvancedReportsResponse) { + option (google.api.http) = { + get: "/v2alpha/{parent=measurementConsumers/*}/advancedReports" + }; + option (google.api.method_signature) = "parent"; + } + + // Updates the `AdvancedReport` with the given resource key. + // + // Only one in-progress update Operation is allow to exist at a time. + // TODO(@kungfucraig): Discuss - should we add a custom method for extending + // report end time and leave this for simpler updates (e.g. the title)? + rpc UpdateAdvancedReport(UpdateAdvancedReportRequest) returns (Operation) { + option (google.api.http) = { + get: "/v2alpha/{advancedReport.name=measurementConsumers/*/advancedReports/*}" + body: "advancedReport" + }; + option (google.api.method_signature) = "advancedReport,update_mask"; + } + + // Queries the `AdvancedReport` with the given resource key. + rpc QueryAdvancedReport(QueryAdvancedReportRequest) + returns (QueryAdvancedReportResponse) { + option (google.api.http) = { + get: "/v2alpha/{name=measurementConsumers/*/advancedReports/*}" + }; + option (google.api.method_signature) = "name"; + } + + // Exports the `AdvancedReport` with the given resource key. + rpc ExportAdvancedReport(ExportAdvancedReportRequest) returns (Operation) { + option (google.api.http) = { + get: "/v2alpha/{name=measurementConsumers/*/advancedReports/*}" + }; + option (google.api.method_signature) = "name"; + } +} + +// Specifies an AdvancedReport query using a PageTemplate and a ReportingUnit. +message PageTemplateSpec { + // The PageTemplate to instantiate. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "reporting.halo-cmm.org/PageTemplate" + } + ]; + + // The reporting unit to parameterize the PageTempalte with. + ReportingUnit reporting_unit = 2 [(google.api.field_behavior) = REQUIRED]; +} + +// Specifies how to query an AdvancedReport +message QuerySpec { + // The interval over which to query. + // + // If unspecified the entire interval associated with the Report is used. + // For Weekly metrics: + // 1) The start day must either be the start day of the report or be the + // same day of the week as the windowing criteria specified during report + // creation. + // 2) The end date must be either the end day of the report or be the same + // day of the week as the windowing criteria specified during report + // creation. + ReportingInterval reporting_interval = 1 + [(google.api.field_behavior) = OPTIONAL]; + + // Required. + oneof query { + // The PageSpec that describes the query to be run. + PageSpec page_spec = 2 [(google.api.field_behavior) = OPTIONAL]; + // A PageTemplateSpec that describes the query to be run. + PageTemplateSpec page_template_spec = 3 + [(google.api.field_behavior) = OPTIONAL]; + } +} + +// Request message for `CreateAdvancedReport` method +message CreateAdvancedReportRequest { + // The parent Measurement Consumer + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + child_type: "reporting.halo-cmm.org/AdvancedReport" + } + ]; + + // The ID to use for the report, which will become the final component of + // the report's resource name. + // + // This must conform to RFC 1034, with the additional restriction that all + // letters must be lower-case. + string advanced_report_id = 2 [(google.api.field_behavior) = REQUIRED]; + + // The AdvancedReport to create. + AdvancedReport advanced_report = 3; + + // A unique identifier for this request. Restricted to 36 ASCII characters. + // A random UUID is recommended. + // This request is only idempotent if a `request_id` is provided. + string request_id = 4; +} + +// Request message for `GetAdvancedReport` method +message GetAdvancedReportRequest { + // The name of the Advanced report to retrieve. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "reporting.halo-cmm.org/AdvancedReport" + } + ]; +} + +// Request message for `ListAdvancedReport` method +message ListAdvancedReportsRequest { + // The parent Measurement Consumer + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + child_type: "reporting.halo-cmm.org/AdvancedReport" + } + ]; + + // Filter criteria. Repeated fields are treated as logical ORs, and multiple + // fields are treated as logical ANDs. + message Filter { + // Return AdvancedReports that were created after this time. + // (-- api-linter: core::0140::prepositions=disabled + // -- api-linter: core::0142::time-field-names=disabled + // aip.dev/not-precedent: Structured filters are used instead of the + // AIP-160 filtering language --) + google.protobuf.Timestamp create_time_after = 1 + [(google.api.field_behavior) = REQUIRED]; + } + + // Filter for the list of AdvancedReports + // (-- api-linter: core::0132::request-field-types=disabled + // aip.dev/not-precedent: Structured filters are used instead of the + // AIP-160 filtering language --) + Filter filter = 2 [(google.api.field_behavior) = OPTIONAL]; + + // The maximum number of advanced reports to return. The service may return + // fewer than this value. If unspecified, at most 10 advanced reports will be + // returned. The maximum value is 25; values above 25 will be coerced to 25. + int32 page_size = 3 [(google.api.field_behavior) = OPTIONAL]; + + // A page token, received from a previous `ListAdvancedReports` call. + // Provide this to retrieve the subsequent page. + // + // When paginating, all other parameters provided to `ListAdvancedReports` + // must match the call that provided the page token. + string page_token = 4 [(google.api.field_behavior) = OPTIONAL]; +} + +// Response message for `ListAdvancedReports` method. +message ListAdvancedReportsResponse { + // The Advanced Reports that met the filter criteria + repeated AdvancedReport advanced_reports = 1 + [(google.api.field_behavior) = OPTIONAL]; + + // 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 [(google.api.field_behavior) = OPTIONAL]; +} + +// Request message for `UpdateAdvancedReport` method +message UpdateAdvancedReportRequest { + AdvancedReport advanced_report = 1 [(google.api.field_behavior) = REQUIRED]; + + // The list of fields to update. + google.protobuf.FieldMask update_mask = 2; +} + +// Request message for `QueryAdvancedReport` method +message QueryAdvancedReportRequest { + // Specifies the query to run. + QuerySpec query_spec = 1 [(google.api.field_behavior) = REQUIRED]; +} + +// Response message for `QueryAdvancedReport` method +message QueryAdvancedReportResponse { + // The result of the query + PageResult page_result = 1; +} + +// Request message for `ExportAdvancedReport` method +message ExportAdvancedReportRequest { + QuerySpec query_spec = 1 [(google.api.field_behavior) = REQUIRED]; +} + +// Message used by the long running operation to provide the +// real response to the `ExportAdvancedReport` method +message ExportAdvancedReportResponse { + // TODO(@kungfucraig): Determine response parameters as part of the + // detailed design of export. +} diff --git a/src/main/proto/wfa/measurement/reporting/v2alpha/event_groups_service.proto b/src/main/proto/wfa/measurement/reporting/v2alpha/event_groups_service.proto index 71ecab7695d..07ac9d457c8 100644 --- a/src/main/proto/wfa/measurement/reporting/v2alpha/event_groups_service.proto +++ b/src/main/proto/wfa/measurement/reporting/v2alpha/event_groups_service.proto @@ -16,9 +16,9 @@ syntax = "proto3"; package wfa.measurement.reporting.v2alpha; -import "google/api/annotations.proto"; import "google/api/client.proto"; import "google/api/field_behavior.proto"; +import "google/api/annotations.proto"; import "google/api/resource.proto"; import "wfa/measurement/reporting/v2alpha/event_group.proto"; diff --git a/src/main/proto/wfa/measurement/reporting/v2alpha/impression_qualification_filter_spec.proto b/src/main/proto/wfa/measurement/reporting/v2alpha/impression_qualification_filter_spec.proto index 2ffbb3c5c35..51fbbd119ac 100644 --- a/src/main/proto/wfa/measurement/reporting/v2alpha/impression_qualification_filter_spec.proto +++ b/src/main/proto/wfa/measurement/reporting/v2alpha/impression_qualification_filter_spec.proto @@ -17,7 +17,6 @@ syntax = "proto3"; package wfa.measurement.reporting.v2alpha; import "google/api/field_behavior.proto"; -import "google/protobuf/duration.proto"; import "wfa/measurement/reporting/v2alpha/event_filter.proto"; import "wfa/measurement/reporting/v2alpha/media_type.proto"; @@ -26,10 +25,6 @@ option java_multiple_files = true; option java_outer_classname = "ImpressionQualificationFilterSpecProto"; // Specifies impression qualification filter criteria for a MediaType -// -// If particular filter values are not applicable to the media they -// are applied to it is an error (e.g. DISPLAY cannot be filtered by -// percent completion) message ImpressionQualificationFilterSpec { // The Media Type the filter is applicable to. MediaType media_type = 1 [ diff --git a/src/main/proto/wfa/measurement/reporting/v2alpha/metric_calculation_specs_service.proto b/src/main/proto/wfa/measurement/reporting/v2alpha/metric_calculation_specs_service.proto index a1d09817c3c..7a82254e925 100644 --- a/src/main/proto/wfa/measurement/reporting/v2alpha/metric_calculation_specs_service.proto +++ b/src/main/proto/wfa/measurement/reporting/v2alpha/metric_calculation_specs_service.proto @@ -16,9 +16,9 @@ syntax = "proto3"; package wfa.measurement.reporting.v2alpha; -import "google/api/annotations.proto"; import "google/api/client.proto"; import "google/api/field_behavior.proto"; +import "google/api/annotations.proto"; import "google/api/resource.proto"; import "wfa/measurement/reporting/v2alpha/metric_calculation_spec.proto"; diff --git a/src/main/proto/wfa/measurement/reporting/v2alpha/metrics_service.proto b/src/main/proto/wfa/measurement/reporting/v2alpha/metrics_service.proto index d4168279f6f..dcfe8826e95 100644 --- a/src/main/proto/wfa/measurement/reporting/v2alpha/metrics_service.proto +++ b/src/main/proto/wfa/measurement/reporting/v2alpha/metrics_service.proto @@ -16,9 +16,9 @@ syntax = "proto3"; package wfa.measurement.reporting.v2alpha; -import "google/api/annotations.proto"; import "google/api/client.proto"; import "google/api/field_behavior.proto"; +import "google/api/annotations.proto"; import "google/api/resource.proto"; import "wfa/measurement/reporting/v2alpha/metric.proto"; diff --git a/src/main/proto/wfa/measurement/reporting/v2alpha/operation.proto b/src/main/proto/wfa/measurement/reporting/v2alpha/operation.proto new file mode 100644 index 00000000000..1f3ab73205a --- /dev/null +++ b/src/main/proto/wfa/measurement/reporting/v2alpha/operation.proto @@ -0,0 +1,43 @@ +// Copyright 2024 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. + +syntax = "proto3"; + +package wfa.measurement.reporting.v2alpha; + +import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; +import "google/protobuf/timestamp.proto"; +import "google/type/date.proto"; +import "google/type/datetime.proto"; + +option java_package = "org.wfanet.measurement.reporting.v2alpha"; +option java_multiple_files = true; +option java_outer_classname = "OperationProto"; + +// Resource representing a Advanced Report. +message Operation { + option (google.api.resource) = { + type: "reporting.halo-cmm.org/Operation" + pattern: "measurementConsumers/{measurement_consumer}/operations/{operation}" + singular: "operation" + plural: "operations" + }; + + // TODO(@kungfucraig): Discuss whether we should have a custom operation or + // use the one recommended by the AIP + // + // The custom operation would be a copy of the AIP one, but would use a oneof + // instead of an Any, any time an Any is used. +} diff --git a/src/main/proto/wfa/measurement/reporting/v2alpha/page.proto b/src/main/proto/wfa/measurement/reporting/v2alpha/page.proto index 0108e88608d..7cbe1ac4a70 100644 --- a/src/main/proto/wfa/measurement/reporting/v2alpha/page.proto +++ b/src/main/proto/wfa/measurement/reporting/v2alpha/page.proto @@ -44,8 +44,9 @@ message WindowingSpec { // Non-cumulative metrics NON_CUMULATIVE = 2; } - // How to accumulate results. + // How to accumulate results. Not available for AdvancedReport. AccumulationOptions accumulation_options = 2 [ + deprecated = true, (google.api.field_behavior) = REQUIRED, (google.api.field_behavior) = IMMUTABLE ]; @@ -86,9 +87,8 @@ message PageMetricSpec { // filters that are associated with calculation spec is reported. bool population_size = 1 [(google.api.field_behavior) = IMMUTABLE]; - // The set of basic metrics that can be computed for any aspect of the - // reporting_unit (e.g. the whole thing, a single component, intersections, - // etc.) + // Reporting Unit (e.g. the whole thing, a single component, intersections, + // etc.), whether the metric is cumualtive or non-cumulative. message BasicMetricSetSpec { // The reach bool reach = 1 [(google.api.field_behavior) = IMMUTABLE]; @@ -108,6 +108,12 @@ message PageMetricSpec { // The average frequency bool average_frequency = 5 [(google.api.field_behavior) = IMMUTABLE]; + // The maximum frequency for which to compute a frequency histogram. + // + // The last bin in the historgram will contain values for + // all requencies >= the value provided here. + int32 frequency_histogram = 8 [(google.api.field_behavior) = IMMUTABLE]; + // The impression count bool impressions = 6 [(google.api.field_behavior) = IMMUTABLE]; @@ -115,10 +121,33 @@ message PageMetricSpec { bool grps = 7 [(google.api.field_behavior) = IMMUTABLE]; } + // A structure for specifying that new reach and new impressions be + // computed. + message NewReachMetricSetSpec { + // The new reach of all the unit(s) for the time period compared to + // all previous time encompassed by the reporting_interval + bool reach = 1 [(google.api.field_behavior) = IMMUTABLE]; + + // The impressions associated with the new reach + bool impressions = 2 [(google.api.field_behavior) = IMMUTABLE]; + } + // Metrics to be computed over the entire reporting_unit message ReportingUnitMetricSetSpec { - // Metrics for the union of the items in the reporting)unit - BasicMetricSetSpec basic = 1 [(google.api.field_behavior) = IMMUTABLE]; + // Metrics for the union of the items in the reporting_unit + BasicMetricSetSpec basic = 1 + [deprecated = true, (google.api.field_behavior) = IMMUTABLE]; + + // Non-cumulative metrics for the union of the reporting_unit components + BasicMetricSetSpec non_cumulative = 3 + [(google.api.field_behavior) = IMMUTABLE]; + + // Cumulative metrics for the union of the reporting_unit components + BasicMetricSetSpec cumulative = 4 [(google.api.field_behavior) = IMMUTABLE]; + + // Reach and associated impressions that are new to the time period for all + // components of the reporing_unit + NewReachMetricSetSpec new = 5 [(google.api.field_behavior) = IMMUTABLE]; // Compute a stacked incremental reach result for the reporting_unit // @@ -146,6 +175,7 @@ message PageMetricSpec { // the components as [EDP3, EDP2, EDP1]. bool stacked_incremental_reach = 2; } + // The set of metrics to compute for the entire reporting_unit ReportingUnitMetricSetSpec reporting_unit = 2; @@ -153,21 +183,41 @@ message PageMetricSpec { // with respect to all others. message ComponentMetricSetSpec { // The basic metrics for each ReportingUnit.unit - BasicMetricSetSpec basic = 1 [(google.api.field_behavior) = IMMUTABLE]; + BasicMetricSetSpec basic = 1 + [deprecated = true, (google.api.field_behavior) = IMMUTABLE]; + + // Non-cumulative metrics for each component of the reporting_unit + BasicMetricSetSpec non_cumulative = 3 + [(google.api.field_behavior) = IMMUTABLE]; + + // Cumulative metrics for each component of the reporting_unit + BasicMetricSetSpec cumulative = 4 [(google.api.field_behavior) = IMMUTABLE]; - // Compute the unique reach of each reporting unit in the - // reporting_unit_spec with respect to all other reporting units. + // The unique reach of each reporting unit in the + // reporting_unit with respect to all other reporting units. // // For example if reporting_sets=[RS1, RS2, RS3] the unique reach of // RS1, RS2, and RS3 are computed. - // - // It is an error to specify this if only a single reporting unit is - // specified since it is the same thing as requesting union.reach. bool unique_reach = 2 [(google.api.field_behavior) = IMMUTABLE]; + + // The impressions associated with the unique reach. + // Cannot be use in conjunction with component. + bool unique_reach_impressions = 5 [(google.api.field_behavior) = IMMUTABLE]; + + // Reach and associated impressions that are new to the time period for each + // component of the reporting_unit + NewReachMetricSetSpec new = 6 [(google.api.field_behavior) = IMMUTABLE]; + + // Reach and associated impressions that are new to the time period and + // uniquefor each component of the reporting_unit + NewReachMetricSetSpec new_unique = 7 + [(google.api.field_behavior) = IMMUTABLE]; } - // If reporting_unit.component is of size 1 the metrics computed for the - // component are identical to those computed for the union. Specifying this - // value is not recommended in this case. + // Metrics for each component of the reporting_unit. + // + // If the number of components is 1 the metrics computed for the component + // are identical to those computed for the entire reporting unit. Specifying + // this value is not recommended in that case. ComponentMetricSetSpec component = 3 [(google.api.field_behavior) = IMMUTABLE]; @@ -189,9 +239,20 @@ message PageMetricSpec { // The set of metrics to be computed for each intersection BasicMetricSetSpec basic = 2 [ + deprecated = true, (google.api.field_behavior) = IMMUTABLE, (google.api.field_behavior) = REQUIRED ]; + + // Non-cumulative metrics for the various intersections + BasicMetricSetSpec non_cumulative = 3 + [(google.api.field_behavior) = IMMUTABLE]; + + // Cumulative metrics for the various intersections + BasicMetricSetSpec cumulative = 4 [(google.api.field_behavior) = IMMUTABLE]; + + // New reach metrics + NewReachMetricSetSpec new = 5 [(google.api.field_behavior) = IMMUTABLE]; } // Compute n-way intersections ComponentIntersectionMetricSetSpec component_intersection = 4 @@ -251,6 +312,14 @@ message Page { // The time interval over which the metrics were computed google.type.Interval time_interval = 2 + [deprecated = true, (google.api.field_behavior) = IMMUTABLE]; + + // The time interval over which non-cumulative results are computed. + google.type.Interval non_cumulative_time_interval = 6 + [(google.api.field_behavior) = IMMUTABLE]; + + // The time interval over which cumulative results are computed. + google.type.Interval cumulative_time_interval = 7 [(google.api.field_behavior) = IMMUTABLE]; // The windowing spec that was applied @@ -278,21 +347,44 @@ message Page { // The k+ reach where the index is frequency - 1. repeated int32 k_plus_reach = 3 [(google.api.field_behavior) = IMMUTABLE]; // The percent k+ reach - repeated float percent_k_plus_reach = 4 - [(google.api.field_behavior) = IMMUTABLE]; + repeated float percent_k_plus_reach = 4; // The average frequency float average_frequency = 5 [(google.api.field_behavior) = IMMUTABLE]; + // The frequency histogram where the index of the array is frequency-1 + repeated float frequency_histogram = 8 + [(google.api.field_behavior) = IMMUTABLE]; // The impression count int32 impressions = 6 [(google.api.field_behavior) = IMMUTABLE]; // The gross ratings points float grps = 7 [(google.api.field_behavior) = IMMUTABLE]; } + + // Metrics associated with the new reach of the reporting_unit + // or component thereof. + message NewReachMetricSet { + // The new reach + int32 reach = 1 [(google.api.field_behavior) = IMMUTABLE]; + // The impressions associated with the new reach + int32 impressions = 2 [(google.api.field_behavior) = IMMUTABLE]; + } + // Metrics for the entire reporting_unit. message ReportingUnitMetricSet { // The metrics for the union of the reporting_unit components - BasicMetricSet basic = 1 [(google.api.field_behavior) = IMMUTABLE]; + BasicMetricSet basic = 1 + [deprecated = true, (google.api.field_behavior) = IMMUTABLE]; + + // The non-cumulative metrics for the union of the reporting_unit + // components. + BasicMetricSet non_cumulative = 3 + [(google.api.field_behavior) = IMMUTABLE]; + + // The cumulative metrics for the union of the reporting_unit components. + BasicMetricSet cumulative = 4 [(google.api.field_behavior) = IMMUTABLE]; + // The metrics associated with the new reach of the reporting_unit + NewReachMetricSet new = 5 [(google.api.field_behavior) = IMMUTABLE]; - // The stacked incremental reach of the ReportingUnit. + // The stacked incremental reach of the Reporting Unit. // // For example if the units in the ReportingUnit were "rs1", "rs2", // "rs3" then the values in this array are as follows: @@ -301,16 +393,37 @@ message Page { // 3. reach(rs1+rs2+rs3) - reach(rs1+rs2) repeated int32 stacked_incremental_reach = 2; } - // Metrics for the whole reporting_unit + // The results for the whole Reporting Unit ReportingUnitMetricSet reporting_unit = 2; // Metrics for a single component of the reporting_unit. message ComponentMetricSet { - // The basic metrics for this component - BasicMetricSet basic = 1 [(google.api.field_behavior) = IMMUTABLE]; + // The basic metrics for a reporting_unit component + BasicMetricSet basic = 1 + [deprecated = true, (google.api.field_behavior) = IMMUTABLE]; - // The component's unique reach + // The non-cumulative basic metrics for a reporting_unit component + BasicMetricSet non_cumulative = 3 + [(google.api.field_behavior) = IMMUTABLE]; + + // The cumulative basic metrics for a reporting_unit component + BasicMetricSet cumulative = 4 [(google.api.field_behavior) = IMMUTABLE]; + + // The unique reach of a reporting_unit component int32 unique_reach = 2 [(google.api.field_behavior) = IMMUTABLE]; + + // The count of impressions associated with the unique reach + // of a reporting_unit component + int32 unique_reach_impressions = 5 + [(google.api.field_behavior) = IMMUTABLE]; + + // Metrics associated with the new reach of a reporting_unit component + NewReachMetricSet new = 6 [(google.api.field_behavior) = IMMUTABLE]; + + // Metrics associated with the new unique reach of a reporting_unit + // component + NewReachMetricSet new_unique = 7 + [(google.api.field_behavior) = IMMUTABLE]; } // Entry for `components` map. message ComponentMetricSetMapEntry { @@ -342,7 +455,18 @@ message Page { // ReportingSet resource names when used with an AdvancedReport. repeated string components = 1 [(google.api.field_behavior) = IMMUTABLE]; // Basic metrics for the intersection of the components - BasicMetricSet basic = 2 [(google.api.field_behavior) = IMMUTABLE]; + BasicMetricSet basic = 2 + [deprecated = true, (google.api.field_behavior) = IMMUTABLE]; + + // Non-cumulative metrics for the intersection of the components + BasicMetricSet non_cumulative = 3 + [(google.api.field_behavior) = IMMUTABLE]; + + // Cumulative metrics for the intersection of the components + BasicMetricSet cumulative = 4 [(google.api.field_behavior) = IMMUTABLE]; + + // Metrics associated with the new reach of the components + NewReachMetricSet new = 5 [(google.api.field_behavior) = IMMUTABLE]; } // The metrics for the requested intersections repeated ComponentIntersectionMetricSet component_intersections = 4 diff --git a/src/main/proto/wfa/measurement/reporting/v2alpha/page_template.proto b/src/main/proto/wfa/measurement/reporting/v2alpha/page_template.proto new file mode 100644 index 00000000000..0a2cf5b45f0 --- /dev/null +++ b/src/main/proto/wfa/measurement/reporting/v2alpha/page_template.proto @@ -0,0 +1,65 @@ +// Copyright 2024 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. + +syntax = "proto3"; + +package wfa.measurement.reporting.v2alpha; + +import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; +import "wfa/measurement/reporting/v2alpha/page.proto"; + +option java_package = "org.wfanet.measurement.reporting.v2alpha"; +option java_multiple_files = true; +option java_outer_classname = "PageTemplateProto"; + +// Resource representing a Page Template +// +// A PageTempalte is essentially a PageSpec with an empty ReportingUnit. The +// ReportingUnit is determined when the PageTemplate is instantiated. +message PageTemplate { + option (google.api.resource) = { + type: "reporting.halo-cmm.org/PageTemplate" + // TODO(@kungfucraig): Make this multi-parented so that local markets and + // Halo can define built-in templates. + pattern: "measurementConsumers/{measurement_consumer}/pageTemplates/{page_template}" + singular: "pageTemplate" + plural: "pageTemplates" + }; + + // Resource name. + string name = 1 [(google.api.field_behavior) = IDENTIFIER]; + + // A user friendly display name for the template + string display_name = 2 [(google.api.field_behavior) = IMMUTABLE]; + + // Specifies the window over which metrics are computed + // and whether they are cumulative or not. + WindowingSpec windowing_spec = 3 [ + (google.api.field_behavior) = REQUIRED, + (google.api.field_behavior) = IMMUTABLE + ]; + + // Specfies the dimensions over which the report is filtered and grouped. + DimensionSpec dimension_spec = 4 [ + (google.api.field_behavior) = REQUIRED, + (google.api.field_behavior) = IMMUTABLE + ]; + + // Specifies the Metrics to compute. + PageMetricSpec metric_spec = 5 [ + (google.api.field_behavior) = REQUIRED, + (google.api.field_behavior) = IMMUTABLE + ]; +} diff --git a/src/main/proto/wfa/measurement/reporting/v2alpha/page_templates_service.proto b/src/main/proto/wfa/measurement/reporting/v2alpha/page_templates_service.proto new file mode 100644 index 00000000000..67b2cf4df10 --- /dev/null +++ b/src/main/proto/wfa/measurement/reporting/v2alpha/page_templates_service.proto @@ -0,0 +1,167 @@ +// Copyright 2024 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. + +syntax = "proto3"; + +package wfa.measurement.reporting.v2alpha; + +import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; +import "google/protobuf/timestamp.proto"; +import "wfa/measurement/reporting/v2alpha/page.proto"; +import "wfa/measurement/reporting/v2alpha/page_template.proto"; +import "wfa/measurement/reporting/v2alpha/reporting_unit.proto"; + +option java_package = "org.wfanet.measurement.reporting.v2alpha"; +option java_multiple_files = true; +option java_outer_classname = "PageTemplatesServiceProto"; + +service PageTemplates { + rpc CreatePageTemplate(CreatePageTemplateRequest) returns (PageTemplate) { + option (google.api.http) = { + post: "/v2alpha/{parent=measurementConsumers/*}/pageTemplates" + body: "pageTemplate" + }; + option (google.api.method_signature) = "parent,pageTemplate"; + } + + // Returns the `PageTemplate` with the given resource key. + rpc GetPageTemplate(GetPageTemplateRequest) returns (PageTemplate) { + option (google.api.http) = { + get: "/v2alpha/{name=measurementConsumers/*/pageTemplates/*}" + }; + option (google.api.method_signature) = "name"; + } + + // Ordered by `name` ascending. + rpc ListPageTemplates(ListPageTemplatesRequest) + returns (ListPageTemplatesResponse) { + option (google.api.http) = { + get: "/v2alpha/{parent=measurementConsumers/*}/pageTemplates" + }; + option (google.api.method_signature) = "parent"; + } + + // Creates a PageSpec from the PageTemplate. + // TODO(@kungfucraig): Discuss choice of verb. + rpc InstantiatePageSpec(InstantiatePageSpecRequest) returns (PageSpec) { + option (google.api.http) = { + get: "/v2alpha/{name=measurementConsumers/*/pageTemplates/*}" + }; + option (google.api.method_signature) = "name"; + } +} + +// Request message for `CreatePageTemplate` method +message CreatePageTemplateRequest { + // The parent Measurement Consumer + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + child_type: "reporting.halo-cmm.org/PageTemplate" + } + ]; + + // The ID to use for the page template, which will become the final component + // of the page template's resource name. + // + // This must conform to RFC 1034, with the additional restriction that all + // letters must be lower-case. + string page_template_id = 2 [(google.api.field_behavior) = REQUIRED]; + + // The PageTemplate to create. + PageTemplate page_template = 3; + + // A unique identifier for this request. Restricted to 36 ASCII characters. + // A random UUID is recommended. + // This request is only idempotent if a `request_id` is provided. + string request_id = 4; +} + +// Request message for `GetPageTemplate` method +message GetPageTemplateRequest { + // The name of the Page Template to retrieve. + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "reporting.halo-cmm.org/PageTemplate" + } + ]; +} + +// Request message for `ListPageTemplate` method +message ListPageTemplatesRequest { + // The parent Measurement Consumer + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + child_type: "reporting.halo-cmm.org/PageTemplate" + } + ]; + + // Filter criteria. Repeated fields are treated as logical ORs, and multiple + // fields are treated as logical ANDs. + // TODO(@kungfucraig): Discuss - Do we need filters for this? Search by name or + // display name could be useful, but should postpone that until it is clear + // how these will be used via an UI. + message Filter {} + + // Filter for the list of PageTemplates + // (-- api-linter: core::0132::request-field-types=disabled + // aip.dev/not-precedent: Structured filters are used instead of the + // AIP-160 filtering language --) + Filter filter = 2 [(google.api.field_behavior) = OPTIONAL]; + + // The maximum number of page templates to return. The service may return + // fewer than this value. If unspecified, at most 10 page templates reports + // will be returned. The maximum value is 25; values above 25 will be coerced + // to 25. + int32 page_size = 3 [(google.api.field_behavior) = OPTIONAL]; + + // A page token, received from a previous `ListPageTemplates` call. + // Provide this to retrieve the subsequent page. + // + // When paginating, all other parameters provided to `ListPageTemplates` must + // match the call that provided the page token. + string page_token = 4 [(google.api.field_behavior) = OPTIONAL]; +} + +// Response message for `ListPageTemplates` method. +message ListPageTemplatesResponse { + // The Page Templates that met the filter criteria + repeated PageTemplate page_templates = 1 + [(google.api.field_behavior) = OPTIONAL]; + + // 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 [(google.api.field_behavior) = OPTIONAL]; +} + +// Request message for `InstantiatePageSpec` +message InstantiatePageSpecRequest { + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "reporting.halo-cmm.org/PageTemplate" + } + ]; + + // The reporting unit to include in the returned PageSpec. + ReportingUnit reporting_unit = 2 [ + (google.api.field_behavior) = REQUIRED, + (google.api.field_behavior) = IMMUTABLE + ]; +} diff --git a/src/main/proto/wfa/measurement/reporting/v2alpha/report_schedule_iterations_service.proto b/src/main/proto/wfa/measurement/reporting/v2alpha/report_schedule_iterations_service.proto index 9f7f3319aaa..d1e50a59ab6 100644 --- a/src/main/proto/wfa/measurement/reporting/v2alpha/report_schedule_iterations_service.proto +++ b/src/main/proto/wfa/measurement/reporting/v2alpha/report_schedule_iterations_service.proto @@ -16,9 +16,9 @@ syntax = "proto3"; package wfa.measurement.reporting.v2alpha; -import "google/api/annotations.proto"; import "google/api/client.proto"; import "google/api/field_behavior.proto"; +import "google/api/annotations.proto"; import "google/api/resource.proto"; import "wfa/measurement/reporting/v2alpha/report_schedule_iteration.proto"; diff --git a/src/main/proto/wfa/measurement/reporting/v2alpha/report_schedules_service.proto b/src/main/proto/wfa/measurement/reporting/v2alpha/report_schedules_service.proto index 59c6929fdae..040cfc4e3ab 100644 --- a/src/main/proto/wfa/measurement/reporting/v2alpha/report_schedules_service.proto +++ b/src/main/proto/wfa/measurement/reporting/v2alpha/report_schedules_service.proto @@ -16,9 +16,9 @@ syntax = "proto3"; package wfa.measurement.reporting.v2alpha; -import "google/api/annotations.proto"; import "google/api/client.proto"; import "google/api/field_behavior.proto"; +import "google/api/annotations.proto"; import "google/api/resource.proto"; import "wfa/measurement/reporting/v2alpha/report_schedule.proto"; diff --git a/src/main/proto/wfa/measurement/reporting/v2alpha/reporting_sets_service.proto b/src/main/proto/wfa/measurement/reporting/v2alpha/reporting_sets_service.proto index 9ccfdd876bb..195dfedbdb5 100644 --- a/src/main/proto/wfa/measurement/reporting/v2alpha/reporting_sets_service.proto +++ b/src/main/proto/wfa/measurement/reporting/v2alpha/reporting_sets_service.proto @@ -16,9 +16,9 @@ syntax = "proto3"; package wfa.measurement.reporting.v2alpha; -import "google/api/annotations.proto"; import "google/api/client.proto"; import "google/api/field_behavior.proto"; +import "google/api/annotations.proto"; import "google/api/resource.proto"; import "wfa/measurement/reporting/v2alpha/reporting_set.proto"; diff --git a/src/main/proto/wfa/measurement/reporting/v2alpha/reports_service.proto b/src/main/proto/wfa/measurement/reporting/v2alpha/reports_service.proto index bcbe24b12d2..3af93e58831 100644 --- a/src/main/proto/wfa/measurement/reporting/v2alpha/reports_service.proto +++ b/src/main/proto/wfa/measurement/reporting/v2alpha/reports_service.proto @@ -16,9 +16,9 @@ syntax = "proto3"; package wfa.measurement.reporting.v2alpha; -import "google/api/annotations.proto"; import "google/api/client.proto"; import "google/api/field_behavior.proto"; +import "google/api/annotations.proto"; import "google/api/resource.proto"; import "wfa/measurement/reporting/v2alpha/report.proto";