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:
@@ -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" }
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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"`
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user