Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support vertexai featureonlinestore_featureview GA (standard url) #9696

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 120 additions & 0 deletions mmv1/products/vertexai/FeatureOnlineStoreFeatureview.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# 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: FeatureOnlineStoreFeatureview
base_url: projects/{{project}}/locations/{{region}}/featureOnlineStores/{{feature_online_store}}/featureViews
create_url: projects/{{project}}/locations/{{region}}/featureOnlineStores/{{feature_online_store}}/featureViews?featureViewId={{name}}
self_link: projects/{{project}}/locations/{{region}}/featureOnlineStores/{{feature_online_store}}/featureViews/{{name}}
update_verb: :PATCH
update_mask: true
references: !ruby/object:Api::Resource::ReferenceLinks
guides:
'Official Documentation': 'https://cloud.google.com/vertex-ai/docs'
api: 'https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.featureOnlineStores.featureViews'
async: !ruby/object:Api::OpAsync
actions:
- create
- delete
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: |-
FeatureView is representation of values that the FeatureOnlineStore will serve based on its syncConfig.
import_format:
[
'projects/{{project}}/locations/{{region}}/featureOnlineStores/{{feature_online_store}}/featureViews/{{name}}',
]
autogen_async: false
examples:
- !ruby/object:Provider::Terraform::Examples
name: 'vertex_ai_featureonlinestore_featureview'
primary_resource_id: 'featureview'
vars:
name: 'example_feature_view'
parameters:
- !ruby/object:Api::Type::String
name: featureOnlineStore
description:
The name of the FeatureOnlineStore to use for the featureview.
url_param_only: true
immutable: true
required: true
- !ruby/object:Api::Type::String
name: 'region'
description: The region for the resource. It should be the same as the featureonlinestore region.
required: true
immutable: true
url_param_only: true
properties:
- !ruby/object:Api::Type::String
name: 'name'
description:
Name of the FeatureView. This value may be up to 60 characters, and
valid characters are [a-z0-9_]. The first character cannot be a number.
immutable: true
url_param_only: true
- !ruby/object:Api::Type::String
name: 'createTime'
output: true
description: |
The timestamp of when the featureOnlinestore 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 featureOnlinestore was last updated in RFC3339 UTC "Zulu" format, with nanosecond resolution and up to nine fractional digits.
- !ruby/object:Api::Type::KeyValueLabels
name: 'labels'
description: |
A set of key/value label pairs to assign to this FeatureView.
- !ruby/object:Api::Type::NestedObject
name: 'syncConfig'
description: |
Configures when data is to be synced/updated for this FeatureView. At the end of the sync the latest featureValues for each entityId of this FeatureView are made ready for online serving.
properties:
- !ruby/object:Api::Type::String
name: 'cron'
description: |
Cron schedule (https://en.wikipedia.org/wiki/Cron) to launch scheduled runs.
To explicitly set a timezone to the cron tab, apply a prefix in the cron tab: "CRON_TZ=${IANA_TIME_ZONE}" or "TZ=${IANA_TIME_ZONE}".
default_from_api: true
- !ruby/object:Api::Type::NestedObject
name: 'bigQuerySource'
description: |
Configures how data is supposed to be extracted from a BigQuery source to be loaded onto the FeatureOnlineStore.
properties:
- !ruby/object:Api::Type::String
name: 'uri'
required: true
description: |
The BigQuery view URI that will be materialized on each sync trigger based on FeatureView.SyncConfig.
- !ruby/object:Api::Type::Array
name: 'entityIdColumns'
required: true
description: |
Columns to construct entityId / row keys. Start by supporting 1 only.
item_type: Api::Type::String
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
resource "google_vertex_ai_feature_online_store" "featureonlinestore" {
name = "<%= ctx[:vars]['name'] %>"
labels = {
foo = "bar"
}
region = "us-central1"
bigtable {
auto_scaling {
min_node_count = 1
max_node_count = 2
cpu_utilization_target = 80
}
}
}

resource "google_bigquery_dataset" "tf-test-dataset" {

dataset_id = "<%= ctx[:vars]['name'] %>"
friendly_name = "test"
description = "This is a test description"
location = "US"
}

resource "google_bigquery_table" "tf-test-table" {
deletion_protection = false

dataset_id = google_bigquery_dataset.tf-test-dataset.dataset_id
table_id = "<%= ctx[:vars]['name'] %>"
schema = <<EOF
[
{
"name": "entity_id",
"mode": "NULLABLE",
"type": "STRING",
"description": "Test default entity_id"
},
{
"name": "test_entity_column",
"mode": "NULLABLE",
"type": "STRING",
"description": "test secondary entity column"
},
{
"name": "feature_timestamp",
"mode": "NULLABLE",
"type": "TIMESTAMP",
"description": "Default timestamp value"
}
]
EOF
}

resource "google_vertex_ai_feature_online_store_featureview" "<%= ctx[:primary_resource_id] %>" {
name = "<%= ctx[:vars]['name'] %>"
region = "us-central1"
feature_online_store = google_vertex_ai_feature_online_store.featureonlinestore.name
sync_config {
cron = "0 0 * * *"
}
big_query_source {
uri = "bq://${google_bigquery_table.tf-test-table.project}.${google_bigquery_table.tf-test-table.dataset_id}.${google_bigquery_table.tf-test-table.table_id}"
entity_id_columns = ["test_entity_column"]

}
}

data "google_project" "project" {
provider = google
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package vertexai_test

import (
"testing"

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

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

func TestAccVertexAIFeatureOnlineStoreFeatureview_vertexAiFeatureonlinestoreFeatureview_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: testAccCheckVertexAIFeatureOnlineStoreFeatureviewDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccVertexAIFeatureOnlineStoreFeatureview_vertexAiFeatureonlinestoreFeatureview_basic(context),
},
{
ResourceName: "google_vertex_ai_feature_online_store_featureview.featureview",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"name", "etag", "feature_online_store", "labels", "terraform_labels"},
},
{
Config: testAccVertexAIFeatureOnlineStoreFeatureview_vertexAiFeatureonlinestoreFeatureview_update(context),
},
{
ResourceName: "google_vertex_ai_feature_online_store_featureview.featureview",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"name", "feature_online_store", "labels", "terraform_labels"},
},
},
})
}

