// Copyright 2021 Google LLC
//
// 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 google.storagetransfer.v1;

import "google/api/annotations.proto";
import "google/api/field_behavior.proto";
import "google/protobuf/any.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "google/rpc/code.proto";
import "google/type/date.proto";
import "google/type/timeofday.proto";

option cc_enable_arenas = true;
option csharp_namespace = "Google.Cloud.StorageTransfer.V1";
option go_package = "google.golang.org/genproto/googleapis/storagetransfer/v1;storagetransfer";
option java_outer_classname = "TransferTypes";
option java_package = "com.google.storagetransfer.v1.proto";
option php_namespace = "Google\\Cloud\\StorageTransfer\\V1";
option ruby_package = "Google::Cloud::StorageTransfer::V1";

// Google service account
message GoogleServiceAccount {
  // Email address of the service account.
  string account_email = 1;

  // Unique identifier for the service account.
  string subject_id = 2;
}

// AWS access key (see
// [AWS Security
// Credentials](https://docs.aws.amazon.com/general/latest/gr/aws-security-credentials.html)).
//
// For information on our data retention policy for user credentials, see
// [User credentials](/storage-transfer/docs/data-retention#user-credentials).
message AwsAccessKey {
  // Required. AWS access key ID.
  string access_key_id = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. AWS secret access key. This field is not returned in RPC
  // responses.
  string secret_access_key = 2 [(google.api.field_behavior) = REQUIRED];
}

// Azure credentials
//
// For information on our data retention policy for user credentials, see
// [User credentials](/storage-transfer/docs/data-retention#user-credentials).
message AzureCredentials {
  // Required. Azure shared access signature (SAS).
  //
  // <aside class="note">
  // <strong>Note:</strong>Copying data from Azure Data Lake
  // Storage (ADLS) Gen 2 is in [Preview](/products/#product-launch-stages).
  // During Preview, if you are copying data from ADLS Gen 2, you must use an
  // account SAS.
  // </aside>
  //
  // For more information about SAS, see
  // [Grant limited access to Azure Storage resources using shared access
  // signatures
  // (SAS)](https://docs.microsoft.com/en-us/azure/storage/common/storage-sas-overview).
  string sas_token = 2 [(google.api.field_behavior) = REQUIRED];
}

