Skip to content

Commit 0c7847c

Browse files
committed
feat: first sequence support
Support "sequences" from dlt-logs-utils in notebook.
1 parent 7001e8e commit 0c7847c

File tree

4 files changed

+526
-7
lines changed

4 files changed

+526
-7
lines changed

package.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,14 @@
143143
},
144144
"dependencies": {
145145
"@vscode/extension-telemetry": "^0.8.4",
146-
"dlt-logs-utils": "^0.2.0",
146+
"dlt-logs-utils": "^0.3.0",
147147
"jju": "github:mbehr1/jju#3aa4169df926e99083fdd511d7c20b5bd9ba789f",
148148
"js-yaml": "^4.1.0",
149149
"json5": "2.2.3",
150150
"jsonpath": "^1.1.1",
151+
"mdast-util-assert": "^5.0.0",
152+
"mdast-util-gfm-table": "^2.0.0",
153+
"mdast-util-to-markdown": "^2.1.2",
151154
"request": "^2.88.2",
152155
"short-unique-id": "4.4.4",
153156
"tslib": "2.6.2"

src/extension/fbaNBRQRenderer.ts

+146-1
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,14 @@ import { DocData, FBAEditorProvider } from './fbaEditor'
1717
import { FBBadge } from './fbaFormat'
1818
import { arrayEquals, getMemberParent, MemberPath } from './util'
1919
import * as uv0 from 'dlt-logs-utils'
20-
import { RQ, rqUriDecode, rqUriEncode } from 'dlt-logs-utils/dist/restQuery'
20+
import { RQ, rqUriDecode, rqUriEncode } from 'dlt-logs-utils/restQuery'
21+
import { DltFilter, DltLifecycleInfoMinIF, FbSequenceResult, SeqChecker, seqResultToMdAst } from 'dlt-logs-utils/sequence'
2122
import { NotebookCellOutput } from 'vscode'
2223

24+
import { toMarkdown } from 'mdast-util-to-markdown'
25+
import { gfmTableToMarkdown } from 'mdast-util-gfm-table'
26+
import { assert as mdassert } from 'mdast-util-assert'
27+
2328
class FBANBRQCell extends vscode.NotebookCellData {
2429
constructor(kind: vscode.NotebookCellKind, value: string, languageId: string, metadata?: object) {
2530
super(kind, value, languageId)
@@ -631,6 +636,8 @@ export class FBANBRestQueryRenderer {
631636
],
632637
}
633638
FBANBRestQueryRenderer.execRestQuery(editorProvider, exec, docData, filterRq, '', '')
639+
} else if (fbUidMembers[fbUidMembers.length - 1].endsWith(':sequences')) {
640+
this.executeSequences(editorProvider, exec, docData, cell)
634641
} else {
635642
exec.end(false)
636643
}
@@ -642,6 +649,144 @@ export class FBANBRestQueryRenderer {
642649
}
643650
}
644651

