// Copyright 2025 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.cloud.metastore.v1;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/cloud/metastore/v1/metastore.proto";
import "google/longrunning/operations.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";

option go_package = "cloud.google.com/go/metastore/apiv1/metastorepb;metastorepb";
option java_multiple_files = true;
option java_outer_classname = "MetastoreFederationProto";
option java_package = "com.google.cloud.metastore.v1";

// Configures and manages metastore federation services.
// Dataproc Metastore Federation Service allows federating a collection of
// backend metastores like BigQuery, Dataplex Lakes, and other Dataproc
// Metastores. The Federation Service exposes a gRPC URL through which metadata
// from the backend metastores are served at query time.
//
// The Dataproc Metastore Federation API defines the following resource model:
// * The service works with a collection of Google Cloud projects.
// * Each project has a collection of available locations.
// * Each location has a collection of federations.
// * Dataproc Metastore Federations are resources with names of the
// form:
// `projects/{project_number}/locations/{location_id}/federations/{federation_id}`.
service DataprocMetastoreFederation {
  option (google.api.default_host) = "metastore.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform";

  // Lists federations in a project and location.
  rpc ListFederations(ListFederationsRequest)
      returns (ListFederationsResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*}/federations"
    };
    option (google.api.method_signature) = "parent";
  }

  // Gets the details of a single federation.
  rpc GetFederation(GetFederationRequest) returns (Federation) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/federations/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Creates a metastore federation in a project and location.
  rpc CreateFederation(CreateFederationRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*}/federations"
      body: "federation"
    };
    option (google.api.method_signature) = "parent,federation,federation_id";
    option (google.longrunning.operation_info) = {
      response_type: "Federation"
      metadata_type: "google.cloud.metastore.v1.OperationMetadata"
    };
  }

  // Updates the fields of a federation.
  rpc UpdateFederation(UpdateFederationRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      patch: "/v1/{federation.name=projects/*/locations/*/federations/*}"
      body: "federation"
    };
    option (google.api.method_signature) = "federation,update_mask";
    option (google.longrunning.operation_info) = {
      response_type: "Federation"
      metadata_type: "google.cloud.metastore.v1.OperationMetadata"
    };
  }

  // Deletes a single federation.
  rpc DeleteFederation(DeleteFederationRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/locations/*/federations/*}"
    };
    option (google.api.method_signature) = "name";
    option (google.longrunning.operation_info) = {
      response_type: "google.protobuf.Empty"
      metadata_type: "google.cloud.metastore.v1.OperationMetadata"
    };
  }
}

// Represents a federation of multiple backend metastores.
message Federation {
  option (google.api.resource) = {
    type: "metastore.googleapis.com/Federation"
    pattern: "projects/{project}/locations/{location}/federations/{federation}"
  };

  // The current state of the federation.
  enum State {
    // The state of the metastore federation is unknown.
    STATE_UNSPECIFIED = 0;

    // The metastore federation is in the process of being created.
    CREATING = 1;

    // The metastore federation is running and ready to serve queries.
    ACTIVE = 2;

    // The metastore federation is being updated. It remains usable but cannot
    // accept additional update requests or be deleted at this time.
    UPDATING = 3;

    // The metastore federation is undergoing deletion. It cannot be used.
    DELETING = 4;

    // The metastore federation has encountered an error and cannot be used. The
    // metastore federation should be deleted.
    ERROR = 5;
  }

  // Immutable. The relative resource name of the federation, of the
  // form:
  // projects/{project_number}/locations/{location_id}/federations/{federation_id}`.
  string name = 1 [(google.api.field_behavior) = IMMUTABLE];

  // Output only. The time when the metastore federation was created.
  google.protobuf.Timestamp create_time = 2
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time when the metastore federation was last updated.
  google.protobuf.Timestamp update_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // User-defined labels for the metastore federation.
  map<string, string> labels = 4;

  // Immutable. The Apache Hive metastore version of the federation. All backend
  // metastore versions must be compatible with the federation version.
  string version = 5 [(google.api.field_behavior) = IMMUTABLE];

  // A map from `BackendMetastore` rank to `BackendMetastore`s from which the
  // federation service serves metadata at query time. The map key represents
  // the order in which `BackendMetastore`s should be evaluated to resolve
  // database names at query time and should be greater than or equal to zero. A
  // `BackendMetastore` with a lower number will be evaluated before a
  // `BackendMetastore` with a higher number.
  map<int32, BackendMetastore> backend_metastores = 6;

  // Output only. The federation endpoint.
  string endpoint_uri = 7 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The current state of the federation.
  State state = 8 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Additional information about the current state of the
  // metastore federation, if available.
  string state_message = 9 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The globally unique resource identifier of the metastore
  // federation.
  string uid = 10 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Represents a backend metastore for the federation.
message BackendMetastore {
  // The type of the backend metastore.
  enum MetastoreType {
    // The metastore type is not set.
    METASTORE_TYPE_UNSPECIFIED = 0;

    // The backend metastore is BigQuery.
    BIGQUERY = 2;

    // The backend metastore is Dataproc Metastore.
    DATAPROC_METASTORE = 3;
  }

  // The relative resource name of the metastore that is being federated.
  // The formats of the relative resource names for the currently supported
  // metastores are listed below:
  //
  // * BigQuery
  //     * `projects/{project_id}`
  // * Dataproc Metastore
  //     * `projects/{project_id}/locations/{location}/services/{service_id}`
  string name = 1;

  // The type of the backend metastore.
  MetastoreType metastore_type = 2;
}

// Request message for ListFederations.
message ListFederationsRequest {
  // Required. The relative resource name of the location of metastore
  // federations to list, in the following form:
  // `projects/{project_number}/locations/{location_id}`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "metastore.googleapis.com/Federation"
    }
  ];

  // Optional. The maximum number of federations to return. The response may
  // contain less than the maximum number. If unspecified, no more than 500
  // services are returned. The maximum value is 1000; values above 1000 are
  // changed to 1000.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A page token, received from a previous ListFederationServices
  // call. Provide this token to retrieve the subsequent page.
  //
  // To retrieve the first page, supply an empty page token.
  //
  // When paginating, other parameters provided to
  // ListFederationServices must match the call that provided the
  // page token.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The filter to apply to list results.
  string filter = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Specify the ordering of results as described in [Sorting
  // Order](https://cloud.google.com/apis/design/design_patterns#sorting_order).
  // If not specified, the results will be sorted in the default order.
  string order_by = 5 [(google.api.field_behavior) = OPTIONAL];
}

// Response message for ListFederations
message ListFederationsResponse {
  // The services in the specified location.
  repeated Federation federations = 1;

  // A token that 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;

  // Locations that could not be reached.
  repeated string unreachable = 3;
}

// Request message for GetFederation.
message GetFederationRequest {
  // Required. The relative resource name of the metastore federation to
  // retrieve, in the following form:
  //
  // `projects/{project_number}/locations/{location_id}/federations/{federation_id}`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "metastore.googleapis.com/Federation"
    }
  ];
}

// Request message for CreateFederation.
message CreateFederationRequest {
  // Required. The relative resource name of the location in which to create a
  // federation service, in the following form:
  //
  // `projects/{project_number}/locations/{location_id}`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "metastore.googleapis.com/Federation"
    }
  ];

  // Required. The ID of the metastore federation, which is used as the final
  // component of the metastore federation's name.
  //
  // This value must be between 2 and 63 characters long inclusive, begin with a
  // letter, end with a letter or number, and consist of alpha-numeric
  // ASCII characters or hyphens.
  string federation_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. The Metastore Federation to create. The `name` field is
  // ignored. The ID of the created metastore federation must be
  // provided in the request's `federation_id` field.
  Federation federation = 3 [(google.api.field_behavior) = REQUIRED];

  // Optional. A request ID. Specify a unique request ID to allow the server to
  // ignore the request if it has completed. The server will ignore subsequent
  // requests that provide a duplicate request ID for at least 60 minutes after
  // the first request.
  //
  // For example, if an initial request times out, followed by another request
  // with the same request ID, the server ignores the second request to prevent
  // the creation of duplicate commitments.
  //
  // The request ID must be a valid
  // [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Format)
  // A zero UUID (00000000-0000-0000-0000-000000000000) is not supported.
  string request_id = 4 [(google.api.field_behavior) = OPTIONAL];
}

// Request message for UpdateFederation.
message UpdateFederationRequest {
  // Required. A field mask used to specify the fields to be overwritten in the
  // metastore federation resource by the update.
  // Fields specified in the `update_mask` are relative to the resource (not
  // to the full request). A field is overwritten if it is in the mask.
  google.protobuf.FieldMask update_mask = 1
      [(google.api.field_behavior) = REQUIRED];

  // Required. The metastore federation to update. The server only merges fields
  // in the service if they are specified in `update_mask`.
  //
  // The metastore federation's `name` field is used to identify the
  // metastore service to be updated.
  Federation federation = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. A request ID. Specify a unique request ID to allow the server to
  // ignore the request if it has completed. The server will ignore subsequent
  // requests that provide a duplicate request ID for at least 60 minutes after
  // the first request.
  //
  // For example, if an initial request times out, followed by another request
  // with the same request ID, the server ignores the second request to prevent
  // the creation of duplicate commitments.
  //
  // The request ID must be a valid
  // [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Format)
  // A zero UUID (00000000-0000-0000-0000-000000000000) is not supported.
  string request_id = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Request message for DeleteFederation.
message DeleteFederationRequest {
  // Required. The relative resource name of the metastore federation to delete,
  // in the following form:
  //
  // `projects/{project_number}/locations/{location_id}/federations/{federation_id}`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "metastore.googleapis.com/Federation"
    }
  ];

  // Optional. A request ID. Specify a unique request ID to allow the server to
  // ignore the request if it has completed. The server will ignore subsequent
  // requests that provide a duplicate request ID for at least 60 minutes after
  // the first request.
  //
  // For example, if an initial request times out, followed by another request
  // with the same request ID, the server ignores the second request to prevent
  // the creation of duplicate commitments.
  //
  // The request ID must be a valid
  // [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Format)
  // A zero UUID (00000000-0000-0000-0000-000000000000) is not supported.
  string request_id = 2 [(google.api.field_behavior) = OPTIONAL];
}
