Skip to content

Commit

Permalink
Merge pull request #63 from roopesh83/main
Browse files Browse the repository at this point in the history
ExportRoute CRD  operations added
  • Loading branch information
loafoe authored Aug 5, 2021
2 parents ab90516 + b439f4d commit 49bb987
Show file tree
Hide file tree
Showing 3 changed files with 369 additions and 0 deletions.
3 changes: 3 additions & 0 deletions cdl/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ type Client struct {
Study *StudyService
DataTypeDefinition *DatatypeDefinitionService
LabelDefinition *LabelDefinitionService
ExportRoute *ExportRouteService
}

// NewClient returns a new HSDP CDL API client. A configured IAM client
Expand All @@ -81,6 +82,8 @@ func newClient(iamClient *iam.Client, config *Config) (*Client, error) {
c.DataTypeDefinition = &DatatypeDefinitionService{client: c, validate: validator.New(), config: config}
c.LabelDefinition = &LabelDefinitionService{client: c, validate: validator.New(), config: config}
_ = c.LabelDefinition.validate.RegisterValidation("labelDefValidationHandler", labelDefValidationHandler)

c.ExportRoute = &ExportRouteService{client: c, validate: validator.New(), config: config}
return c, nil
}

Expand Down
190 changes: 190 additions & 0 deletions cdl/export_route_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
package cdl

import (
"fmt"
"github.com/go-playground/validator/v10"
"io"
"net/http"
"path"
)

type ExportRoute struct {
ID string `json:"id,omitempty"`
ExportRouteName string `json:"name" validate:"required"`
Description string `json:"description,omitempty"`
DisplayName string `json:"displayName" validate:"required"`
Source Source `json:"source" validate:"required"`
AutoExport bool `json:"autoExport,omitempty"`
Destination Destination `json:"destination" validate:"required"`
ServiceAccount ExportServiceAccount `json:"serviceAccount" validate:"required"`
CreatedBy string `json:"createdBy,omitempty"`
CreatedOn string `json:"createdOn,omitempty"`
UpdatedBy string `json:"updatedBy,omitempty"`
UpdatedOn string `json:"updatedOn,omitempty"`
}

type Source struct {
CDLResearchStudy ExportResearchStudySource `json:"cdlResearchStudy" validate:"required"`
}

type Destination struct {
CDLResearchStudy ExportResearchStudyDestination `json:"cdlResearchStudy" validate:"required"`
}

type ExportResearchStudySource struct {
Endpoint string `json:"endpoint" validate:"required"`
Allowed *ExportAllowedField `json:"allowed,omitempty"`
}

type ExportResearchStudyDestination struct {
Endpoint string `json:"endpoint" validate:"required"`
}

type ExportAllowedField struct {
DataObject []ExportDataObject `json:"dataObject,omitempty"`
}

type ExportDataObject struct {
Type string `json:"type"`
ExportLabel []ExportLabel `json:"label,omitempty"`
}

type ExportLabel struct {
Name string `json:"name,omitempty"`
ApprovalRequired bool `json:"approvalRequired,omitempty"`
}

type ExportServiceAccount struct {
CDLServiceAccount ExportServiceAccountDetails `json:"cdlServiceAccount" validate:"required"`
}

type ExportServiceAccountDetails struct {
ServiceID string `json:"serviceId" validate:"required"`
PrivateKey string `json:"privateKey" validate:"required"`
AccessTokenEndPoint string `json:"accessTokenEndPoint" validate:"required"`
TokenEndPoint string `json:"tokenEndPoint" validate:"required"`
}

type ExportRouteService struct {
client *Client
config *Config
validate *validator.Validate
}

func (exp *ExportRouteService) path(components ...string) string {
return path.Join(components...)
}

type ExportRouteBundleEntry struct {
FullURL string `json:"fullUrl,omitempty"`
Resource ExportRoute `json:"resource,omitempty"`
}

type LinkElementType struct {
Relation string `json:"relation"`
URL string `json:"url"`
}

type ExportRouteBundleResponse struct {
ResourceType string `json:"resourceType,omitempty"`
ID string `json:"id,omitempty"`
Type string `json:"type,omitempty"`
Link []LinkElementType `json:"link,omitempty"`
Entry []ExportRouteBundleEntry `json:"entry" validate:"required"`
}

func (exp *ExportRouteService) CreateExportRoute(exportRoute ExportRoute) (*ExportRoute, *Response, error) {
if err := exp.validate.Struct(exportRoute); err != nil {
return nil, nil, err
}

req, err := exp.client.newCDLRequest("POST", exp.path("ExportRoute"), exportRoute, nil)
if err != nil {
return nil, nil, err
}
req.Header.Set("Api-Version", "1")

var createdExportRoute ExportRoute
resp, err := exp.client.do(req, &createdExportRoute)
if (err != nil && err != io.EOF) || resp == nil {
if resp == nil && err != nil {
err = fmt.Errorf("CreateExportRoute: %w", ErrEmptyResult)
}
return nil, resp, err
}

return &createdExportRoute, resp, nil
}

