Skip to content

Commit

Permalink
Cosmos DB - Using azcore.ETag instead of strings (#15649)
Browse files Browse the repository at this point in the history
* using azcore.etag

* test

* missing item etag
  • Loading branch information
ealsur authored Sep 28, 2021
1 parent a51b084 commit b5f0d55
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 17 deletions.
4 changes: 3 additions & 1 deletion sdk/data/azcosmos/cosmos_container_properties.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@

package azcosmos

import "github.com/Azure/azure-sdk-for-go/sdk/azcore"

// CosmosContainerProperties represents the properties of a container.
type CosmosContainerProperties struct {
// Id contains the unique id of the container.
Id string `json:"id"`
// ETag contains the entity etag of the container.
ETag string `json:"_etag,omitempty"`
ETag azcore.ETag `json:"_etag,omitempty"`
// SelfLink contains the self-link of the container.
SelfLink string `json:"_self,omitempty"`
// ResourceId contains the resource id of the container.
Expand Down
4 changes: 3 additions & 1 deletion sdk/data/azcosmos/cosmos_database_properties.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@

package azcosmos

import "github.com/Azure/azure-sdk-for-go/sdk/azcore"

// CosmosDatabaseProperties represents the properties of a database.
type CosmosDatabaseProperties struct {
// Id contains the unique id of the database.
Id string `json:"id"`
// ETag contains the entity etag of the database
ETag string `json:"_etag,omitempty"`
ETag azcore.ETag `json:"_etag,omitempty"`
// SelfLink contains the self-link of the database
SelfLink string `json:"_self,omitempty"`
// ResourceId contains the resource id of the database
Expand Down
16 changes: 9 additions & 7 deletions sdk/data/azcosmos/cosmos_database_request_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,25 @@

package azcosmos

import "github.com/Azure/azure-sdk-for-go/sdk/azcore"

// CosmosDatabaseRequestOptions includes options for operations against a database.
type CosmosDatabaseRequestOptions struct {
IfMatchEtag string
IfNoneMatchEtag string
IfMatchEtag *azcore.ETag
IfNoneMatchEtag *azcore.ETag
}

func (options *CosmosDatabaseRequestOptions) toHeaders() *map[string]string {
if options.IfMatchEtag == "" && options.IfNoneMatchEtag == "" {
if options.IfMatchEtag == nil && options.IfNoneMatchEtag == nil {
return nil
}

headers := make(map[string]string)
if options.IfMatchEtag != "" {
headers[headerIfMatch] = options.IfMatchEtag
if options.IfMatchEtag != nil {
headers[headerIfMatch] = string(*options.IfMatchEtag)
}
if options.IfNoneMatchEtag != "" {
headers[headerIfNoneMatch] = options.IfNoneMatchEtag
if options.IfNoneMatchEtag != nil {
headers[headerIfNoneMatch] = string(*options.IfNoneMatchEtag)
}
return &headers
}
12 changes: 8 additions & 4 deletions sdk/data/azcosmos/cosmos_database_request_options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ package azcosmos

import (
"testing"

"github.com/Azure/azure-sdk-for-go/sdk/azcore"
)

func TestDatabaseRequestOptionsToHeaders(t *testing.T) {
Expand All @@ -13,18 +15,20 @@ func TestDatabaseRequestOptionsToHeaders(t *testing.T) {
t.Error("toHeaders should return nil")
}

options.IfMatchEtag = "etag"
options.IfNoneMatchEtag = "noneetag"
etagValue := azcore.ETag("etag")
noneEtagValue := azcore.ETag("noneetag")
options.IfMatchEtag = &etagValue
options.IfNoneMatchEtag = &noneEtagValue
header := options.toHeaders()
if header == nil {
t.Error("toHeaders should return non-nil")
}

headers := *header
if headers[headerIfMatch] != options.IfMatchEtag {
if headers[headerIfMatch] != string(*options.IfMatchEtag) {
t.Errorf("IfMatchEtag not set matching expected %v got %v", options.IfMatchEtag, headers[headerIfMatch])
}
if headers[headerIfNoneMatch] != options.IfNoneMatchEtag {
if headers[headerIfNoneMatch] != string(*options.IfNoneMatchEtag) {
t.Errorf("IfNoneMatchEtag not set matching expected %v got %v", options.IfNoneMatchEtag, headers[headerIfNoneMatch])
}
}
13 changes: 12 additions & 1 deletion sdk/data/azcosmos/cosmos_item_request_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@

package azcosmos

import "strings"
import (
"strings"

"github.com/Azure/azure-sdk-for-go/sdk/azcore"
)

// CosmosItemRequestOptions includes options for operations on items.
type CosmosItemRequestOptions struct {
Expand All @@ -27,6 +31,9 @@ type CosmosItemRequestOptions struct {
// When EnableContentResponseOnWrite is false will cause the response on write operations to have a null resource. This reduces networking and CPU load by not sending the resource back over the network and serializing it on the client.
// The default is false.
EnableContentResponseOnWrite bool
// IfMatchEtag is used to ensure optimistic concurrency control.
// https://docs.microsoft.com/azure/cosmos-db/sql/database-transactions-optimistic-concurrency#optimistic-concurrency-control
IfMatchEtag *azcore.ETag
}

func (options *CosmosItemRequestOptions) toHeaders() *map[string]string {
Expand All @@ -52,5 +59,9 @@ func (options *CosmosItemRequestOptions) toHeaders() *map[string]string {
headers[cosmosHeaderSessionToken] = options.SessionToken
}

if options.IfMatchEtag != nil {
headers[headerIfMatch] = string(*options.IfMatchEtag)
}

return &headers
}
7 changes: 7 additions & 0 deletions sdk/data/azcosmos/cosmos_item_request_options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ package azcosmos

import (
"testing"

"github.com/Azure/azure-sdk-for-go/sdk/azcore"
)

func TestItemRequestOptionsToHeaders(t *testing.T) {
Expand All @@ -14,6 +16,8 @@ func TestItemRequestOptionsToHeaders(t *testing.T) {
options.ConsistencyLevel = ConsistencyLevelSession.ToPtr()
options.SessionToken = "sessionToken"
options.IndexingDirective = IndexingDirectiveInclude.ToPtr()
etagValue := azcore.ETag("someEtag")
options.IfMatchEtag = &etagValue
header := options.toHeaders()
if header == nil {
t.Error("toHeaders should return non-nil")
Expand All @@ -35,4 +39,7 @@ func TestItemRequestOptionsToHeaders(t *testing.T) {
if headers[cosmosHeaderSessionToken] != "sessionToken" {
t.Errorf("SessionToken should be sessionToken but got %v", headers[cosmosHeaderSessionToken])
}
if headers[headerIfMatch] != string(*options.IfMatchEtag) {
t.Errorf("IfMatchEtag should be someEtag but got %v", headers[headerIfMatch])
}
}
6 changes: 4 additions & 2 deletions sdk/data/azcosmos/cosmos_response.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ package azcosmos
import (
"net/http"
"strconv"

"github.com/Azure/azure-sdk-for-go/sdk/azcore"
)

// CosmosResponse is the base response type for all responses from the Azure Cosmos DB database service.
Expand Down Expand Up @@ -34,6 +36,6 @@ func (c *CosmosResponse) ActivityId() string {
}

// ETag contains the value from the ETag header.
func (c *CosmosResponse) ETag() string {
return c.RawResponse.Header.Get(cosmosHeaderEtag)
func (c *CosmosResponse) ETag() azcore.ETag {
return azcore.ETag(c.RawResponse.Header.Get(cosmosHeaderEtag))
}
3 changes: 2 additions & 1 deletion sdk/data/azcosmos/throughput_properties.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"fmt"
"strconv"

"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
)

Expand All @@ -18,7 +19,7 @@ const (

// ThroughputProperties describes the throughput configuration of a resource.
type ThroughputProperties struct {
ETag string
ETag azcore.ETag
LastModified *UnixTime

version string
Expand Down

0 comments on commit b5f0d55

Please sign in to comment.