// Conditions that determine which objects will be transferred. Applies only
// to Cloud Data Sources such as S3, Azure, and Cloud Storage.
//
// The "last modification time" refers to the time of the
// last change to the object's content or metadata — specifically, this is
// the `updated` property of Cloud Storage objects, the `LastModified` field
// of S3 objects, and the `Last-Modified` header of Azure blobs.
message ObjectConditions {
  // If specified, only objects with a "last modification time" before
  // `NOW` - `min_time_elapsed_since_last_modification` and objects that don't
  //  have a "last modification time" are transferred.
  //
  // For each [TransferOperation][google.storagetransfer.v1.TransferOperation]
  // started by this [TransferJob][google.storagetransfer.v1.TransferJob], `NOW`
  // refers to the [start_time]
  // [google.storagetransfer.v1.TransferOperation.start_time] of the
  // `TransferOperation`.
  google.protobuf.Duration min_time_elapsed_since_last_modification = 1;

  // If specified, only objects with a "last modification time" on or after
  // `NOW` - `max_time_elapsed_since_last_modification` and objects that don't
  // have a "last modification time" are transferred.
  //
  // For each [TransferOperation][google.storagetransfer.v1.TransferOperation]
  // started by this [TransferJob][google.storagetransfer.v1.TransferJob],
  // `NOW` refers to the [start_time]
  // [google.storagetransfer.v1.TransferOperation.start_time] of the
  // `TransferOperation`.
  google.protobuf.Duration max_time_elapsed_since_last_modification = 2;

  // If you specify `include_prefixes`, Storage Transfer Service uses the items
  // in the `include_prefixes` array to determine which objects to include in a
  // transfer. Objects must start with one of the matching `include_prefixes`
  // for inclusion in the transfer. If [exclude_prefixes]
  // [google.storagetransfer.v1.ObjectConditions.exclude_prefixes] is specified,
  // objects must not start with any of the `exclude_prefixes` specified for
  // inclusion in the transfer.
  //
  // The following are requirements of `include_prefixes`:
  //
  //   * Each include-prefix can contain any sequence of Unicode characters, to
  //     a max length of 1024 bytes when UTF8-encoded, and must not contain
  //     Carriage Return or Line Feed characters.  Wildcard matching and regular
  //     expression matching are not supported.
  //
  //   * Each include-prefix must omit the leading slash. For example, to
  //     include the object `s3://my-aws-bucket/logs/y=2015/requests.gz`,
  //     specify the include-prefix as `logs/y=2015/requests.gz`.
  //
  //   * None of the include-prefix values can be empty, if specified.
  //
  //   * Each include-prefix must include a distinct portion of the object
  //     namespace. No include-prefix may be a prefix of another
  //     include-prefix.
  //
  // The max size of `include_prefixes` is 1000.
  //
  // For more information, see [Filtering objects from
  // transfers](/storage-transfer/docs/filtering-objects-from-transfers).
  repeated string include_prefixes = 3;

  // If you specify `exclude_prefixes`, Storage Transfer Service uses the items
  // in the `exclude_prefixes` array to determine which objects to exclude from
  // a transfer. Objects must not start with one of the matching
  // `exclude_prefixes` for inclusion in a transfer.
  //
  // The following are requirements of `exclude_prefixes`:
  //
  //   * Each exclude-prefix can contain any sequence of Unicode characters, to
  //     a max length of 1024 bytes when UTF8-encoded, and must not contain
  //     Carriage Return or Line Feed characters.  Wildcard matching and regular
  //     expression matching are not supported.
  //
  //   * Each exclude-prefix must omit the leading slash. For example, to
  //     exclude the object `s3://my-aws-bucket/logs/y=2015/requests.gz`,
  //     specify the exclude-prefix as `logs/y=2015/requests.gz`.
  //
  //   * None of the exclude-prefix values can be empty, if specified.
  //
  //   * Each exclude-prefix must exclude a distinct portion of the object
  //     namespace. No exclude-prefix may be a prefix of another
  //     exclude-prefix.
  //
  //   * If [include_prefixes]
  //     [google.storagetransfer.v1.ObjectConditions.include_prefixes] is
  //     specified, then each exclude-prefix must start with the value of a path
  //     explicitly included by `include_prefixes`.
  //
  // The max size of `exclude_prefixes` is 1000.
  //
  // For more information, see [Filtering objects from
  // transfers](/storage-transfer/docs/filtering-objects-from-transfers).
  repeated string exclude_prefixes = 4;

  // If specified, only objects with a "last modification time" on or after
  // this timestamp and objects that don't have a "last modification time" are
  // transferred.
  //
  // The `last_modified_since` and `last_modified_before` fields can be used
  // together for chunked data processing. For example, consider a script that
  // processes each day's worth of data at a time. For that you'd set each
  // of the fields as follows:
  //
  // *  `last_modified_since` to the start of the day
  //
  // *  `last_modified_before` to the end of the day
  google.protobuf.Timestamp last_modified_since = 5;

  // If specified, only objects with a "last modification time" before this
  // timestamp and objects that don't have a "last modification time" will be
  // transferred.
  google.protobuf.Timestamp last_modified_before = 6;
}

// In a GcsData resource, an object's name is the Cloud Storage object's
// name and its "last modification time" refers to the object's `updated`
// property of Cloud Storage objects, which changes when the content or the
// metadata of the object is updated.
message GcsData {
  // Required. Cloud Storage bucket name. Must meet
  // [Bucket Name Requirements](/storage/docs/naming#requirements).
  string bucket_name = 1 [(google.api.field_behavior) = REQUIRED];

  // Root path to transfer objects.
  //
  // Must be an empty string or full path name that ends with a '/'. This field
  // is treated as an object prefix. As such, it should generally not begin with
  // a '/'.
  //
  // The root path value must meet
  // [Object Name Requirements](/storage/docs/naming#objectnames).
  string path = 3;
}

