Skip to content

Commit

Permalink
SNRGY-3572 implemented list interfaces; missing criteria filter imple…
Browse files Browse the repository at this point in the history
…mentation; failing TestUserDelete
  • Loading branch information
IngoRoessner committed Oct 21, 2024
1 parent b7f4eaf commit 27b84dd
Show file tree
Hide file tree
Showing 12 changed files with 178 additions and 133 deletions.
1 change: 0 additions & 1 deletion config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"server_port": "8080",
"jwt_pub_rsa": "",
"users_topic": "user",
"permissions_topic": "permissions",
"permission_v2_url": "http://permv2.permissions:8080",
"device_repo_url": "http://device-repo:8080",
"mongo_url": "mongodb://localhost:27017",
Expand Down
59 changes: 42 additions & 17 deletions lib/api/import_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"log"
"net/http"
"strconv"
"strings"

"github.com/SENERGY-Platform/import-repository/lib/config"
"github.com/SENERGY-Platform/import-repository/lib/model"
Expand All @@ -41,36 +42,60 @@ func ImportTypesEndpoints(config config.Config, control Controller, router *http
http.Error(writer, err.Error(), http.StatusBadRequest)
return
}
limit := request.URL.Query().Get("limit")
if limit == "" {
limit = "100"

listOptions := model.ImportTypeListOptions{
Limit: 100,
Offset: 0,
}
limitParam := request.URL.Query().Get("limit")
if limitParam != "" {
listOptions.Limit, err = strconv.ParseInt(limitParam, 10, 64)
}
limitInt, err := strconv.ParseInt(limit, 10, 64)
if err != nil {
http.Error(writer, err.Error(), http.StatusBadRequest)
http.Error(writer, "unable to parse limit:"+err.Error(), http.StatusBadRequest)
return
}
offset := request.URL.Query().Get("offset")
if offset == "" {
offset = "0"

offsetParam := request.URL.Query().Get("offset")
if offsetParam != "" {
listOptions.Offset, err = strconv.ParseInt(offsetParam, 10, 64)
}
offsetInt, err := strconv.ParseInt(offset, 10, 64)
if err != nil {
http.Error(writer, err.Error(), http.StatusBadRequest)
http.Error(writer, "unable to parse offset:"+err.Error(), http.StatusBadRequest)
return
}
sort := request.URL.Query().Get("sort")
if sort == "" {
sort = "name"

idsParam := request.URL.Query().Get("ids")
if request.URL.Query().Has("ids") {
if idsParam != "" {
listOptions.Ids = strings.Split(strings.TrimSpace(idsParam), ",")
} else {
listOptions.Ids = []string{}
}
}
//TODO:
// fill model.ImportTypeListOptions with
// use ListImportTypesV2(token jwt.Token, options model.ImportTypeListOptions) (result []model.ImportType, err error, errCode int)
result, err, errCode := control.ListImportTypes(token, limitInt, offsetInt, sort)

criteria := request.URL.Query().Get("criteria")
if criteria != "" {
listOptions.Criteria = []model.ImportTypeFilterCriteria{}
err = json.Unmarshal([]byte(criteria), &listOptions.Criteria)
if err != nil {
http.Error(writer, err.Error(), http.StatusBadRequest)
return
}
}

listOptions.Search = request.URL.Query().Get("search")
listOptions.SortBy = request.URL.Query().Get("sort")
if listOptions.SortBy == "" {
listOptions.SortBy = "name.asc"
}

result, total, err, errCode := control.ListImportTypes(token, listOptions)
if err != nil {
http.Error(writer, err.Error(), errCode)
return
}
writer.Header().Set("X-Total-Count", strconv.FormatInt(total, 10))
writer.Header().Set("Content-Type", "application/json; charset=utf-8")
err = json.NewEncoder(writer).Encode(result)
if err != nil {
Expand Down
3 changes: 1 addition & 2 deletions lib/api/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ import (

type Controller interface {
ReadImportType(id string, token jwt.Token) (result model.ImportType, err error, errCode int)
ListImportTypes(token jwt.Token, limit int64, offset int64, sort string) (result []model.ImportType, err error, errCode int)
ListImportTypesV2(token jwt.Token, options model.ImportTypeListOptions) (result []model.ImportType, err error, errCode int)
ListImportTypes(token jwt.Token, options model.ImportTypeListOptions) (result []model.ImportType, total int64, err error, errCode int)
CreateImportType(importType model.ImportType, token jwt.Token) (result model.ImportType, err error, code int)
SetImportType(importType model.ImportType, token jwt.Token) (err error, code int)
DeleteImportType(id string, token jwt.Token) (err error, errCode int)
Expand Down
23 changes: 23 additions & 0 deletions lib/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/SENERGY-Platform/import-repository/lib/model"
"io"
"net/http"
"strconv"
)

type Interface = api.Controller
Expand Down Expand Up @@ -53,5 +54,27 @@ func do[T any](req *http.Request) (result T, err error, code int) {
return
}

func doWithTotalInResult[T any](req *http.Request) (result T, total int64, err error, code int) {
resp, err := http.DefaultClient.Do(req)
if err != nil {
return result, total, err, http.StatusInternalServerError
}
defer resp.Body.Close()
if resp.StatusCode > 299 {
temp, _ := io.ReadAll(resp.Body) //read error response end ensure that resp.Body is read to EOF
return result, total, fmt.Errorf("unexpected statuscode %v: %v", resp.StatusCode, string(temp)), resp.StatusCode
}
total, err = strconv.ParseInt(resp.Header.Get("X-Total-Count"), 10, 64)
if err != nil {
return result, total, fmt.Errorf("unable to read X-Total-Count header %w", err), http.StatusInternalServerError
}
err = json.NewDecoder(resp.Body).Decode(&result)
if err != nil {
_, _ = io.ReadAll(resp.Body) //ensure resp.Body is read to EOF
return result, total, err, http.StatusInternalServerError
}
return
}

type ImportTypeListOptions = model.ImportTypeListOptions
type ImportTypeFilterCriteria = model.ImportTypeFilterCriteria
52 changes: 38 additions & 14 deletions lib/client/import-types.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ import (
"encoding/json"
"github.com/SENERGY-Platform/service-commons/pkg/jwt"
"net/http"
"net/url"
"strconv"
"strings"

"github.com/SENERGY-Platform/import-repository/lib/model"
)
Expand All @@ -31,22 +33,44 @@ func (c Client) ReadImportType(id string, token jwt.Token) (result model.ImportT
if err != nil {
return result, err, http.StatusInternalServerError
}
req.Header.Set("Authorization", "Bearer "+token.Jwt())
req.Header.Set("Authorization", token.Jwt())
return do[model.ImportType](req)
}

func (c Client) ListImportTypes(token jwt.Token, limit int64, offset int64, sort string) (result []model.ImportType, err error, errCode int) {
req, err := http.NewRequest(http.MethodGet, c.baseUrl+"/import-types?limit="+strconv.FormatInt(limit, 10)+"&offset="+strconv.FormatInt(offset, 10)+"&sort="+sort, nil)
func (c Client) ListImportTypes(token jwt.Token, options model.ImportTypeListOptions) (result []model.ImportType, total int64, err error, errCode int) {
queryString := ""
query := url.Values{}
if options.Search != "" {
query.Set("search", options.Search)
}
if options.Ids != nil {
query.Set("ids", strings.Join(options.Ids, ","))
}
if options.SortBy != "" {
query.Set("sort", options.SortBy)
}
if options.Limit != 0 {
query.Set("limit", strconv.FormatInt(options.Limit, 10))
}
if options.Offset != 0 {
query.Set("offset", strconv.FormatInt(options.Offset, 10))
}
if len(options.Criteria) > 0 {
filterStr, err := json.Marshal(options.Criteria)
if err != nil {
return result, total, err, http.StatusBadRequest
}
query.Add("criteria", string(filterStr))
}
if len(query) > 0 {
queryString = "?" + query.Encode()
}
req, err := http.NewRequest(http.MethodGet, c.baseUrl+"/import-types"+queryString, nil)
if err != nil {
return result, err, http.StatusInternalServerError
return result, total, err, http.StatusInternalServerError
}
req.Header.Set("Authorization", "Bearer "+token.Jwt())
return do[[]model.ImportType](req)
}

func (c Client) ListImportTypesV2(token jwt.Token, options model.ImportTypeListOptions) (result []model.ImportType, err error, errCode int) {
//TODO implement me
panic("implement me")
req.Header.Set("Authorization", token.Jwt())
return doWithTotalInResult[[]model.ImportType](req)
}

func (c Client) CreateImportType(importType model.ImportType, token jwt.Token) (result model.ImportType, err error, code int) {
Expand All @@ -58,7 +82,7 @@ func (c Client) CreateImportType(importType model.ImportType, token jwt.Token) (
if err != nil {
return result, err, http.StatusInternalServerError
}
req.Header.Set("Authorization", "Bearer "+token.Jwt())
req.Header.Set("Authorization", token.Jwt())
return do[model.ImportType](req)
}

Expand All @@ -71,7 +95,7 @@ func (c Client) SetImportType(importType model.ImportType, token jwt.Token) (err
if err != nil {
return err, http.StatusInternalServerError
}
req.Header.Set("Authorization", "Bearer "+token.Jwt())
req.Header.Set("Authorization", token.Jwt())
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err, http.StatusInternalServerError
Expand All @@ -84,7 +108,7 @@ func (c Client) DeleteImportType(id string, token jwt.Token) (err error, errCode
if err != nil {
return err, http.StatusInternalServerError
}
req.Header.Set("Authorization", "Bearer "+token.Jwt())
req.Header.Set("Authorization", token.Jwt())
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err, http.StatusInternalServerError
Expand Down
3 changes: 0 additions & 3 deletions lib/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ type Config struct {
ServerPort string `json:"server_port"`
KafkaBootstrap string `json:"kafka_bootstrap"`
GroupId string `json:"group_id"`
ImportTypeTopic string `json:"import_type_topic"`
PermissionsUrl string `json:"permissions_url"`
DeviceRepoUrl string `json:"device_repo_url"`
MongoUrl string `json:"mongo_url"`
MongoReplSet bool `json:"mongo_repl_set"` //set true if mongodb is configured as replication set or mongos and is able to handle transactions
Expand All @@ -43,7 +41,6 @@ type Config struct {
Validate bool `json:"validate"`
UsersTopic string `json:"users_topic"`
RepublishStartup bool `json:"republish_startup"`
PermissionsTopic string `json:"permissions_topic"`
PermissionV2Url string `json:"permissions_v2_url"`
}

Expand Down
38 changes: 26 additions & 12 deletions lib/controller/import_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,22 +74,36 @@ func (this *Controller) ReadImportType(id string, token jwt.Token) (result model
return result, nil, http.StatusOK
}

func (this *Controller) ListImportTypes(token jwt.Token, limit int64, offset int64, sort string) (result []model.ImportType, err error, errCode int) {
ids, err, errCode := this.permV2Client.ListAccessibleResourceIds(token.Token, PermV2Topic, permV2Model.ListOptions{}, permV2Model.Read)
if err != nil {
return
func (this *Controller) ListImportTypes(token jwt.Token, options model.ImportTypeListOptions) (result []model.ImportType, total int64, err error, errCode int) {
ids := []string{}
if options.Ids == nil {
if token.IsAdmin() {
ids = nil //no auth check for admins -> no id filter
} else {
ids, err, _ = this.permV2Client.ListAccessibleResourceIds(token.Token, PermV2Topic, permV2Model.ListOptions{}, permV2Model.Read)
if err != nil {
return result, total, err, http.StatusInternalServerError
}
}
} else {
options.Limit = 0
options.Offset = 0
idMap, err, _ := this.permV2Client.CheckMultiplePermissions(token.Token, PermV2Topic, options.Ids, permV2Model.Read)
if err != nil {
return result, total, err, http.StatusInternalServerError
}
for id, ok := range idMap {
if ok {
ids = append(ids, id)
}
}
}
ctx, _ := getTimeoutContext()
result, err = this.db.ListImportTypes(ctx, limit, offset, sort, ids)
result, total, err = this.db.ListImportTypes(ctx, options)
if err != nil {
return result, err, http.StatusInternalServerError
return result, total, err, http.StatusInternalServerError
}
return result, nil, http.StatusOK
}

func (this *Controller) ListImportTypesV2(token jwt.Token, options model.ImportTypeListOptions) (result []model.ImportType, err error, errCode int) {
//TODO: implement
panic("implement me")
return result, total, nil, http.StatusOK
}

func (this *Controller) SetImportType(importType model.ImportType, token jwt.Token) (err error, errCode int) {
Expand Down
2 changes: 1 addition & 1 deletion lib/database/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (

type Database interface {
GetImportType(ctx context.Context, id string) (device model.ImportType, exists bool, err error)
ListImportTypes(ctx context.Context, limit int64, offset int64, sort string, limitToIds []string) (result []model.ImportType, err error)
ListImportTypes(ctx context.Context, options model.ImportTypeListOptions) (result []model.ImportType, total int64, err error)
SetImportType(ctx context.Context, importType model.ImportType) error
RemoveImportType(ctx context.Context, id string) error
}
Loading

0 comments on commit 27b84dd

Please sign in to comment.