Skip to content

Commit

Permalink
feat(vertexai): Support google_vertex_ai_feature_group (#9520)
Browse files Browse the repository at this point in the history
  • Loading branch information
shotarok authored Dec 19, 2023
1 parent 999fed4 commit 49252d7
Show file tree
Hide file tree
Showing 4 changed files with 305 additions and 0 deletions.
107 changes: 107 additions & 0 deletions mmv1/products/vertexai/FeatureGroup.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Copyright 2023 Google Inc.
# 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.

--- !ruby/object:Api::Resource
name: FeatureGroup
base_url: projects/{{project}}/locations/{{region}}/featureGroups
create_url: projects/{{project}}/locations/{{region}}/featureGroups?featureGroupId={{name}}
self_link: projects/{{project}}/locations/{{region}}/featureGroups/{{name}}
update_verb: :PATCH
update_mask: true
create_verb: :POST
references: !ruby/object:Api::Resource::ReferenceLinks
guides:
'Creating a Feature Group': 'https://cloud.google.com/vertex-ai/docs/featurestore/latest/create-featuregroup'
api: 'https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.featureGroups'
async: !ruby/object:Api::OpAsync
actions:
- create
- delete
- update
operation: !ruby/object:Api::OpAsync::Operation
path: 'name'
base_url: '{{op_id}}'
wait_ms: 1000
result: !ruby/object:Api::OpAsync::Result
path: 'response'
resource_inside_response: true
status: !ruby/object:Api::OpAsync::Status
path: 'done'
complete: true
allowed:
- true
- false
error: !ruby/object:Api::OpAsync::Error
path: 'error'
message: 'message'
description: Vertex AI Feature Group.
autogen_async: false
examples:
- !ruby/object:Provider::Terraform::Examples
name: vertex_ai_feature_group
primary_resource_id: feature_group
ignore_read_extra:
- description
vars:
job_id: job_load
feature_group_name: example_feature_group
parameters:
- !ruby/object:Api::Type::String
name: region
description: The region of feature group. eg us-central1
url_param_only: true
immutable: true
properties:
- !ruby/object:Api::Type::String
name: name
description: The resource name of the Feature Group.
custom_flatten: templates/terraform/custom_flatten/name_from_self_link.erb
- !ruby/object:Api::Type::String
name: createTime
output: true
description: The timestamp of when the FeatureGroup was created in RFC3339 UTC "Zulu" format, with nanosecond resolution and up to nine fractional digits.
- !ruby/object:Api::Type::String
name: updateTime
output: true
description: The timestamp of when the FeatureGroup was last updated in RFC3339 UTC "Zulu" format, with nanosecond resolution and up to nine fractional digits.
- !ruby/object:Api::Type::String
name: etag
description: Used to perform consistent read-modify-write updates.
output: true
ignore_read: true
- !ruby/object:Api::Type::KeyValueLabels
name: labels
description: The labels with user-defined metadata to organize your FeatureGroup.
- !ruby/object:Api::Type::String
name: description
description: The description of the FeatureGroup.
# When API starts returning description, this line should be removed.
custom_flatten: templates/terraform/custom_flatten/vertex_ai_feature_group_ignore_description.go.erb
- !ruby/object:Api::Type::NestedObject
name: bigQuery
description: Indicates that features for this group come from BigQuery Table/View. By default treats the source as a sparse time series source, which is required to have an entityId and a feature_timestamp column in the source.
properties:
- !ruby/object:Api::Type::NestedObject
name: bigQuerySource
required: true
immutable: true
description: The BigQuery source URI that points to either a BigQuery Table or View.
properties:
- !ruby/object:Api::Type::String
name: 'inputUri'
required: true
description: 'BigQuery URI to a table, up to 2000 characters long. For example: `bq://projectId.bqDatasetId.bqTableId.`'
- !ruby/object:Api::Type::Array
name: entityIdColumns
description: Columns to construct entityId / row keys. Currently only supports 1 entity_id_column. If not provided defaults to entityId.
item_type: Api::Type::String
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<%# The license inside this block applies to this file.
# Copyright 2023 Google Inc.
# 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.
-%>
func flatten<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return d.Get("description")
}
43 changes: 43 additions & 0 deletions mmv1/templates/terraform/examples/vertex_ai_feature_group.tf.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
resource "google_vertex_ai_feature_group" "<%= ctx[:primary_resource_id] %>" {
name = "<%= ctx[:vars]['feature_group_name'] %>"
description = "A sample feature group"
region = "us-central1"
labels = {
label-one = "value-one"
}
big_query {
big_query_source {
# The source table must have a column named 'feature_timestamp' of type TIMESTAMP.
input_uri = "bq://${google_bigquery_table.sample_table.project}.${google_bigquery_table.sample_table.dataset_id}.${google_bigquery_table.sample_table.table_id}"
}
entity_id_columns = ["feature_id"]
}
}