// An AwsS3Data resource can be a data source, but not a data sink.
// In an AwsS3Data resource, an object's name is the S3 object's key name.
message AwsS3Data {
  // Required. S3 Bucket name (see
  // [Creating a
  // bucket](https://docs.aws.amazon.com/AmazonS3/latest/dev/create-bucket-get-location-example.html)).
  string bucket_name = 1 [(google.api.field_behavior) = REQUIRED];

  // Input only. AWS access key used to sign the API requests to the AWS S3
  // bucket. Permissions on the bucket must be granted to the access ID of the
  // AWS access key. This field is required.
  //
  // For information on our data retention policy for user credentials, see
  // [User credentials](/storage-transfer/docs/data-retention#user-credentials).
  AwsAccessKey aws_access_key = 2 [(google.api.field_behavior) = INPUT_ONLY];

  // Root path to transfer objects.
  //
  // Must be an empty string or full path name that ends with a '/'. This field
  // is treated as an object prefix. As such, it should generally not begin with
  // a '/'.
  string path = 3;

  // Input only. Role arn to support temporary credentials via
  // AssumeRoleWithWebIdentity.
  //
  // When role arn is provided, transfer service will fetch temporary
  // credentials for the session using AssumeRoleWithWebIdentity call for the
  // provided role using the [GoogleServiceAccount] for this project.
  string role_arn = 4 [(google.api.field_behavior) = INPUT_ONLY];
}

// An AzureBlobStorageData resource can be a data source, but not a data sink.
// An AzureBlobStorageData resource represents one Azure container. The storage
// account determines the [Azure
// endpoint](https://docs.microsoft.com/en-us/azure/storage/common/storage-create-storage-account#storage-account-endpoints).
// In an AzureBlobStorageData resource, a blobs's name is the [Azure Blob
// Storage blob's key
// name](https://docs.microsoft.com/en-us/rest/api/storageservices/naming-and-referencing-containers--blobs--and-metadata#blob-names).
message AzureBlobStorageData {
  // Required. The name of the Azure Storage account.
  string storage_account = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Input only. Credentials used to authenticate API requests to
  // Azure.
  //
  // For information on our data retention policy for user credentials, see
  // [User credentials](/storage-transfer/docs/data-retention#user-credentials).
  AzureCredentials azure_credentials = 2 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.field_behavior) = INPUT_ONLY
  ];

  // Required. The container to transfer from the Azure Storage account.
  string container = 4 [(google.api.field_behavior) = REQUIRED];

  // Root path to transfer objects.
  //
  // Must be an empty string or full path name that ends with a '/'. This field
  // is treated as an object prefix. As such, it should generally not begin with
  // a '/'.
  string path = 5;
}

// An HttpData resource specifies a list of objects on the web to be transferred
// over HTTP.  The information of the objects to be transferred is contained in
// a file referenced by a URL. The first line in the file must be
// `"TsvHttpData-1.0"`, which specifies the format of the file.  Subsequent
// lines specify the information of the list of objects, one object per list
// entry. Each entry has the following tab-delimited fields:
//
// * **HTTP URL** — The location of the object.
//
// * **Length** — The size of the object in bytes.
//
// * **MD5** — The base64-encoded MD5 hash of the object.
//
// For an example of a valid TSV file, see
// [Transferring data from
// URLs](https://cloud.google.com/storage-transfer/docs/create-url-list).
//
// When transferring data based on a URL list, keep the following in mind:
//
// * When an object located at `http(s)://hostname:port/<URL-path>` is
// transferred to a data sink, the name of the object at the data sink is
// `<hostname>/<URL-path>`.
//
// * If the specified size of an object does not match the actual size of the
// object fetched, the object will not be transferred.
//
// * If the specified MD5 does not match the MD5 computed from the transferred
// bytes, the object transfer will fail.
//
// * Ensure that each URL you specify is publicly accessible. For
// example, in Cloud Storage you can
// [share an object publicly]
// (/storage/docs/cloud-console#_sharingdata) and get a link to it.
//
// * Storage Transfer Service obeys `robots.txt` rules and requires the source
// HTTP server to support `Range` requests and to return a `Content-Length`
// header in each response.
//
// * [ObjectConditions][google.storagetransfer.v1.ObjectConditions] have no
// effect when filtering objects to transfer.
message HttpData {
  // Required. The URL that points to the file that stores the object list
  // entries. This file must allow public access.  Currently, only URLs with
  // HTTP and HTTPS schemes are supported.
  string list_url = 1 [(google.api.field_behavior) = REQUIRED];
}