func (exp *ExportRouteService) GetExportRoutes(page int, options ...OptionFunc) ([]ExportRoute, *ExportRouteBundleResponse, *Response, error) {
req, err := exp.client.newCDLRequest("GET", exp.path("ExportRoute"), &struct {
Page int `url:"page"`
}{page}, options...)
if err != nil {
return nil, nil, nil, err
}
req.Header.Set("Api-Version", "1")

var getAllExportRouteResponse ExportRouteBundleResponse
resp, err := exp.client.do(req, &getAllExportRouteResponse)
if err != nil {
if resp != nil && resp.StatusCode == http.StatusNotFound {
return nil, nil, resp, ErrEmptyResult
}
return nil, nil, resp, err
}
var exportRouteSlice []ExportRoute
for _, entry := range getAllExportRouteResponse.Entry {
exportRouteSlice = append(exportRouteSlice, entry.Resource)
}
return exportRouteSlice, &getAllExportRouteResponse, resp, err
}

func (exp *ExportRouteService) GetExportRouteByID(exportRouteId string) (*ExportRoute, *Response, error) {
page := 1
exportRoutes, getAllExportBundleResponse, resp, err := exp.GetExportRoutes(page)

if err != nil {
return nil, resp, err
}

for {
for _, expRoute := range exportRoutes {
if expRoute.ID == exportRouteId {
return &expRoute, resp, err
}
}

lastPage := true
for _, link := range getAllExportBundleResponse.Link {
if link.Relation == "next" {
page += 1
exportRoutes, getAllExportBundleResponse, resp, err = exp.GetExportRoutes(page)
if err != nil {
return nil, resp, err
}
lastPage = false
}
}
if lastPage {
return nil, resp, err
}
}
}

func (exp *ExportRouteService) DeleteExportRouteByID(exportRouteId string) (*Response, error) {
req, err := exp.client.newCDLRequest("DELETE", exp.path("ExportRoute", exportRouteId), nil, nil)
if err != nil {
return nil, err
}
req.Header.Set("Api-Version", "1")

resp, err := exp.client.do(req, nil)
if (err != nil && err != io.EOF) || resp == nil {
if resp == nil && err != nil {
err = fmt.Errorf("DeleteExportRouteByID: %w", ErrEmptyResult)
}
return resp, err
}
return resp, nil
}
176 changes: 176 additions & 0 deletions cdl/export_route_service_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
package cdl_test

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

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

exportRouteID := "1ee7eb94-3eab-4c1c-9a1c-7c5347ab538d"

exportRoute := cdl.ExportRoute{
ExportRouteName: "ExportTrial_for_demo27",
Description: "description11",
DisplayName: "DisplayName",
Source: cdl.Source{
CDLResearchStudy: cdl.ExportResearchStudySource{
Endpoint: "https://cicd-datalake.cloud.pcftest.com/store/cdl/1f5be763-f896-4883-80fa-5593cd69556d/Study/a1467792-ef81-11eb-8ac2-477a9e3b09aa",
},
},
Destination: cdl.Destination{
CDLResearchStudy: cdl.ExportResearchStudyDestination{
Endpoint: "https://cicd-datalake.cloud.pcftest.com/store/cdl/1f5be763-f896-4883-80fa-5593cd69556d/Study/5c8431e2-f4f1-11eb-bf8f-b799651c8a11",
},
},
ServiceAccount: cdl.ExportServiceAccount{
CDLServiceAccount: cdl.ExportServiceAccountDetails{
ServiceID: "eng_cdl_tenant_1_ser.eng__cdl__tenant__1__app.eng__cdl__tenant__1@eng__cdl__tenant__1.cdal.philips-healthsuite.com",
PrivateKey: "-----BEGIN RSA PRIVATE KEY-----SERVICE_KEY-----END RSA PRIVATE KEY-----",
AccessTokenEndPoint: "https://iam-development.us-east.philips-healthsuite.com/oauth2/access_token",
TokenEndPoint: "https://iam-development.us-east.philips-healthsuite.com/authorize/oauth2/token",
},
},
}