652+
static getLCInfoFromRQLc(rqLc: any): DltLifecycleInfoMinIF {
653+
return {
654+
ecu: rqLc.ecu,
655+
persistentId: rqLc.id,
656+
lifecycleStart: new Date(rqLc.startTimeUtc),
657+
lifecycleEnd: new Date(rqLc.endTimeUtc),
658+
isResume: rqLc.isResume,
659+
lifecycleResume: rqLc.resumeTimeUtc ? new Date(rqLc.resumeTimeUtc) : undefined,
660+
nrMsgs: rqLc.nrMsgs,
661+
tooltip: rqLc.tooltip || '',
662+
swVersions: rqLc.sws,
663+
getTreeNodeLabel: () => rqLc.label,
664+
}
665+
}
666+
667+
static async executeSequences(
668+
editorProvider: FBAEditorProvider,
669+
exec: vscode.NotebookCellExecution,
670+
docData: DocData,
671+
cell: vscode.NotebookCell,
672+
): Promise<void> {
673+
const sequences = JSON5.parse(cell.document.getText())
674+
if (Array.isArray(sequences) && sequences.length > 0) {
675+
// code similar to fba-cli.processSequences (todo refactor to dlt-log-utils/sequences?)
676+
for (const jsonSeq of sequences) {
677+
const seqResult: FbSequenceResult = {
678+
sequence: jsonSeq,
679+
occurrences: [],
680+
logs: [],
681+
}
682+
const seqChecker = new SeqChecker(jsonSeq, seqResult, DltFilter)
683+
// determine all filters to query from steps and failures:
684+
const allFilters = seqChecker.getAllFilters()
685+
if (allFilters.length === 0) {
686+
console.warn(`processSequences: no filters found for sequence '${seqChecker.name}'`)
687+
seqResult.logs.push(`no filters found for sequence '${seqChecker.name}'`)
688+
continue
689+
} else {
690+
// we do want lifecycle infos as well
691+
allFilters[0].addLifecycles = true
692+
}
693+
const allFiltersRq: RQ = {
694+
path: 'ext:mbehr1.dlt-logs/get/docs/0/filters?', // todo get from cell data!
695+
commands: [
696+
{
697+
cmd: 'query',
698+
param: JSON.stringify(allFilters),
699+
},
700+
],
701+
}
702+
await editorProvider.performRestQuery(docData, rqUriEncode(allFiltersRq)).then(
703+
async (resJson: any) => {
704+
if ('error' in resJson) {
705+
exec.appendOutput(
706+
new NotebookCellOutput([vscode.NotebookCellOutputItem.stderr(`query got error:${JSON.stringify(resJson.error)}`)]),
707+
)
708+
} else {
709+
if ('data' in resJson && Array.isArray(resJson.data)) {
710+
const lifecycles = new Map(
711+
(<any[]>resJson.data)
712+
.filter((d: any) => d.type === 'lifecycles')
713+
.map((d: any) => [d.id as number, this.getLCInfoFromRQLc(d.attributes)]),
714+
)
715+
const msgs = <any[]>resJson.data
716+
.filter((d: any) => d.type === 'msg')
717+
.map((d: any) => {
718+
const lifecycle = lifecycles.get(d.attributes.lifecycle)
719+
return {
720+
index: d.id,
721+
...d.attributes,
722+
lifecycle,
723+
receptionTimeInMs: lifecycle ? lifecycle.lifecycleStart.valueOf() + d.attributes.timeStamp / 10000 : 0,
724+
}
725+
})
726+
const slicedMsgs = msgs.slice(0, 50)
727+
appendMarkdown(exec, [
728+
{
729+
open: false,
730+
summary: `received ${lifecycles.size} lifecycles and ${msgs.length} messages${
731+
msgs.length > slicedMsgs.length ? `. Unfold to see first ${slicedMsgs.length}` : resJson.data.length > 0 ? ':' : ''
732+
}`,
733+
texts: msgs.map((msg) => codeBlock(JSON.stringify(slicedMsgs, undefined, 2), 'json')).flat(),
734+
},
735+
])
736+
seqChecker.processMsgs(msgs)
737+
/*appendMarkdown(exec, [
738+
{
739+
open: false,
740+
summary: `seqResult`,
741+
texts: codeBlock(JSON.stringify(seqResult, undefined, 2), 'json'),
742+
},
743+
])*/
744+
try {
745+
const resAsMd = seqResultToMdAst(seqResult)
746+
/*appendMarkdown(exec, [
747+
{
748+
open: false,
749+
summary: `resAsMd`,
750+
texts: codeBlock(JSON.stringify(resAsMd, undefined, 2), 'json'),
751+
},
752+
])*/
753+
for (const res of resAsMd) {
754+
mdassert(res)
755+
}
756+
const resAsMarkdown = toMarkdown(
757+
{ type: 'root', children: resAsMd },
758+
{ extensions: [gfmTableToMarkdown({ tablePipeAlign: false })] },
759+
)
760+
appendMarkdown(exec, [resAsMarkdown])
761+
} catch (e) {
762+
exec.appendOutput(new NotebookCellOutput([vscode.NotebookCellOutputItem.stderr(`converting result to md got err:${e}`)]))
763+
}
764+
appendMarkdown(exec, [
765+
{
766+
open: false, // todo only in case of error
767+
summary: `Sequence '${seqChecker.name}': logs:${seqResult.logs.length}`,
768+
texts: seqResult.logs.map((log: string) => codeBlock(log, 'json')).flat(),
769+
},
770+
])
771+
}
772+
}
773+
},
774+
(errTxt) => {
775+
console.log(`FBANBRestQueryRenderer.execRestQuery got error:`, errTxt)
776+
exec.appendOutput(new NotebookCellOutput([vscode.NotebookCellOutputItem.stderr(`query got error:${JSON.stringify(errTxt)}`)]))
777+
exec.end(true)
778+
},
779+
)
780+
}
781+
exec.end(true)
782+
} else {
783+
exec.appendOutput(
784+
new NotebookCellOutput([vscode.NotebookCellOutputItem.stderr(`no sequences provided! Needs to be a non empty json array!`)]),
785+
)
786+
exec.end(false)
787+
}
788+
}
789+
645790
static execRestQuery(
646791
editorProvider: FBAEditorProvider,
647792
exec: vscode.NotebookCellExecution,

tsconfig.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
"./node_modules/@types",
55
"./types"
66
],
7-
"module": "commonjs",
7+
"module": "es2022",
8+
"moduleResolution": "bundler",
89
"target": "es2021",
910
"outDir": "out",
1011
"lib": [

0 commit comments

Comments
 (0)