// TransferOptions define the actions to be performed on objects in a transfer.
message TransferOptions {
  // When to overwrite objects that already exist in the sink. The default is
  // that only objects that are different from the source are ovewritten. If
  // true, all objects in the sink whose name matches an object in the source
  // will be overwritten with the source object.
  bool overwrite_objects_already_existing_in_sink = 1;

  // Whether objects that exist only in the sink should be deleted.
  //
  // **Note:** This option and [delete_objects_from_source_after_transfer]
  // [google.storagetransfer.v1.TransferOptions.delete_objects_from_source_after_transfer]
  // are mutually exclusive.
  bool delete_objects_unique_in_sink = 2;

  // Whether objects should be deleted from the source after they are
  // transferred to the sink.
  //
  // **Note:** This option and [delete_objects_unique_in_sink]
  // [google.storagetransfer.v1.TransferOptions.delete_objects_unique_in_sink]
  // are mutually exclusive.
  bool delete_objects_from_source_after_transfer = 3;
}

// Configuration for running a transfer.
message TransferSpec {
  // The write sink for the data.
  oneof data_sink {
    // A Cloud Storage data sink.
    GcsData gcs_data_sink = 4;
  }

  // The read source of the data.
  oneof data_source {
    // A Cloud Storage data source.
    GcsData gcs_data_source = 1;

    // An AWS S3 data source.
    AwsS3Data aws_s3_data_source = 2;

    // An HTTP URL data source.
    HttpData http_data_source = 3;

    // An Azure Blob Storage data source.
    AzureBlobStorageData azure_blob_storage_data_source = 8;
  }

  // Only objects that satisfy these object conditions are included in the set
  // of data source and data sink objects.  Object conditions based on
  // objects' "last modification time" do not exclude objects in a data sink.
  ObjectConditions object_conditions = 5;

  // If the option
  // [delete_objects_unique_in_sink][google.storagetransfer.v1.TransferOptions.delete_objects_unique_in_sink]
  // is `true` and time-based object conditions such as 'last modification time'
  // are specified, the request fails with an
  // [INVALID_ARGUMENT][google.rpc.Code.INVALID_ARGUMENT] error.
  TransferOptions transfer_options = 6;
}

