@@ -138,6 +138,10 @@ func materializedlViewPath(project, instance, materializedView string) string {
138138 return fmt .Sprintf ("%s/materializedViews/%s" , instancePrefix (project , instance ), materializedView )
139139}
140140
141+ func appProfilePath (project , instance , appProfile string ) string {
142+ return fmt .Sprintf ("%s/appProfiles/%s" , instancePrefix (project , instance ), appProfile )
143+ }
144+
141145// EncryptionInfo represents the encryption info of a table.
142146type EncryptionInfo struct {
143147 Status * Status
@@ -1843,33 +1847,125 @@ func (iac *InstanceAdminClient) InstanceIAM(instanceID string) *iam.Handle {
18431847
18441848// Routing policies.
18451849const (
1850+ // Deprecated: Use MultiClusterRoutingUseAnyConfig instead.
18461851 // MultiClusterRouting is a policy that allows read/write requests to be
18471852 // routed to any cluster in the instance. Requests will will fail over to
18481853 // another cluster in the event of transient errors or delays. Choosing
18491854 // this option sacrifices read-your-writes consistency to improve
18501855 // availability.
18511856 MultiClusterRouting = "multi_cluster_routing_use_any"
1857+ // Deprecated: Use SingleClusterRoutingConfig instead.
18521858 // SingleClusterRouting is a policy that unconditionally routes all
18531859 // read/write requests to a specific cluster. This option preserves
18541860 // read-your-writes consistency, but does not improve availability.
18551861 SingleClusterRouting = "single_cluster_routing"
18561862)
18571863
1858- // ProfileConf contains the information necessary to create an profile
1864+ // ProfileConf contains the information necessary to create a profile
18591865type ProfileConf struct {
1860- Name string
1861- ProfileID string
1862- InstanceID string
1863- Etag string
1864- Description string
1865- RoutingPolicy string
1866- ClusterID string
1866+ Name string
1867+ ProfileID string
1868+ InstanceID string
1869+ Etag string
1870+ Description string
1871+
1872+ RoutingConfig RoutingPolicyConfig
1873+ Isolation AppProfileIsolation
1874+
1875+ // Deprecated: Use RoutingConfig instead.
1876+ // Ignored when RoutingConfig is set.
1877+ RoutingPolicy string
1878+ // Deprecated: Use RoutingConfig with SingleClusterRoutingConfig instead.
1879+ // Ignored when RoutingConfig is set.
1880+ // To use with RoutingPolicy field while specifying SingleClusterRouting.
1881+ ClusterID string
1882+ // Deprecated: Use RoutingConfig with SingleClusterRoutingConfig instead.
1883+ // Ignored when RoutingConfig is set.
1884+ // To use with RoutingPolicy field while specifying SingleClusterRouting.
18671885 AllowTransactionalWrites bool
18681886
18691887 // If true, warnings are ignored
18701888 IgnoreWarnings bool
18711889}
18721890
1891+ func setIsolation (profile * btapb.AppProfile , isolation AppProfileIsolation ) error {
1892+ if isolation != nil {
1893+ switch cfg := isolation .(type ) {
1894+ case * StandardIsolation :
1895+ profile .Isolation = & btapb.AppProfile_StandardIsolation_ {
1896+ StandardIsolation : & btapb.AppProfile_StandardIsolation {
1897+ Priority : btapb .AppProfile_Priority (cfg .Priority ),
1898+ },
1899+ }
1900+ case * DataBoostIsolationReadOnly :
1901+ dataBoostProto := & btapb.AppProfile_DataBoostIsolationReadOnly {}
1902+ cbo := btapb .AppProfile_DataBoostIsolationReadOnly_ComputeBillingOwner (cfg .ComputeBillingOwner )
1903+ dataBoostProto .ComputeBillingOwner = & cbo
1904+ profile .Isolation = & btapb.AppProfile_DataBoostIsolationReadOnly_ {DataBoostIsolationReadOnly : dataBoostProto }
1905+ default :
1906+ return fmt .Errorf ("bigtable: unknown isolation config type: %T" , cfg )
1907+ }
1908+ }
1909+ return nil
1910+ }
1911+
1912+ func setRoutingPolicy (appProfile * btapb.AppProfile , rpc RoutingPolicyConfig , routingPolicy optional.String ,
1913+ clusterID string , allowTransactionalWrites bool , allowNil bool ) error {
1914+ if allowNil && routingPolicy == nil && rpc == nil {
1915+ return nil
1916+ }
1917+ if rpc != nil {
1918+ switch cfg := rpc .(type ) {
1919+ case * MultiClusterRoutingUseAnyConfig :
1920+ appProfile .RoutingPolicy = & btapb.AppProfile_MultiClusterRoutingUseAny_ {
1921+ MultiClusterRoutingUseAny : & btapb.AppProfile_MultiClusterRoutingUseAny {
1922+ ClusterIds : cfg .ClusterIDs ,
1923+ },
1924+ }
1925+ if cfg .Affinity != nil {
1926+ switch cfg .Affinity .(type ) {
1927+ case * RowAffinity :
1928+ appProfile .GetMultiClusterRoutingUseAny ().Affinity = & btapb.AppProfile_MultiClusterRoutingUseAny_RowAffinity_ {
1929+ RowAffinity : & btapb.AppProfile_MultiClusterRoutingUseAny_RowAffinity {},
1930+ }
1931+ default :
1932+ return errors .New ("bigtable: invalid affinity in MultiClusterRoutingUseAnyConfig" )
1933+ }
1934+ }
1935+ case * SingleClusterRoutingConfig :
1936+ appProfile .RoutingPolicy = & btapb.AppProfile_SingleClusterRouting_ {
1937+ SingleClusterRouting : & btapb.AppProfile_SingleClusterRouting {
1938+ ClusterId : cfg .ClusterID ,
1939+ AllowTransactionalWrites : cfg .AllowTransactionalWrites ,
1940+ },
1941+ }
1942+ default :
1943+ return fmt .Errorf ("bigtable: unknown RoutingConfig type: %T" , cfg )
1944+ }
1945+ } else { // Fallback to deprecated fields
1946+ if routingPolicy == nil {
1947+ return errors .New ("bigtable: at least one of RoutingPolicy or RoutingConfig must be set" )
1948+ }
1949+
1950+ switch routingPolicy {
1951+ case MultiClusterRouting :
1952+ appProfile .RoutingPolicy = & btapb.AppProfile_MultiClusterRoutingUseAny_ {
1953+ MultiClusterRoutingUseAny : & btapb.AppProfile_MultiClusterRoutingUseAny {},
1954+ }
1955+ case SingleClusterRouting :
1956+ appProfile .RoutingPolicy = & btapb.AppProfile_SingleClusterRouting_ {
1957+ SingleClusterRouting : & btapb.AppProfile_SingleClusterRouting {
1958+ ClusterId : clusterID ,
1959+ AllowTransactionalWrites : allowTransactionalWrites ,
1960+ },
1961+ }
1962+ default :
1963+ return errors .New ("bigtable: invalid RoutingPolicy " + optional .ToString (routingPolicy ))
1964+ }
1965+ }
1966+ return nil
1967+ }
1968+
18731969// ProfileIterator iterates over profiles.
18741970type ProfileIterator struct {
18751971 items []* btapb.AppProfile
@@ -1882,11 +1978,22 @@ type ProfileAttrsToUpdate struct {
18821978 // If set, updates the description.
18831979 Description optional.String
18841980
1885- //If set, updates the routing policy.
1981+ // If set, updates the routing policy.
1982+ // Takes precedence over deprecated RoutingPolicy, ClusterID and AllowTransactionalWrites.
1983+ RoutingConfig RoutingPolicyConfig
1984+
1985+ // If set, updates the isolation options.
1986+ Isolation AppProfileIsolation
1987+
1988+ // If set, updates the routing policy.
1989+ // Deprecated: Use RoutingConfig instead.
18861990 RoutingPolicy optional.String
18871991
1888- //If RoutingPolicy is updated to SingleClusterRouting, set these fields as well.
1889- ClusterID string
1992+ // If RoutingPolicy is updated to SingleClusterRouting, set this field as well.
1993+ // Deprecated: Use RoutingConfig with SingleClusterRoutingConfig instead
1994+ ClusterID string
1995+ // If RoutingPolicy is updated to SingleClusterRouting, set this field as well.
1996+ // Deprecated: Use RoutingConfig with SingleClusterRoutingConfig instead
18901997 AllowTransactionalWrites bool
18911998
18921999 // If true, warnings are ignored
@@ -1900,12 +2007,131 @@ func (p *ProfileAttrsToUpdate) GetFieldMaskPath() []string {
19002007 path = append (path , "description" )
19012008 }
19022009
1903- if p .RoutingPolicy != nil {
2010+ if p .RoutingConfig != nil {
2011+ path = append (path , p .RoutingConfig .getFieldMaskPath ())
2012+ } else if p .RoutingPolicy != nil {
19042013 path = append (path , optional .ToString (p .RoutingPolicy ))
19052014 }
2015+ if p .Isolation != nil {
2016+ path = append (path , p .Isolation .getFieldMaskPath ())
2017+ }
2018+
19062019 return path
19072020}
19082021
2022+ // RoutingPolicyConfig represents the configuration for a specific routing policy.
2023+ type RoutingPolicyConfig interface {
2024+ isRoutingPolicyConfig ()
2025+ getFieldMaskPath () string
2026+ }
2027+
2028+ // SingleClusterRoutingConfig is a policy that unconditionally routes all
2029+ // read/write requests to a specific cluster. This option preserves
2030+ // read-your-writes consistency, but does not improve availability.
2031+ type SingleClusterRoutingConfig struct {
2032+ // The cluster to which read/write requests should be routed.
2033+ ClusterID string
2034+ // Whether or not `CheckAndMutateRow` and `ReadModifyWriteRow` requests are
2035+ // allowed by this app profile. It is unsafe to send these requests to
2036+ // the same table/row/column in multiple clusters.
2037+ AllowTransactionalWrites bool
2038+ }
2039+
2040+ func (* SingleClusterRoutingConfig ) isRoutingPolicyConfig () {}
2041+ func (* SingleClusterRoutingConfig ) getFieldMaskPath () string { return "single_cluster_routing" }
2042+
2043+ // MultiClusterRoutingUseAnyConfig is a policy whererin read/write requests are
2044+ // routed to the nearest cluster in the instance, and
2045+ // will fail over to the nearest cluster that is available in the event of
2046+ // transient errors or delays. Clusters in a region are considered
2047+ // equidistant. Choosing this option sacrifices read-your-writes consistency
2048+ // to improve availability.
2049+ type MultiClusterRoutingUseAnyConfig struct {
2050+ // The set of clusters to route to. The order is ignored; clusters will be
2051+ // tried in order of distance. If left empty, all clusters are eligible.
2052+ ClusterIDs []string
2053+
2054+ // Possible algorithms for routing affinity. If enabled, Bigtable will
2055+ // route between equidistant clusters in a deterministic order rather than
2056+ // choosing randomly.
2057+ Affinity MultiClusterRoutingUseAnyAffinity
2058+ }
2059+
2060+ func (* MultiClusterRoutingUseAnyConfig ) isRoutingPolicyConfig () {}
2061+ func (* MultiClusterRoutingUseAnyConfig ) getFieldMaskPath () string {
2062+ return "multi_cluster_routing_use_any"
2063+ }
2064+
2065+ // MultiClusterRoutingUseAnyAffinity represents the configuration for a specific affinity strategy.
2066+ type MultiClusterRoutingUseAnyAffinity interface {
2067+ isMultiClusterRoutingUseAnyAffinity ()
2068+ }
2069+
2070+ // RowAffinity enables row-based affinity.
2071+ // If enabled, Bigtable will route the request based on the row key of the
2072+ // request, rather than randomly. Instead, each row key will be assigned
2073+ // to a cluster, and will stick to that cluster.
2074+ type RowAffinity struct {}
2075+
2076+ func (* RowAffinity ) isMultiClusterRoutingUseAnyAffinity () {}
2077+
2078+ // AppProfileIsolation represents the configuration for a specific traffic isolation policy.
2079+ type AppProfileIsolation interface {
2080+ isAppProfileIsolation ()
2081+ getFieldMaskPath () string
2082+ }
2083+
2084+ // StandardIsolation configures standard traffic isolation.
2085+ type StandardIsolation struct {
2086+ Priority AppProfilePriority
2087+ }
2088+
2089+ func (* StandardIsolation ) isAppProfileIsolation () {}
2090+ func (* StandardIsolation ) getFieldMaskPath () string { return "standard_isolation" }
2091+
2092+ // AppProfilePriority represents possible priorities for an app profile.
2093+ type AppProfilePriority int32
2094+
2095+ const (
2096+ // AppProfilePriorityUnspecified is the default value. Mapped to PRIORITY_HIGH (the legacy behavior) on creation.
2097+ AppProfilePriorityUnspecified AppProfilePriority = AppProfilePriority (btapb .AppProfile_PRIORITY_UNSPECIFIED )
2098+ // AppProfilePriorityLow represents the lowest priority.
2099+ AppProfilePriorityLow AppProfilePriority = AppProfilePriority (btapb .AppProfile_PRIORITY_LOW )
2100+ // AppProfilePriorityMedium represents the medium priority.
2101+ AppProfilePriorityMedium AppProfilePriority = AppProfilePriority (btapb .AppProfile_PRIORITY_MEDIUM )
2102+ // AppProfilePriorityHigh represents the highest priority.
2103+ AppProfilePriorityHigh AppProfilePriority = AppProfilePriority (btapb .AppProfile_PRIORITY_HIGH )
2104+ )
2105+
2106+ // DataBoostIsolationReadOnly configures Data Boost isolation.
2107+ // Data Boost is a serverless compute capability that lets you run
2108+ // high-throughput read jobs and queries on your Bigtable data, without
2109+ // impacting the performance of the clusters that handle your application
2110+ // traffic. Data Boost supports read-only use cases with single-cluster
2111+ // routing.
2112+ type DataBoostIsolationReadOnly struct {
2113+ // Compute Billing Owner specifies how usage should be accounted when using
2114+ // Data Boost. Compute Billing Owner also configures which Cloud Project is
2115+ // charged for relevant quota.
2116+ ComputeBillingOwner IsolationComputeBillingOwner
2117+ }
2118+
2119+ func (* DataBoostIsolationReadOnly ) isAppProfileIsolation () {}
2120+ func (* DataBoostIsolationReadOnly ) getFieldMaskPath () string { return "data_boost_isolation_read_only" }
2121+
2122+ // IsolationComputeBillingOwner specifies how usage should be accounted when using
2123+ // Data Boost. Compute Billing Owner also configures which Cloud Project is
2124+ // charged for relevant quota.
2125+ type IsolationComputeBillingOwner int32
2126+
2127+ const (
2128+ // ComputeBillingOwnerUnspecified is the default value.
2129+ ComputeBillingOwnerUnspecified IsolationComputeBillingOwner = IsolationComputeBillingOwner (btapb .AppProfile_DataBoostIsolationReadOnly_COMPUTE_BILLING_OWNER_UNSPECIFIED )
2130+ // HostPays indicates that the host Cloud Project containing the targeted Bigtable Instance /
2131+ // Table pays for compute.
2132+ HostPays IsolationComputeBillingOwner = IsolationComputeBillingOwner (btapb .AppProfile_DataBoostIsolationReadOnly_HOST_PAYS )
2133+ )
2134+
19092135// PageInfo supports pagination. See https://godoc.org/google.golang.org/api/iterator package for details.
19102136func (it * ProfileIterator ) PageInfo () * iterator.PageInfo {
19112137 return it .pageInfo
@@ -1932,24 +2158,14 @@ func (iac *InstanceAdminClient) CreateAppProfile(ctx context.Context, profile Pr
19322158 Description : profile .Description ,
19332159 }
19342160
1935- if profile .RoutingPolicy == "" {
1936- return nil , errors .New ("invalid routing policy" )
2161+ err := setRoutingPolicy (appProfile , profile .RoutingConfig , optional .String (profile .RoutingPolicy ), profile .ClusterID , profile .AllowTransactionalWrites , false )
2162+ if err != nil {
2163+ return nil , err
19372164 }
19382165
1939- switch profile .RoutingPolicy {
1940- case MultiClusterRouting :
1941- appProfile .RoutingPolicy = & btapb.AppProfile_MultiClusterRoutingUseAny_ {
1942- MultiClusterRoutingUseAny : & btapb.AppProfile_MultiClusterRoutingUseAny {},
1943- }
1944- case SingleClusterRouting :
1945- appProfile .RoutingPolicy = & btapb.AppProfile_SingleClusterRouting_ {
1946- SingleClusterRouting : & btapb.AppProfile_SingleClusterRouting {
1947- ClusterId : profile .ClusterID ,
1948- AllowTransactionalWrites : profile .AllowTransactionalWrites ,
1949- },
1950- }
1951- default :
1952- return nil , errors .New ("invalid routing policy" )
2166+ err = setIsolation (appProfile , profile .Isolation )
2167+ if err != nil {
2168+ return nil , err
19532169 }
19542170
19552171 return iac .iClient .CreateAppProfile (ctx , & btapb.CreateAppProfileRequest {
@@ -2012,32 +2228,28 @@ func (iac *InstanceAdminClient) ListAppProfiles(ctx context.Context, instanceID
20122228// UpdateAppProfile updates an app profile within an instance.
20132229// updateAttrs should be set. If unset, all fields will be replaced.
20142230func (iac * InstanceAdminClient ) UpdateAppProfile (ctx context.Context , instanceID , profileID string , updateAttrs ProfileAttrsToUpdate ) error {
2231+ fmt .Println ("Entering UpdateAppProfile" )
20152232 ctx = mergeOutgoingMetadata (ctx , iac .md )
20162233
20172234 profile := & btapb.AppProfile {
2018- Name : "projects/" + iac .project + "/instances/" + instanceID + "/appProfiles/" + profileID ,
2235+ Name : appProfilePath ( iac .project , instanceID , profileID ) ,
20192236 }
20202237
20212238 if updateAttrs .Description != nil {
20222239 profile .Description = optional .ToString (updateAttrs .Description )
20232240 }
2024- if updateAttrs .RoutingPolicy != nil {
2025- switch optional .ToString (updateAttrs .RoutingPolicy ) {
2026- case MultiClusterRouting :
2027- profile .RoutingPolicy = & btapb.AppProfile_MultiClusterRoutingUseAny_ {
2028- MultiClusterRoutingUseAny : & btapb.AppProfile_MultiClusterRoutingUseAny {},
2029- }
2030- case SingleClusterRouting :
2031- profile .RoutingPolicy = & btapb.AppProfile_SingleClusterRouting_ {
2032- SingleClusterRouting : & btapb.AppProfile_SingleClusterRouting {
2033- ClusterId : updateAttrs .ClusterID ,
2034- AllowTransactionalWrites : updateAttrs .AllowTransactionalWrites ,
2035- },
2036- }
2037- default :
2038- return errors .New ("invalid routing policy" )
2039- }
2241+
2242+ err := setRoutingPolicy (profile , updateAttrs .RoutingConfig , updateAttrs .RoutingPolicy ,
2243+ updateAttrs .ClusterID , updateAttrs .AllowTransactionalWrites , true )
2244+ if err != nil {
2245+ return err
2246+ }
2247+
2248+ err = setIsolation (profile , updateAttrs .Isolation )
2249+ if err != nil {
2250+ return err
20402251 }
2252+
20412253 patchRequest := & btapb.UpdateAppProfileRequest {
20422254 AppProfile : profile ,
20432255 UpdateMask : & field_mask.FieldMask {
0 commit comments