muxCDL.HandleFunc("/store/cdl/"+cdlTenantID+"/ExportRoute", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
switch r.Method {
case "POST":
w.WriteHeader(http.StatusCreated)
_, _ = io.WriteString(w, `{
"id": "1ee7eb94-3eab-4c1c-9a1c-7c5347ab538d",
"resourceType": "ExportRoute",
"name": "ExportTrial_for_demo74",
"description": "description11",
"displayName": "display name11",
"source": {
"cdlResearchStudy": {
"endpoint": "https://cicd-datalake.cloud.pcftest.com/store/cdl/1f5be763-f896-4883-80fa-5593cd69556d/Study/a1467792-ef81-11eb-8ac2-477a9e3b09aa"
}
},
"destination": {
"cdlResearchStudy": {
"endpoint": "https://cicd-datalake.cloud.pcftest.com/store/cdl/1f5be763-f896-4883-80fa-5593cd69556d/Study/5c8431e2-f4f1-11eb-bf8f-b799651c8a11"
}
},
"autoExport": false,
"createdBy": "user@philips.com",
"createdOn": "2021-08-04T10:19:53.168+00:00",
"updatedBy": "user@philips.com",
"updatedOn": "2021-08-04T10:19:53.168+00:00"
}
]
}`)
case "GET":
w.WriteHeader(http.StatusOK)
_, _ = io.WriteString(w, `{
"resourceType": "Bundle",
"id": "b6d0c8e6-6df4-42ae-a239-898e92c5814d",
"type": "searchset",
"link": [
{
"relation": "self",
"url": "https://cicd-datalake.cloud.pcftest.com/store/cdl/1f5be763-f896-4883-80fa-5593cd69556d/Study/a1467792-ef81-11eb-8ac2-477a9e3b09aa/LabelDef"
}
],
"entry": [
{
"fullUrl": "https://cicd-datalake.cloud.pcftest.com/store/cdl/1f5be763-f896-4883-80fa-5593cd69556d/ExportRoute/1ee7eb94-3eab-4c1c-9a1c-7c5347ab538d",
"resource": {
"id": "1ee7eb94-3eab-4c1c-9a1c-7c5347ab538d",
"resourceType": "ExportRoute",
"name": "ExportTrial_for_demo74",
"description": "description11",
"displayName": "display name11",
"source": {
"cdlResearchStudy": {
"endpoint": "https://cicd-datalake.cloud.pcftest.com/store/cdl/1f5be763-f896-4883-80fa-5593cd69556d/Study/a1467792-ef81-11eb-8ac2-477a9e3b09aa"
}
},
"destination": {
"cdlResearchStudy": {
"endpoint": "https://cicd-datalake.cloud.pcftest.com/store/cdl/1f5be763-f896-4883-80fa-5593cd69556d/Study/5c8431e2-f4f1-11eb-bf8f-b799651c8a11"
}
},
"autoExport": false,
"createdBy": "user@philips.com",
"createdOn": "2021-08-04T10:19:53.168+00:00",
"updatedBy": "user@philips.com",
"updatedOn": "2021-08-04T10:19:53.168+00:00"
}
}
]
}`)
default:
w.WriteHeader(http.StatusMethodNotAllowed)
}
})

muxCDL.HandleFunc("/store/cdl/"+cdlTenantID+"/ExportRoute/"+exportRouteID, func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
switch r.Method {
case "DELETE":
w.WriteHeader(http.StatusNoContent)
default:
w.WriteHeader(http.StatusMethodNotAllowed)
}
})

createdExportRoute, resp, err := cdlClient.ExportRoute.CreateExportRoute(exportRoute)

if !assert.Nil(t, err) {
return
}
if !assert.NotNil(t, resp) {
return
}
if !assert.NotNil(t, createdExportRoute) {
return
}
assert.Equal(t, http.StatusCreated, resp.StatusCode)
assert.Equal(t, createdExportRoute.ID, exportRouteID)

item, resp, err := cdlClient.ExportRoute.GetExportRouteByID(exportRouteID)
if !assert.Nil(t, err) {
return
}
if !assert.NotNil(t, resp) {
return
}
if !assert.NotNil(t, item) {
return
}
assert.Equal(t, http.StatusOK, resp.StatusCode)
assert.Equal(t, exportRouteID, item.ID)

items, bundleResponse, resp, err := cdlClient.ExportRoute.GetExportRoutes(1, nil)
if !assert.Nil(t, err) {
return
}
if !assert.NotNil(t, resp) {
return
}
if !assert.NotNil(t, bundleResponse) {
return
}
if !assert.NotNil(t, item) {
return
}
assert.Equal(t, exportRouteID, items[0].ID)
assert.Equal(t, http.StatusOK, resp.StatusCode)

resp, err = cdlClient.ExportRoute.DeleteExportRouteByID(exportRouteID)
if !assert.Nil(t, err) {
return
}
if !assert.NotNil(t, resp) {
return
}
assert.Equal(t, http.StatusNoContent, resp.StatusCode)
}

0 comments on commit 49bb987

Please sign in to comment.