// Transfers can be scheduled to recur or to run just once.
message Schedule {
  // Required. The start date of a transfer. Date boundaries are determined
  // relative to UTC time. If `schedule_start_date` and
  // [start_time_of_day][google.storagetransfer.v1.Schedule.start_time_of_day]
  // are in the past relative to the job's creation time, the transfer starts
  // the day after you schedule the transfer request.
  //
  // **Note:** When starting jobs at or near midnight UTC it is possible that
  // a job will start later than expected. For example, if you send an outbound
  // request on June 1 one millisecond prior to midnight UTC and the Storage
  // Transfer Service server receives the request on June 2, then it will create
  // a TransferJob with `schedule_start_date` set to June 2 and a
  // `start_time_of_day` set to midnight UTC. The first scheduled
  // [TransferOperation][google.storagetransfer.v1.TransferOperation] will take
  // place on June 3 at midnight UTC.
  google.type.Date schedule_start_date = 1
      [(google.api.field_behavior) = REQUIRED];

  // The last day a transfer runs. Date boundaries are determined relative to
  // UTC time. A job will run once per 24 hours within the following guidelines:
  //
  // *   If `schedule_end_date` and
  // [schedule_start_date][google.storagetransfer.v1.Schedule.schedule_start_date]
  // are the same and in
  //     the future relative to UTC, the transfer is executed only one time.
  // *   If `schedule_end_date` is later than `schedule_start_date`  and
  //     `schedule_end_date` is in the future relative to UTC, the job will
  //     run each day at
  //     [start_time_of_day][google.storagetransfer.v1.Schedule.start_time_of_day]
  //     through `schedule_end_date`.
  google.type.Date schedule_end_date = 2;

  // The time in UTC that a transfer job is scheduled to run. Transfers may
  // start later than this time.
  //
  // If `start_time_of_day` is not specified:
  //
  // *   One-time transfers run immediately.
  // *   Recurring transfers run immediately, and each day at midnight UTC,
  //     through
  //     [schedule_end_date][google.storagetransfer.v1.Schedule.schedule_end_date].
  //
  // If `start_time_of_day` is specified:
  //
  // *   One-time transfers run at the specified time.
  // *   Recurring transfers run at the specified time each day, through
  //     `schedule_end_date`.
  google.type.TimeOfDay start_time_of_day = 3;

  // The time in UTC that no further transfer operations are scheduled. Combined
  // with
  // [schedule_end_date][google.storagetransfer.v1.Schedule.schedule_end_date],
  // `end_time_of_day` specifies the end date and time for starting new transfer
  // operations. This field must be greater than or equal to the timestamp
  // corresponding to the combintation of
  // [schedule_start_date][google.storagetransfer.v1.Schedule.schedule_start_date]
  // and
  // [start_time_of_day][google.storagetransfer.v1.Schedule.start_time_of_day],
  // and is subject to the following:
  //
  // *   If `end_time_of_day` is not set and `schedule_end_date` is set, then
  //     a default value of `23:59:59` is used for `end_time_of_day`.
  //
  // *   If `end_time_of_day` is set and `schedule_end_date` is not set, then
  //     [INVALID_ARGUMENT][google.rpc.Code.INVALID_ARGUMENT] is returned.
  google.type.TimeOfDay end_time_of_day = 4;

  // Interval between the start of each scheduled TransferOperation. If
  // unspecified, the default value is 24 hours. This value may not be less than
  // 1 hour.
  google.protobuf.Duration repeat_interval = 5;
}

// This resource represents the configuration of a transfer job that runs
// periodically.
message TransferJob {
  // The status of the transfer job.
  enum Status {
    // Zero is an illegal value.
    STATUS_UNSPECIFIED = 0;

    // New transfers will be performed based on the schedule.
    ENABLED = 1;

    // New transfers will not be scheduled.
    DISABLED = 2;

    // This is a soft delete state. After a transfer job is set to this
    // state, the job and all the transfer executions are subject to
    // garbage collection. Transfer jobs become eligible for garbage collection
    // 30 days after their status is set to `DELETED`.
    DELETED = 3;
  }

  // A unique name (within the transfer project) assigned when the job is
  // created.  If this field is empty in a CreateTransferJobRequest, Storage
  // Transfer Service will assign a unique name. Otherwise, the specified name
  // is used as the unique name for this job.
  //
  // If the specified name is in use by a job, the creation request fails with
  // an [ALREADY_EXISTS][google.rpc.Code.ALREADY_EXISTS] error.
  //
  // This name must start with `"transferJobs/"` prefix and end with a letter or
  // a number, and should be no more than 128 characters. This name must not
  // start with 'transferJobs/OPI'. 'transferJobs/OPI' is a reserved prefix.
  // Example:
  // `"transferJobs/^(?!OPI)[A-Za-z0-9-._~]*[A-Za-z0-9]$"`
  //
  // Invalid job names will fail with an
  // [INVALID_ARGUMENT][google.rpc.Code.INVALID_ARGUMENT] error.
  string name = 1;

  // A description provided by the user for the job. Its max length is 1024
  // bytes when Unicode-encoded.
  string description = 2;

  // The ID of the Google Cloud Platform Project that owns the job.
  string project_id = 3;

  // Transfer specification.
  TransferSpec transfer_spec = 4;

  // Notification configuration.
  NotificationConfig notification_config = 11;

  // Specifies schedule for the transfer job.
  // This is an optional field. When the field is not set, the job will never
  // execute a transfer, unless you invoke RunTransferJob or update the job to
  // have a non-empty schedule.
  Schedule schedule = 5;

  // Status of the job. This value MUST be specified for
  // `CreateTransferJobRequests`.
  //
  // **Note:** The effect of the new job status takes place during a subsequent
  // job run. For example, if you change the job status from
  // [ENABLED][google.storagetransfer.v1.TransferJob.Status.ENABLED] to
  // [DISABLED][google.storagetransfer.v1.TransferJob.Status.DISABLED], and an
  // operation spawned by the transfer is running, the status change would not
  // affect the current operation.
  Status status = 6;

  // Output only. The time that the transfer job was created.
  google.protobuf.Timestamp creation_time = 7
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time that the transfer job was last modified.
  google.protobuf.Timestamp last_modification_time = 8
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time that the transfer job was deleted.
  google.protobuf.Timestamp deletion_time = 9
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // The name of the most recently started TransferOperation of this JobConfig.
  // Present if a TransferOperation has been created for this JobConfig.
  string latest_operation_name = 12;
}

