3
0

Improve workflow session endpoint capabilities

Workflow sessions can now be
 - sorted by resource or event type,status, creation, competition or suspensio date
 - filtered by creator

List of wf sessions is now served w/o stacktraces, input & output scope for performance.
This commit is contained in:
Denis Arh
2021-04-14 12:59:22 +02:00
parent 701f6a4e66
commit 5ce2ac9767
8 changed files with 82 additions and 13 deletions

View File

@@ -193,6 +193,7 @@ endpoints:
get:
- { name: sessionID, type: "[]string", title: "Filter by session ID" }
- { name: workflowID, type: "[]string", title: "Filter by workflow ID" }
- { name: createdBy, type: "[]string", title: "Filter by creators ID" }
- { name: completed, type: "uint", title: "Exclude (0, default), include (1) or return only (2) completed sessions" }
- { name: status, type: "[]uint", title: "Filter by status: started (0), prompted (1), suspended (2), failed (3) and completed (4)" }
- { name: eventType, type: "string", title: "Filter event type" }

View File

@@ -46,6 +46,11 @@ type (
// Filter by workflow ID
WorkflowID []string
// CreatedBy GET parameter
//
// Filter by creators ID
CreatedBy []string
// Completed GET parameter
//
// Exclude (0, default), include (1) or return only (2) completed sessions
@@ -146,6 +151,7 @@ func (r SessionList) Auditable() map[string]interface{} {
return map[string]interface{}{
"sessionID": r.SessionID,
"workflowID": r.WorkflowID,
"createdBy": r.CreatedBy,
"completed": r.Completed,
"status": r.Status,
"eventType": r.EventType,
@@ -166,6 +172,11 @@ func (r SessionList) GetWorkflowID() []string {
return r.WorkflowID
}
// Auditable returns all auditable/loggable parameters
func (r SessionList) GetCreatedBy() []string {
return r.CreatedBy
}
// Auditable returns all auditable/loggable parameters
func (r SessionList) GetCompleted() uint {
return r.Completed
@@ -230,6 +241,17 @@ func (r *SessionList) Fill(req *http.Request) (err error) {
return err
}
}
if val, ok := tmp["createdBy[]"]; ok {
r.CreatedBy, err = val, nil
if err != nil {
return err
}
} else if val, ok := tmp["createdBy"]; ok {
r.CreatedBy, err = val, nil
if err != nil {
return err
}
}
if val, ok := tmp["completed"]; ok && len(val) > 0 {
r.Completed, err = payload.ParseUint(val[0]), nil
if err != nil {

View File

@@ -28,7 +28,18 @@ type (
sessionSetPayload struct {
Filter types.SessionFilter `json:"filter"`
Set types.SessionSet `json:"set"`
Set []*sessionSetItem `json:"set"`
}
sessionSetItem struct {
*types.Session
// Make sure stacktrace is not included in the list
Stacktrace *struct{} `json:"stacktrace,omitempty"`
// Make sure output values are not included in the list
Output *struct{} `json:"output,omitempty"`
// Make sure input values are not included in the list
Input *struct{} `json:"input,omitempty"`
}
)
@@ -44,6 +55,7 @@ func (ctrl Session) List(ctx context.Context, r *request.SessionList) (interface
f = types.SessionFilter{
WorkflowID: payload.ParseUint64s(r.WorkflowID),
SessionID: payload.ParseUint64s(r.SessionID),
CreatedBy: payload.ParseUint64s(r.CreatedBy),
EventType: r.EventType,
ResourceType: r.ResourceType,
Completed: filter.State(r.Completed),
@@ -91,14 +103,17 @@ func (ctrl Session) DeleteState(ctx context.Context, r *request.SessionDeleteSta
return nil, fmt.Errorf("not implemented")
}
func (ctrl Session) makeFilterPayload(ctx context.Context, uu types.SessionSet, f types.SessionFilter, err error) (*sessionSetPayload, error) {
func (ctrl Session) makeFilterPayload(ctx context.Context, ss types.SessionSet, f types.SessionFilter, err error) (*sessionSetPayload, error) {
if err != nil {
return nil, err
}
if len(uu) == 0 {
uu = make([]*types.Session, 0)
out := &sessionSetPayload{Filter: f, Set: make([]*sessionSetItem, len(ss))}
for i, s := range ss {
s.Stacktrace = nil
out.Set[i] = &sessionSetItem{Session: s}
}
return &sessionSetPayload{Filter: f, Set: uu}, nil
return out, nil
}

View File

@@ -73,7 +73,7 @@ func (svc *session) Search(ctx context.Context, filter types.SessionFilter) (rr
return nil
}()
return rr, filter, svc.recordAction(ctx, sap, SessionActionSearch, err)
return rr, f, svc.recordAction(ctx, sap, SessionActionSearch, err)
}
func (svc *session) LookupByID(ctx context.Context, sessionID uint64) (res *types.Session, err error) {

View File

@@ -53,6 +53,7 @@ type (
SessionFilter struct {
SessionID []uint64 `json:"sessionID"`
WorkflowID []uint64 `json:"workflowID"`
CreatedBy []uint64 `json:"createdBy"`
EventType string `json:"eventType"`
ResourceType string `json:"resourceType"`

View File

@@ -7,17 +7,17 @@ types:
fields:
- { field: ID }
- { field: WorkflowID }
- { field: EventType }
- { field: ResourceType }
- { field: Status, type: int }
- { field: EventType, sortable: true }
- { field: ResourceType, sortable: true }
- { field: Status, type: int, sortable: true }
- { field: Input, type: "expr.Vars" }
- { field: Output, type: "expr.Vars" }
- { field: Stacktrace, type: "types.Stacktrace" }
- { field: CreatedBy }
- { field: CreatedAt }
- { field: CreatedAt, sortable: true }
- { field: PurgeAt }
- { field: CompletedAt }
- { field: SuspendedAt }
- { field: CompletedAt, sortable: true }
- { field: SuspendedAt, sortable: true }
- { field: Error }
rdbms:

View File

@@ -508,7 +508,16 @@ func (Store) automationSessionColumns(aa ...string) []string {
// With optional string arg, all columns are returned aliased
func (Store) sortableAutomationSessionColumns() map[string]string {
return map[string]string{
"id": "id",
"id": "id", "event_type": "event_type",
"eventtype": "event_type",
"resource_type": "resource_type",
"resourcetype": "resource_type",
"status": "status", "created_at": "created_at",
"createdat": "created_at",
"completed_at": "completed_at",
"completedat": "completed_at",
"suspended_at": "suspended_at",
"suspendedat": "suspended_at",
}
}
@@ -561,6 +570,23 @@ func (s Store) collectAutomationSessionCursorValues(res *types.Session, cc ...*f
cursor.Set(c.Column, res.ID, c.Descending)
pkId = true
case "event_type":
cursor.Set(c.Column, res.EventType, c.Descending)
case "resource_type":
cursor.Set(c.Column, res.ResourceType, c.Descending)
case "status":
cursor.Set(c.Column, res.Status, c.Descending)
case "created_at":
cursor.Set(c.Column, res.CreatedAt, c.Descending)
case "completed_at":
cursor.Set(c.Column, res.CompletedAt, c.Descending)
case "suspended_at":
cursor.Set(c.Column, res.SuspendedAt, c.Descending)
}
}

View File

@@ -15,6 +15,10 @@ func (s Store) convertAutomationSessionFilter(f types.SessionFilter) (query squi
query = query.Where(squirrel.Eq{"atms.id": f.SessionID})
}
if len(f.CreatedBy) > 0 {
query = query.Where(squirrel.Eq{"atms.created_by": f.CreatedBy})
}
if len(f.Status) > 0 {
query = query.Where(squirrel.Eq{"atms.status": f.Status})
}