resource "google_bigquery_dataset" "sample_dataset" {
dataset_id = "<%= ctx[:vars]['job_id'] %>_dataset"
friendly_name = "test"
description = "This is a test description"
location = "US"
}

resource "google_bigquery_table" "sample_table" {
deletion_protection = false
dataset_id = google_bigquery_dataset.sample_dataset.dataset_id
table_id = "<%= ctx[:vars]['job_id'] %>_table"

schema = <<EOF
[
{
"name": "feature_id",
"type": "STRING",
"mode": "NULLABLE"
},
{
"name": "feature_timestamp",
"type": "TIMESTAMP",
"mode": "NULLABLE"
}
]
EOF
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package vertexai_test

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"

"github.com/hashicorp/terraform-provider-google/google/acctest"
)

func TestAccVertexAIFeatureGroup_updated(t *testing.T) {
t.Parallel()

context := map[string]interface{}{
"random_suffix": acctest.RandString(t, 10),
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
CheckDestroy: testAccCheckVertexAIFeatureGroupDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccVertexAIFeatureGroup_basic(context),
},
{
ResourceName: "google_vertex_ai_feature_group.feature_group",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"etag", "region", "description", "labels", "terraform_labels"},
},
{
Config: testAccVertexAIFeatureGroup_updated(context),
},
{
ResourceName: "google_vertex_ai_feature_group.feature_group",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"etag", "region", "description", "labels", "terraform_labels"},
},
},
})
}

func testAccVertexAIFeatureGroup_basic(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_vertex_ai_feature_group" "feature_group" {
name = "tf_test_feature_group%{random_suffix}"
description = "A sample feature group"
region = "us-central1"
labels = {
label-one = "value-one"
}
big_query {
big_query_source {
input_uri = "bq://${google_bigquery_table.sample_table.project}.${google_bigquery_table.sample_table.dataset_id}.${google_bigquery_table.sample_table.table_id}"
}
entity_id_columns = ["feature_id"]
}
}
resource "google_bigquery_dataset" "sample_dataset" {
dataset_id = "tf_test_job_load%{random_suffix}_dataset"
friendly_name = "test"
description = "This is a test description"
location = "US"
}
resource "google_bigquery_table" "sample_table" {
deletion_protection = false
dataset_id = google_bigquery_dataset.sample_dataset.dataset_id
table_id = "tf_test_job_load%{random_suffix}_table"
schema = <<EOF
[
{
"name": "feature_id",
"type": "STRING",
"mode": "NULLABLE"
},
{
"name": "feature_timestamp",
"type": "TIMESTAMP",
"mode": "NULLABLE"
}
]
EOF
}
`, context)
}

func testAccVertexAIFeatureGroup_updated(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_vertex_ai_feature_group" "feature_group" {
name = "tf_test_feature_group%{random_suffix}"
description = "A sample feature group (updated)"
region = "us-central1"
labels = {
label-one = "value-one"
label-two = "value-two"
}
big_query {
big_query_source {
input_uri = "bq://${google_bigquery_table.sample_table.project}.${google_bigquery_table.sample_table.dataset_id}.${google_bigquery_table.sample_table.table_id}"
}
entity_id_columns = ["feature_id"]
}
}
resource "google_bigquery_dataset" "sample_dataset" {
dataset_id = "tf_test_job_load%{random_suffix}_dataset"
friendly_name = "test"
description = "This is a test description"
location = "US"
}
resource "google_bigquery_table" "sample_table" {
deletion_protection = false
dataset_id = google_bigquery_dataset.sample_dataset.dataset_id
table_id = "tf_test_job_load%{random_suffix}_table"
schema = <<EOF
[
{
"name": "feature_id",
"type": "STRING",
"mode": "NULLABLE"
},
{
"name": "feature_timestamp",
"type": "TIMESTAMP",
"mode": "NULLABLE"
}
]
EOF
}
`, context)
}

0 comments on commit 49252d7

Please sign in to comment.