// An entry describing an error that has occurred.
message ErrorLogEntry {
  // Required. A URL that refers to the target (a data source, a data sink,
  // or an object) with which the error is associated.
  string url = 1 [(google.api.field_behavior) = REQUIRED];

  // A list of messages that carry the error details.
  repeated string error_details = 3;
}

// A summary of errors by error code, plus a count and sample error log
// entries.
message ErrorSummary {
  // Required.
  google.rpc.Code error_code = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Count of this type of error.
  int64 error_count = 2 [(google.api.field_behavior) = REQUIRED];

  // Error samples.
  //
  // At most 5 error log entries will be recorded for a given
  // error code for a single transfer operation.
  repeated ErrorLogEntry error_log_entries = 3;
}

// A collection of counters that report the progress of a transfer operation.
message TransferCounters {
  // Objects found in the data source that are scheduled to be transferred,
  // excluding any that are filtered based on object conditions or skipped due
  // to sync.
  int64 objects_found_from_source = 1;

  // Bytes found in the data source that are scheduled to be transferred,
  // excluding any that are filtered based on object conditions or skipped due
  // to sync.
  int64 bytes_found_from_source = 2;

  // Objects found only in the data sink that are scheduled to be deleted.
  int64 objects_found_only_from_sink = 3;

  // Bytes found only in the data sink that are scheduled to be deleted.
  int64 bytes_found_only_from_sink = 4;

  // Objects in the data source that are not transferred because they already
  // exist in the data sink.
  int64 objects_from_source_skipped_by_sync = 5;

  // Bytes in the data source that are not transferred because they already
  // exist in the data sink.
  int64 bytes_from_source_skipped_by_sync = 6;

  // Objects that are copied to the data sink.
  int64 objects_copied_to_sink = 7;

  // Bytes that are copied to the data sink.
  int64 bytes_copied_to_sink = 8;

  // Objects that are deleted from the data source.
  int64 objects_deleted_from_source = 9;

  // Bytes that are deleted from the data source.
  int64 bytes_deleted_from_source = 10;

  // Objects that are deleted from the data sink.
  int64 objects_deleted_from_sink = 11;

  // Bytes that are deleted from the data sink.
  int64 bytes_deleted_from_sink = 12;

  // Objects in the data source that failed to be transferred or that failed
  // to be deleted after being transferred.
  int64 objects_from_source_failed = 13;

  // Bytes in the data source that failed to be transferred or that failed to
  // be deleted after being transferred.
  int64 bytes_from_source_failed = 14;

  // Objects that failed to be deleted from the data sink.
  int64 objects_failed_to_delete_from_sink = 15;

  // Bytes that failed to be deleted from the data sink.
  int64 bytes_failed_to_delete_from_sink = 16;
}

