diff --git a/federation/rest.yaml b/federation/rest.yaml index ef66022b4..47644e9ea 100644 --- a/federation/rest.yaml +++ b/federation/rest.yaml @@ -305,19 +305,23 @@ endpoints: required: true title: Node ID get: - - type: string - name: query - required: false - title: Search query - - type: uint - name: limit - title: Limit - - type: string - name: pageCursor - title: Page cursor - - type: string - name: sort - title: Sort items + - type: uint64 + name: lastSync + required: false + title: Last sync timestamp + - type: string + name: query + required: false + title: Search query + - type: uint + name: limit + title: Limit + - type: string + name: pageCursor + title: Page cursor + - type: string + name: sort + title: Sort items - title: Sync data description: Sync data @@ -330,20 +334,29 @@ endpoints: title: List all record changes path: "/exposed/records/" parameters: + path: + - type: uint64 + name: nodeID + required: true + title: Node ID get: - - type: string - name: query - required: false - title: Search query - - type: uint - name: limit - title: Limit - - type: string - name: pageCursor - title: Page cursor - - type: string - name: sort - title: Sort items + - type: uint64 + name: lastSync + required: false + title: Last sync timestamp + - type: string + name: query + required: false + title: Search query + - type: uint + name: limit + title: Limit + - type: string + name: pageCursor + title: Page cursor + - type: string + name: sort + title: Sort items - name: readExposed method: GET title: List all records per module @@ -359,23 +372,23 @@ endpoints: required: true title: Module ID get: - - type: string - name: lastSync - required: false - title: Last sync timestamp - - type: string - name: query - required: false - title: Search query - - type: uint - name: limit - required: false - title: Limit - - type: string - name: pageCursor - required: false - title: Page cursor - - type: string - name: sort - required: false - title: Sort items + - type: uint64 + name: lastSync + required: false + title: Last sync timestamp + - type: string + name: query + required: false + title: Search query + - type: uint + name: limit + required: false + title: Limit + - type: string + name: pageCursor + required: false + title: Page cursor + - type: string + name: sort + required: false + title: Sort items diff --git a/federation/rest/request/syncData.go b/federation/rest/request/syncData.go index 161aeaac1..41e1be756 100644 --- a/federation/rest/request/syncData.go +++ b/federation/rest/request/syncData.go @@ -30,6 +30,16 @@ var ( type ( // Internal API interface SyncDataReadExposedAll struct { + // NodeID PATH parameter + // + // Node ID + NodeID uint64 `json:",string"` + + // LastSync GET parameter + // + // Last sync timestamp + LastSync uint64 `json:",string"` + // Query GET parameter // // Search query @@ -65,7 +75,7 @@ type ( // LastSync GET parameter // // Last sync timestamp - LastSync string + LastSync uint64 `json:",string"` // Query GET parameter // @@ -97,6 +107,8 @@ func NewSyncDataReadExposedAll() *SyncDataReadExposedAll { // Auditable returns all auditable/loggable parameters func (r SyncDataReadExposedAll) Auditable() map[string]interface{} { return map[string]interface{}{ + "nodeID": r.NodeID, + "lastSync": r.LastSync, "query": r.Query, "limit": r.Limit, "pageCursor": r.PageCursor, @@ -104,6 +116,16 @@ func (r SyncDataReadExposedAll) Auditable() map[string]interface{} { } } +// Auditable returns all auditable/loggable parameters +func (r SyncDataReadExposedAll) GetNodeID() uint64 { + return r.NodeID +} + +// Auditable returns all auditable/loggable parameters +func (r SyncDataReadExposedAll) GetLastSync() uint64 { + return r.LastSync +} + // Auditable returns all auditable/loggable parameters func (r SyncDataReadExposedAll) GetQuery() string { return r.Query @@ -141,6 +163,12 @@ func (r *SyncDataReadExposedAll) Fill(req *http.Request) (err error) { // GET params tmp := req.URL.Query() + if val, ok := tmp["lastSync"]; ok && len(val) > 0 { + r.LastSync, err = payload.ParseUint64(val[0]), nil + if err != nil { + return err + } + } if val, ok := tmp["query"]; ok && len(val) > 0 { r.Query, err = val[0], nil if err != nil { @@ -167,6 +195,18 @@ func (r *SyncDataReadExposedAll) Fill(req *http.Request) (err error) { } } + { + var val string + // path params + + val = chi.URLParam(req, "nodeID") + r.NodeID, err = payload.ParseUint64(val), nil + if err != nil { + return err + } + + } + return err } @@ -199,7 +239,7 @@ func (r SyncDataReadExposed) GetModuleID() uint64 { } // Auditable returns all auditable/loggable parameters -func (r SyncDataReadExposed) GetLastSync() string { +func (r SyncDataReadExposed) GetLastSync() uint64 { return r.LastSync } @@ -241,7 +281,7 @@ func (r *SyncDataReadExposed) Fill(req *http.Request) (err error) { tmp := req.URL.Query() if val, ok := tmp["lastSync"]; ok && len(val) > 0 { - r.LastSync, err = val[0], nil + r.LastSync, err = payload.ParseUint64(val[0]), nil if err != nil { return err } diff --git a/federation/rest/request/syncStructure.go b/federation/rest/request/syncStructure.go index 8c3d79d92..1a083d2e7 100644 --- a/federation/rest/request/syncStructure.go +++ b/federation/rest/request/syncStructure.go @@ -35,6 +35,11 @@ type ( // Node ID NodeID uint64 `json:",string"` + // LastSync GET parameter + // + // Last sync timestamp + LastSync uint64 `json:",string"` + // Query GET parameter // // Search query @@ -66,6 +71,7 @@ func NewSyncStructureReadExposedAll() *SyncStructureReadExposedAll { func (r SyncStructureReadExposedAll) Auditable() map[string]interface{} { return map[string]interface{}{ "nodeID": r.NodeID, + "lastSync": r.LastSync, "query": r.Query, "limit": r.Limit, "pageCursor": r.PageCursor, @@ -78,6 +84,11 @@ func (r SyncStructureReadExposedAll) GetNodeID() uint64 { return r.NodeID } +// Auditable returns all auditable/loggable parameters +func (r SyncStructureReadExposedAll) GetLastSync() uint64 { + return r.LastSync +} + // Auditable returns all auditable/loggable parameters func (r SyncStructureReadExposedAll) GetQuery() string { return r.Query @@ -115,6 +126,12 @@ func (r *SyncStructureReadExposedAll) Fill(req *http.Request) (err error) { // GET params tmp := req.URL.Query() + if val, ok := tmp["lastSync"]; ok && len(val) > 0 { + r.LastSync, err = payload.ParseUint64(val[0]), nil + if err != nil { + return err + } + } if val, ok := tmp["query"]; ok && len(val) > 0 { r.Query, err = val[0], nil if err != nil { diff --git a/federation/rest/sync_structure.go b/federation/rest/sync_structure.go index 35c182c7b..73040a523 100644 --- a/federation/rest/sync_structure.go +++ b/federation/rest/sync_structure.go @@ -12,7 +12,7 @@ import ( type ( SyncStructure struct{} - listResponse struct { + listModuleResponse struct { Filter *types.ExposedModuleFilter `json:"filter"` Set *types.ExposedModuleSet `json:"set"` } @@ -33,7 +33,8 @@ func (ctrl SyncStructure) ReadExposedAll(ctx context.Context, r *request.SyncStr } f := types.ExposedModuleFilter{ - NodeID: node.ID, + NodeID: node.ID, + LastSync: r.LastSync, } if f.Paging, err = filter.NewPaging(r.Limit, r.PageCursor); err != nil { @@ -44,9 +45,13 @@ func (ctrl SyncStructure) ReadExposedAll(ctx context.Context, r *request.SyncStr return nil, err } - list, f, err := (service.ExposedModule()).Find(context.Background(), f) + list, f, err := (service.ExposedModule()).Find(ctx, f) - return listResponse{ + if err != nil { + return nil, err + } + + return listModuleResponse{ Set: &list, Filter: &f, }, nil diff --git a/federation/service/shared_module.go b/federation/service/shared_module.go index 008567fbb..fb106e56e 100644 --- a/federation/service/shared_module.go +++ b/federation/service/shared_module.go @@ -12,7 +12,6 @@ import ( type ( sharedModule struct { - ctx context.Context compose composeService.ModuleService store store.Storer actionlog actionlog.Recorder @@ -31,8 +30,7 @@ type ( func SharedModule() SharedModuleService { return &sharedModule{ - ctx: context.Background(), - compose: composeService.Module(), + compose: composeService.DefaultModule, store: DefaultStore, actionlog: DefaultActionlog, } diff --git a/federation/types/exposed_module.go b/federation/types/exposed_module.go index e5a87723d..db66e2862 100644 --- a/federation/types/exposed_module.go +++ b/federation/types/exposed_module.go @@ -23,7 +23,9 @@ type ( NodeID uint64 `json:"nodeID,string"` ComposeModuleID uint64 `json:"composeModuleID,string"` ComposeNamespaceID uint64 `json:"composeNamespaceID,string"` - Query string `json:"query"` + + LastSync uint64 `json:"lastSync"` + Query string `json:"query"` Check func(*ExposedModule) (bool, error) `json:"-"` diff --git a/federation/types/shared_module.go b/federation/types/shared_module.go index 1eaee710e..1be463bcc 100644 --- a/federation/types/shared_module.go +++ b/federation/types/shared_module.go @@ -21,7 +21,7 @@ type ( } SharedModuleFilter struct { - NodeID uint64 `json:"node"` + NodeID uint64 `json:"nodeID,string"` Query string `json:"query"` Handle string `json:"handle"` diff --git a/store/federation_exposed_modules.yaml b/store/federation_exposed_modules.yaml index 7225ff35a..cf453f95e 100644 --- a/store/federation_exposed_modules.yaml +++ b/store/federation_exposed_modules.yaml @@ -5,7 +5,7 @@ types: type: types.ExposedModule fields: - - { field: ID } + - { field: ID, isPrimaryKey: true, sortable: true } - { field: NodeID } - { field: ComposeModuleID } - { field: ComposeNamespaceID } diff --git a/store/rdbms/federation_exposed_modules.go b/store/rdbms/federation_exposed_modules.go index a264109a0..9833ff6d4 100644 --- a/store/rdbms/federation_exposed_modules.go +++ b/store/rdbms/federation_exposed_modules.go @@ -1,6 +1,8 @@ package rdbms import ( + "time" + "github.com/Masterminds/squirrel" "github.com/cortezaproject/corteza-server/federation/types" ) @@ -8,8 +10,6 @@ import ( func (s Store) convertFederationExposedModuleFilter(f types.ExposedModuleFilter) (query squirrel.SelectBuilder, err error) { query = s.federationExposedModulesSelectBuilder() - // query = filter.StateCondition(query, "cmd.deleted_at", f.Deleted) - if f.NodeID > 0 { query = query.Where("cmd.rel_node = ?", f.NodeID) } @@ -22,13 +22,13 @@ func (s Store) convertFederationExposedModuleFilter(f types.ExposedModuleFilter) query = query.Where("cmd.rel_compose_namespace = ?", f.ComposeNamespaceID) } - // if f.Query != "" { - // q := "%" + strings.ToLower(f.Query) + "%" - // query = query.Where(squirrel.Or{ - // squirrel.Like{"LOWER(cmd.name)": q}, - // squirrel.Like{"LOWER(cmd.handle)": q}, - // }) - // } + if f.LastSync > 0 { + t := time.Unix(int64(f.LastSync), 0) + + if !t.IsZero() { + query = query.Where("(cmd.updated_at >= ? OR cmd.created_at >= ?)", t.UTC().Format(time.RFC3339), t.UTC().Format(time.RFC3339)) + } + } return }