Skip to content

Commit

Permalink
Merge pull request #153 from philips-software/feature/blr-configuration
Browse files Browse the repository at this point in the history
BLR: Implement BlobStorePolicy APIs
  • Loading branch information
loafoe authored Sep 4, 2023
2 parents 6531d12 + 0e53ff7 commit ed4a6cb
Show file tree
Hide file tree
Showing 5 changed files with 223 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ The current implement covers only a subset of HSDP APIs. Basically, we implement
- [x] Access Policy
- [x] Access URL
- [x] Multipart Upload
- [x] BlobStore Policy management
- [ ] Topic management
- [ ] Store Access
- [ ] Bucket management
Expand Down
4 changes: 3 additions & 1 deletion blr/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ type Client struct {

validate *validator.Validate

Blobs *BlobsService
Blobs *BlobsService
Configurations *ConfigurationsService
}

// NewClient returns a new BLR client
Expand All @@ -67,6 +68,7 @@ func NewClient(iamClient *iam.Client, config *Config) (*Client, error) {
}

c.Blobs = &BlobsService{Client: c, validate: validator.New()}
c.Configurations = &ConfigurationsService{Client: c, validate: validator.New()}

return c, nil
}
Expand Down
122 changes: 122 additions & 0 deletions blr/configurations_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package blr

import (
"encoding/json"
"fmt"
"github.com/go-playground/validator/v10"
"github.com/philips-software/go-hsdp-api/internal"
"net/http"
)

var (
blobConfigurationAPIVersion = "1"
)

type BlobStorePolicy struct {
ResourceType string `json:"resourceType"`
ID string `json:"id,omitempty"`
Statement []BlobStorePolicyStatement `json:"statement"`
}

type BlobStorePolicyStatement struct {
Effect string `json:"effect"`
Action []string `json:"action"`
Principal []string `json:"principal"`
Resource []string `json:"resource"`
}

type GetBlobStorePolicyOptions struct {
ID *string `url:"_id,omitempty"`
}

type ConfigurationsService struct {
*Client
validate *validator.Validate
}

func (b *ConfigurationsService) CreateBlobStorePolicy(policy BlobStorePolicy) (*BlobStorePolicy, *Response, error) {
policy.ResourceType = "BlobStorePolicy"
if err := b.validate.Struct(policy); err != nil {
return nil, nil, err
}

req, _ := b.NewRequest(http.MethodPost, "/configuration/BlobStorePolicy", policy, nil)
req.Header.Set("api-version", blobConfigurationAPIVersion)
req.Header.Set("Content-Type", "application/json")

var created BlobStorePolicy

resp, err := b.Do(req, &created)

if err != nil {
return nil, resp, err
}
if created.ID == "" {
return nil, resp, fmt.Errorf("the 'ID' field is missing")
}
return &created, resp, nil
}

func (b *ConfigurationsService) GetBlobStorePolicyByID(id string) (*Blob, *Response, error) {
req, err := b.NewRequest(http.MethodGet, "/configuration/BlobStorePolicy/"+id, nil)
if err != nil {
return nil, nil, err
}
req.Header.Set("api-version", blobAPIVersion)
req.Header.Set("Content-Type", "application/json")

var resource Blob

resp, err := b.Do(req, &resource)
if err != nil {
return nil, resp, err
}
err = internal.CheckResponse(resp.Response)
if err != nil {
return nil, resp, fmt.Errorf("GetByID: %w", err)
}
if resource.ID != id {
return nil, nil, fmt.Errorf("returned resource does not match")
}
return &resource, resp, nil
}

func (b *ConfigurationsService) FindBlobStorePolicy(opt *GetBlobStorePolicyOptions, options ...OptionFunc) (*[]Blob, *Response, error) {
req, err := b.NewRequest(http.MethodGet, "/configuration/BlobStorePolicy", opt, options...)
if err != nil {
return nil, nil, err
}
req.Header.Set("api-version", blobConfigurationAPIVersion)
req.Header.Set("Content-Type", "application/json")

var bundleResponse internal.Bundle

resp, err := b.Do(req, &bundleResponse)
if err != nil {
return nil, resp, err
}
var resources []Blob
for _, c := range bundleResponse.Entry {
var resource Blob
if err := json.Unmarshal(c.Resource, &resource); err == nil {
resources = append(resources, resource)
}
}
return &resources, resp, err
}