// Specification to configure notifications published to Cloud Pub/Sub.
// Notifications will be published to the customer-provided topic using the
// following `PubsubMessage.attributes`:
//
// * `"eventType"`: one of the
// [EventType][google.storagetransfer.v1.NotificationConfig.EventType] values
// * `"payloadFormat"`: one of the
// [PayloadFormat][google.storagetransfer.v1.NotificationConfig.PayloadFormat]
// values
// * `"projectId"`: the
// [project_id][google.storagetransfer.v1.TransferOperation.project_id] of the
// `TransferOperation`
// * `"transferJobName"`: the
// [transfer_job_name][google.storagetransfer.v1.TransferOperation.transfer_job_name]
// of the `TransferOperation`
// * `"transferOperationName"`: the
// [name][google.storagetransfer.v1.TransferOperation.name] of the
// `TransferOperation`
//
// The `PubsubMessage.data` will contain a
// [TransferOperation][google.storagetransfer.v1.TransferOperation] resource
// formatted according to the specified `PayloadFormat`.
message NotificationConfig {
  // Enum for specifying event types for which notifications are to be
  // published.
  //
  // Additional event types may be added in the future. Clients should either
  // safely ignore unrecognized event types or explicitly specify which event
  // types they are prepared to accept.
  enum EventType {
    // Illegal value, to avoid allowing a default.
    EVENT_TYPE_UNSPECIFIED = 0;

    // `TransferOperation` completed with status
    // [SUCCESS][google.storagetransfer.v1.TransferOperation.Status.SUCCESS].
    TRANSFER_OPERATION_SUCCESS = 1;

    // `TransferOperation` completed with status
    // [FAILED][google.storagetransfer.v1.TransferOperation.Status.FAILED].
    TRANSFER_OPERATION_FAILED = 2;

    // `TransferOperation` completed with status
    // [ABORTED][google.storagetransfer.v1.TransferOperation.Status.ABORTED].
    TRANSFER_OPERATION_ABORTED = 3;
  }

  // Enum for specifying the format of a notification message's payload.
  enum PayloadFormat {
    // Illegal value, to avoid allowing a default.
    PAYLOAD_FORMAT_UNSPECIFIED = 0;

    // No payload is included with the notification.
    NONE = 1;

    // `TransferOperation` is [formatted as a JSON
    // response](https://developers.google.com/protocol-buffers/docs/proto3#json),
    // in application/json.
    JSON = 2;
  }

  // Required. The `Topic.name` of the Cloud Pub/Sub topic to which to publish
  // notifications. Must be of the format: `projects/{project}/topics/{topic}`.
  // Not matching this format will result in an
  // [INVALID_ARGUMENT][google.rpc.Code.INVALID_ARGUMENT] error.
  string pubsub_topic = 1 [(google.api.field_behavior) = REQUIRED];

  // Event types for which a notification is desired. If empty, send
  // notifications for all event types.
  repeated EventType event_types = 2;

  // Required. The desired format of the notification message payloads.
  PayloadFormat payload_format = 3 [(google.api.field_behavior) = REQUIRED];
}

// A description of the execution of a transfer.
message TransferOperation {
  // The status of a TransferOperation.
  enum Status {
    // Zero is an illegal value.
    STATUS_UNSPECIFIED = 0;

    // In progress.
    IN_PROGRESS = 1;

    // Paused.
    PAUSED = 2;

    // Completed successfully.
    SUCCESS = 3;

    // Terminated due to an unrecoverable failure.
    FAILED = 4;

    // Aborted by the user.
    ABORTED = 5;

    // Temporarily delayed by the system. No user action is required.
    QUEUED = 6;
  }

  // A globally unique ID assigned by the system.
  string name = 1;

  // The ID of the Google Cloud Platform Project that owns the operation.
  string project_id = 2;

  // Transfer specification.
  TransferSpec transfer_spec = 3;

  // Notification configuration.
  NotificationConfig notification_config = 10;

  // Start time of this transfer execution.
  google.protobuf.Timestamp start_time = 4;

  // End time of this transfer execution.
  google.protobuf.Timestamp end_time = 5;

  // Status of the transfer operation.
  Status status = 6;

  // Information about the progress of the transfer operation.
  TransferCounters counters = 7;

  // Summarizes errors encountered with sample error log entries.
  repeated ErrorSummary error_breakdowns = 8;

  // The name of the transfer job that triggers this transfer operation.
  string transfer_job_name = 9;
}