func testAccVertexAIFeatureOnlineStoreFeatureview_vertexAiFeatureonlinestoreFeatureview_basic(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_vertex_ai_feature_online_store" "featureonlinestore" {
name = "tf_test_featureonlinestore%{random_suffix}"
labels = {
foo = "bar"
}
region = "us-central1"
bigtable {
auto_scaling {
min_node_count = 1
max_node_count = 2
cpu_utilization_target = 80
}
}
}

resource "google_bigquery_dataset" "tf-test-dataset" {

dataset_id = "tf_test_dataset1_featureview%{random_suffix}"
friendly_name = "test"
description = "This is a test description"
location = "US"
}

resource "google_bigquery_table" "tf-test-table" {
deletion_protection = false

dataset_id = google_bigquery_dataset.tf-test-dataset.dataset_id
table_id = "tf_test_bq_table%{random_suffix}"
schema = <<EOF
[
{
"name": "entity_id",
"mode": "NULLABLE",
"type": "STRING",
"description": "Test default entity_id"
},
{
"name": "test_entity_column",
"mode": "NULLABLE",
"type": "STRING",
"description": "test secondary entity column"
},
{
"name": "feature_timestamp",
"mode": "NULLABLE",
"type": "TIMESTAMP",
"description": "Default timestamp value"
}
]
EOF
}

resource "google_vertex_ai_feature_online_store_featureview" "featureview" {
name = "tf_test_fv%{random_suffix}"
region = "us-central1"
labels = {
foo = "bar"
}
feature_online_store = google_vertex_ai_feature_online_store.featureonlinestore.name
sync_config {
cron = "0 0 * * *"
}
big_query_source {
uri = "bq://${google_bigquery_table.tf-test-table.project}.${google_bigquery_table.tf-test-table.dataset_id}.${google_bigquery_table.tf-test-table.table_id}"
entity_id_columns = ["test_entity_column"]

}
}

data "google_project" "project" {
provider = google
}
`, context)
}

func testAccVertexAIFeatureOnlineStoreFeatureview_vertexAiFeatureonlinestoreFeatureview_update(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_vertex_ai_feature_online_store" "featureonlinestore" {
name = "tf_test_featureonlinestore%{random_suffix}"
labels = {
foo = "bar"
}
region = "us-central1"
bigtable {
auto_scaling {
min_node_count = 1
max_node_count = 2
cpu_utilization_target = 80
}
}
}

resource "google_bigquery_dataset" "tf-test-dataset" {

dataset_id = "tf_test_dataset1_featureview%{random_suffix}"
friendly_name = "test"
description = "This is a test description"
location = "US"
}

resource "google_bigquery_table" "tf-test-table" {
deletion_protection = false

dataset_id = google_bigquery_dataset.tf-test-dataset.dataset_id
table_id = "tf_test_bq_table%{random_suffix}"
schema = <<EOF
[
{
"name": "entity_id",
"mode": "NULLABLE",
"type": "STRING",
"description": "Test default entity_id"
},
{
"name": "test_entity_column",
"mode": "NULLABLE",
"type": "STRING",
"description": "test secondary entity column"
},
{
"name": "feature_timestamp",
"mode": "NULLABLE",
"type": "TIMESTAMP",
"description": "Default timestamp value"
}
]
EOF
}

resource "google_vertex_ai_feature_online_store_featureview" "featureview" {
name = "tf_test_fv%{random_suffix}"
region = "us-central1"
labels = {
foo1 = "bar1"
}
feature_online_store = google_vertex_ai_feature_online_store.featureonlinestore.name
sync_config {
cron = "0 4 * * *"
}
big_query_source {
uri = "bq://${google_bigquery_table.tf-test-table.project}.${google_bigquery_table.tf-test-table.dataset_id}.${google_bigquery_table.tf-test-table.table_id}"
entity_id_columns = ["test_entity_column"]

}
}

data "google_project" "project" {
provider = google
}
`, context)
}