func (b *ConfigurationsService) DeleteBlobStorePolicy(policy BlobStorePolicy) (bool, *Response, error) {
req, err := b.NewRequest(http.MethodDelete, "/configuration/BlobStorePolicy/"+policy.ID, nil, nil)
if err != nil {
return false, nil, err
}
req.Header.Set("api-version", blobConfigurationAPIVersion)

var deleteResponse interface{}

resp, err := b.Do(req, &deleteResponse)
if resp == nil || resp.StatusCode() != http.StatusNoContent {
return false, resp, err
}
return true, resp, nil
}
96 changes: 96 additions & 0 deletions blr/configurations_service_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package blr_test

import (
"fmt"
"github.com/philips-software/go-hsdp-api/blr"
"github.com/stretchr/testify/assert"
"io"
"net/http"
"testing"
)

func blobStorePolicyBody(id, effect, action, principal, resource string) string {
return fmt.Sprintf(`{
"resourceType": "BlobStorePolicy",
"meta": {
"lastUpdated": "2022-05-25T19:36:10Z",
"versionId": "1"
},
"id": "%s",
"statement": [
{
"effect": "%s",
"action": [
"%s"
],
"principal": [
"%s"
],
"resource": [
"%s"
]
}
]
}`, id, effect, action, principal, resource)
}

func TestBlobStorePolicyCRUD(t *testing.T) {
teardown := setup(t)
defer teardown()

blobStorePolicyID := "dbf1d779-ab9f-4c27-b4aa-ea75f9efbbc1"
muxBLR.HandleFunc("/connect/blobrepository/configuration/BlobStorePolicy", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
switch r.Method {
case "POST":
w.Header().Set("Etag", "1")
w.WriteHeader(http.StatusCreated)
_, _ = io.WriteString(w, blobStorePolicyBody(blobStorePolicyID, "effect", "action", "principal", "resource"))
}
})
muxBLR.HandleFunc("/connect/blobrepository/configuration/BlobStorePolicy/"+blobStorePolicyID, func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
switch r.Method {
case "GET":
w.WriteHeader(http.StatusOK)
_, _ = io.WriteString(w, blobStorePolicyBody(blobStorePolicyID, "effect", "action", "principal", "resource"))
case "PUT":
w.WriteHeader(http.StatusOK)
_, _ = io.WriteString(w, blobStorePolicyBody(blobStorePolicyID, "effect", "action", "principal", "resource"))
case "DELETE":
w.WriteHeader(http.StatusNoContent)
}
})

created, resp, err := blrClient.Configurations.CreateBlobStorePolicy(blr.BlobStorePolicy{
Statement: []blr.BlobStorePolicyStatement{
{
Effect: "effect",
Action: []string{"action"},
Principal: []string{"principal"},
Resource: []string{"resource"},
},
},
})
if !assert.Nil(t, err) {
return
}
if !assert.NotNil(t, resp) {
return
}
if !assert.NotNil(t, created) {
return
}
assert.Equal(t, []string{"action"}, created.Statement[0].Action)
assert.Equal(t, blobStorePolicyID, created.ID)

res, resp, err := blrClient.Configurations.DeleteBlobStorePolicy(*created)
if !assert.Nil(t, err) {
return
}
if !assert.NotNil(t, resp) {
return
}
assert.True(t, res)
assert.Equal(t, http.StatusNoContent, resp.StatusCode())
}
2 changes: 1 addition & 1 deletion internal/version.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package internal

const (
LibraryVersion = "0.81.3"
LibraryVersion = "0.82.0"
)

0 comments on commit ed4a6cb

Please sign in to comment.