@grepr/cli 1.1.4 → 1.3.0-94fe60c
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/dist/commands/base-command.d.ts +3 -3
- package/build/dist/commands/base-command.d.ts.map +1 -1
- package/build/dist/commands/base-command.js +1 -7
- package/build/dist/commands/base-command.js.map +1 -1
- package/build/dist/commands/config-command.d.ts +5 -9
- package/build/dist/commands/config-command.d.ts.map +1 -1
- package/build/dist/commands/config-command.js +32 -4
- package/build/dist/commands/config-command.js.map +1 -1
- package/build/dist/commands/crud-command.d.ts +11 -18
- package/build/dist/commands/crud-command.d.ts.map +1 -1
- package/build/dist/commands/crud-command.js +27 -11
- package/build/dist/commands/crud-command.js.map +1 -1
- package/build/dist/commands/dataset-command.d.ts +8 -13
- package/build/dist/commands/dataset-command.d.ts.map +1 -1
- package/build/dist/commands/dataset-command.js.map +1 -1
- package/build/dist/commands/docs-command.d.ts +87 -0
- package/build/dist/commands/docs-command.d.ts.map +1 -0
- package/build/dist/commands/docs-command.js +164 -0
- package/build/dist/commands/docs-command.js.map +1 -0
- package/build/dist/commands/docs-get-command.d.ts +53 -0
- package/build/dist/commands/docs-get-command.d.ts.map +1 -0
- package/build/dist/commands/docs-get-command.js +75 -0
- package/build/dist/commands/docs-get-command.js.map +1 -0
- package/build/dist/commands/grok-command.d.ts +71 -0
- package/build/dist/commands/grok-command.d.ts.map +1 -0
- package/build/dist/commands/grok-command.js +258 -0
- package/build/dist/commands/grok-command.js.map +1 -0
- package/build/dist/commands/integration-command.d.ts +5 -7
- package/build/dist/commands/integration-command.d.ts.map +1 -1
- package/build/dist/commands/integration-command.js +4 -4
- package/build/dist/commands/integration-command.js.map +1 -1
- package/build/dist/commands/job-command.d.ts +7 -43
- package/build/dist/commands/job-command.d.ts.map +1 -1
- package/build/dist/commands/job-command.js +5 -3
- package/build/dist/commands/job-command.js.map +1 -1
- package/build/dist/commands/job-to-test-command.d.ts +74 -0
- package/build/dist/commands/job-to-test-command.d.ts.map +1 -0
- package/build/dist/commands/job-to-test-command.js +159 -0
- package/build/dist/commands/job-to-test-command.js.map +1 -0
- package/build/dist/commands/list-command.d.ts +5 -7
- package/build/dist/commands/list-command.d.ts.map +1 -1
- package/build/dist/commands/list-command.js +20 -4
- package/build/dist/commands/list-command.js.map +1 -1
- package/build/dist/commands/query-command.d.ts +3 -8
- package/build/dist/commands/query-command.d.ts.map +1 -1
- package/build/dist/commands/query-command.js +34 -14
- package/build/dist/commands/query-command.js.map +1 -1
- package/build/dist/docs-index/catalog.json +1 -0
- package/build/dist/docs-index/index.json +1 -0
- package/build/dist/grepr.js +43 -7
- package/build/dist/grepr.js.map +1 -1
- package/build/dist/lib/api-client-factory.d.ts +2 -2
- package/build/dist/lib/api-client-factory.d.ts.map +1 -1
- package/build/dist/lib/api-client-factory.js +1 -1
- package/build/dist/lib/api-client-factory.js.map +1 -1
- package/build/dist/lib/auth.d.ts +17 -9
- package/build/dist/lib/auth.d.ts.map +1 -1
- package/build/dist/lib/auth.js +53 -14
- package/build/dist/lib/auth.js.map +1 -1
- package/build/dist/lib/command-registry.d.ts +3 -2
- package/build/dist/lib/command-registry.d.ts.map +1 -1
- package/build/dist/lib/command-registry.js.map +1 -1
- package/build/dist/lib/config.d.ts +15 -0
- package/build/dist/lib/config.d.ts.map +1 -1
- package/build/dist/lib/config.js +45 -11
- package/build/dist/lib/config.js.map +1 -1
- package/build/dist/lib/docs-search.d.ts +154 -0
- package/build/dist/lib/docs-search.d.ts.map +1 -0
- package/build/dist/lib/docs-search.js +208 -0
- package/build/dist/lib/docs-search.js.map +1 -0
- package/build/dist/lib/grepr-api-client.d.ts +33 -193
- package/build/dist/lib/grepr-api-client.d.ts.map +1 -1
- package/build/dist/lib/grepr-api-client.js +58 -38
- package/build/dist/lib/grepr-api-client.js.map +1 -1
- package/build/dist/lib/job-graph-transformer.d.ts +89 -0
- package/build/dist/lib/job-graph-transformer.d.ts.map +1 -0
- package/build/dist/lib/job-graph-transformer.js +497 -0
- package/build/dist/lib/job-graph-transformer.js.map +1 -0
- package/build/dist/lib/job-graph-utils.d.ts +50 -0
- package/build/dist/lib/job-graph-utils.d.ts.map +1 -0
- package/build/dist/lib/job-graph-utils.js +84 -0
- package/build/dist/lib/job-graph-utils.js.map +1 -0
- package/build/dist/lib/json-formatter.d.ts +1 -0
- package/build/dist/lib/json-formatter.d.ts.map +1 -1
- package/build/dist/lib/json-formatter.js +28 -16
- package/build/dist/lib/json-formatter.js.map +1 -1
- package/build/dist/lib/parser.d.ts.map +1 -1
- package/build/dist/lib/parser.js +3 -6
- package/build/dist/lib/parser.js.map +1 -1
- package/build/dist/lib/streaming-job-executor.d.ts +3 -3
- package/build/dist/lib/streaming-job-executor.d.ts.map +1 -1
- package/build/dist/lib/streaming-job-executor.js +54 -21
- package/build/dist/lib/streaming-job-executor.js.map +1 -1
- package/build/dist/lib/time-utils.js +1 -1
- package/build/dist/lib/time-utils.js.map +1 -1
- package/build/dist/lib/transformers-embeddings.d.ts +76 -0
- package/build/dist/lib/transformers-embeddings.d.ts.map +1 -0
- package/build/dist/lib/transformers-embeddings.js +109 -0
- package/build/dist/lib/transformers-embeddings.js.map +1 -0
- package/build/dist/openapi/openApiTypes.d.ts +3967 -2240
- package/build/dist/openapi/openApiTypes.d.ts.map +1 -1
- package/build/dist/openapi/openApiTypes.js +341 -85
- package/build/dist/openapi/openApiTypes.js.map +1 -1
- package/build/dist/types.d.ts +48 -78
- package/build/dist/types.d.ts.map +1 -1
- package/build/dist/types.js +73 -0
- package/build/dist/types.js.map +1 -1
- package/package.json +41 -11
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Job graph transformation utilities for converting production jobs to test configurations.
|
|
3
|
+
*
|
|
4
|
+
* This module provides functions to transform a production job definition into a test job
|
|
5
|
+
* by replacing sources, sinks, and adding test-specific tagging. The transformations are
|
|
6
|
+
* purely functional - they do not make any API calls or create resources.
|
|
7
|
+
*
|
|
8
|
+
* Key transformations:
|
|
9
|
+
* - Source replacement: Replace vendor sources with dataset queries or keep originals with limits
|
|
10
|
+
* - Sink replacement: Replace vendor sinks with synchronous test sinks or test dataset sinks
|
|
11
|
+
* - Test tagging: Add test run ID and sink name tags to track test data
|
|
12
|
+
*
|
|
13
|
+
* The transformed job can then be executed using the standard job:create command.
|
|
14
|
+
*/
|
|
15
|
+
import { JobExecution, JobProcessing } from '../types.js';
|
|
16
|
+
import { SchemaCreateJob } from '../openapi/openApiTypes.js';
|
|
17
|
+
/**
|
|
18
|
+
* Options for transforming a job to a test configuration.
|
|
19
|
+
*/
|
|
20
|
+
export interface JobToTestOptions {
|
|
21
|
+
/** Target execution type (default: keep original) */
|
|
22
|
+
execution?: JobExecution;
|
|
23
|
+
/** Target processing type (default: keep original) */
|
|
24
|
+
processing?: JobProcessing;
|
|
25
|
+
/** Path to sample data file (not yet implemented) */
|
|
26
|
+
sampleDataFile?: string;
|
|
27
|
+
/** Dataset ID to use as data source (requires start and end) */
|
|
28
|
+
datasetId?: string;
|
|
29
|
+
/** Query to filter dataset source data (optional, requires datasetId) */
|
|
30
|
+
query?: string;
|
|
31
|
+
/** Start time for dataset query (ISO 8601 format) */
|
|
32
|
+
start?: string;
|
|
33
|
+
/** End time for dataset query (ISO 8601 format) */
|
|
34
|
+
end?: string;
|
|
35
|
+
/** Record limit for batch sources (default: 1000) */
|
|
36
|
+
limitRecords?: number;
|
|
37
|
+
/** Dataset ID for async test output (enables tagging) */
|
|
38
|
+
testDataset?: string;
|
|
39
|
+
/** Custom test run identifier (default: auto-generated) */
|
|
40
|
+
testTag?: string;
|
|
41
|
+
/** Custom test job name (default: {original}_test) */
|
|
42
|
+
testName?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Transforms a production job configuration into a test job configuration.
|
|
46
|
+
*
|
|
47
|
+
* This is the main entry point for job transformation. It applies the following changes:
|
|
48
|
+
* 1. Renames the job (appends "_test" or uses custom name)
|
|
49
|
+
* 2. Updates execution and processing types if specified
|
|
50
|
+
* 3. Adds test run ID tag to job tags
|
|
51
|
+
* 4. Transforms sources (replace with dataset query, sample data, or add limits)
|
|
52
|
+
* 5. Transforms sinks (replace with sync sink or test dataset sinks)
|
|
53
|
+
* 6. Adds test tagging operations before sinks
|
|
54
|
+
*
|
|
55
|
+
* The transformation is purely functional and does not make any API calls.
|
|
56
|
+
*
|
|
57
|
+
* @param originalJob - The production job to transform
|
|
58
|
+
* @param options - Transformation options
|
|
59
|
+
* @returns A new job configuration suitable for testing
|
|
60
|
+
* @throws Error if job graph is missing or invalid
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* const testJob = transformJobToTest(prodJob, {
|
|
64
|
+
* execution: 'SYNCHRONOUS',
|
|
65
|
+
* processing: 'BATCH',
|
|
66
|
+
* datasetId: 'my_dataset',
|
|
67
|
+
* start: '2025-01-01T00:00:00Z',
|
|
68
|
+
* end: '2025-01-01T01:00:00Z',
|
|
69
|
+
* limitRecords: 100
|
|
70
|
+
* });
|
|
71
|
+
*/
|
|
72
|
+
export declare function transformJobToTest(originalJob: SchemaCreateJob, options: JobToTestOptions): SchemaCreateJob;
|
|
73
|
+
/**
|
|
74
|
+
* Displays a summary of the transformations applied to a job.
|
|
75
|
+
*
|
|
76
|
+
* This shows a before/after comparison including:
|
|
77
|
+
* - Job name changes
|
|
78
|
+
* - Execution type changes
|
|
79
|
+
* - Processing type changes
|
|
80
|
+
* - operation and edge changes
|
|
81
|
+
* - Test run ID
|
|
82
|
+
*
|
|
83
|
+
* The output is formatted for console display.
|
|
84
|
+
*
|
|
85
|
+
* @param originalJob - The original production job
|
|
86
|
+
* @param transformedJob - The transformed test job
|
|
87
|
+
*/
|
|
88
|
+
export declare function showDiff(originalJob: SchemaCreateJob, transformedJob: SchemaCreateJob): void;
|
|
89
|
+
//# sourceMappingURL=job-graph-transformer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-graph-transformer.d.ts","sourceRoot":"","sources":["../../../src/main/typescript/lib/job-graph-transformer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAiC,YAAY,EAAE,aAAa,EAAyB,MAAM,aAAa,CAAC;AAChH,OAAO,EAGL,eAAe,EAWhB,MAAM,wBAAwB,CAAC;AAQhC;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,qDAAqD;IACrD,SAAS,CAAC,EAAE,YAAY,CAAC;IAEzB,sDAAsD;IACtD,UAAU,CAAC,EAAE,aAAa,CAAC;IAE3B,qDAAqD;IACrD,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,mDAAmD;IACnD,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,eAAe,EAC5B,OAAO,EAAE,gBAAgB,GACxB,eAAe,CAwDjB;AA+YD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,QAAQ,CACtB,WAAW,EAAE,eAAe,EAC5B,cAAc,EAAE,eAAe,GAC9B,IAAI,CA4EN"}
|
|
@@ -0,0 +1,497 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Job graph transformation utilities for converting production jobs to test configurations.
|
|
3
|
+
*
|
|
4
|
+
* This module provides functions to transform a production job definition into a test job
|
|
5
|
+
* by replacing sources, sinks, and adding test-specific tagging. The transformations are
|
|
6
|
+
* purely functional - they do not make any API calls or create resources.
|
|
7
|
+
*
|
|
8
|
+
* Key transformations:
|
|
9
|
+
* - Source replacement: Replace vendor sources with dataset queries or keep originals with limits
|
|
10
|
+
* - Sink replacement: Replace vendor sinks with synchronous test sinks or test dataset sinks
|
|
11
|
+
* - Test tagging: Add test run ID and sink name tags to track test data
|
|
12
|
+
*
|
|
13
|
+
* The transformed job can then be executed using the standard job:create command.
|
|
14
|
+
*/
|
|
15
|
+
import { DEFAULT_INPUT, DEFAULT_OUTPUT, JobExecution, JobProcessing, Vertex, DEFAULT_LIMIT } from '../types.js';
|
|
16
|
+
import { LogsIcebergTableSourceType, LogsSynchronousSinkType, LogsIcebergTableSinkType, LogTransformActionType, DatadogQueryPredicateType, TagActionModification, TagActionType, LogsValuesSourceType } from '../openapi/openApiTypes.js';
|
|
17
|
+
import { canLimit, parseEdge, generateUUID } from './job-graph-utils.js';
|
|
18
|
+
import * as fs from 'fs-extra';
|
|
19
|
+
/**
|
|
20
|
+
* Transforms a production job configuration into a test job configuration.
|
|
21
|
+
*
|
|
22
|
+
* This is the main entry point for job transformation. It applies the following changes:
|
|
23
|
+
* 1. Renames the job (appends "_test" or uses custom name)
|
|
24
|
+
* 2. Updates execution and processing types if specified
|
|
25
|
+
* 3. Adds test run ID tag to job tags
|
|
26
|
+
* 4. Transforms sources (replace with dataset query, sample data, or add limits)
|
|
27
|
+
* 5. Transforms sinks (replace with sync sink or test dataset sinks)
|
|
28
|
+
* 6. Adds test tagging operations before sinks
|
|
29
|
+
*
|
|
30
|
+
* The transformation is purely functional and does not make any API calls.
|
|
31
|
+
*
|
|
32
|
+
* @param originalJob - The production job to transform
|
|
33
|
+
* @param options - Transformation options
|
|
34
|
+
* @returns A new job configuration suitable for testing
|
|
35
|
+
* @throws Error if job graph is missing or invalid
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* const testJob = transformJobToTest(prodJob, {
|
|
39
|
+
* execution: 'SYNCHRONOUS',
|
|
40
|
+
* processing: 'BATCH',
|
|
41
|
+
* datasetId: 'my_dataset',
|
|
42
|
+
* start: '2025-01-01T00:00:00Z',
|
|
43
|
+
* end: '2025-01-01T01:00:00Z',
|
|
44
|
+
* limitRecords: 100
|
|
45
|
+
* });
|
|
46
|
+
*/
|
|
47
|
+
export function transformJobToTest(originalJob, options) {
|
|
48
|
+
const job = { ...originalJob };
|
|
49
|
+
// Determine target execution and processing types (use options or keep original)
|
|
50
|
+
const targetExecution = options.execution || job.execution;
|
|
51
|
+
const targetProcessing = options.processing || job.processing;
|
|
52
|
+
// Create base transformed job with updated metadata
|
|
53
|
+
const transformedJob = {
|
|
54
|
+
...job,
|
|
55
|
+
name: options.testName || `${job.name}_test`,
|
|
56
|
+
execution: targetExecution,
|
|
57
|
+
processing: targetProcessing,
|
|
58
|
+
tags: {
|
|
59
|
+
...(job.tags || {}),
|
|
60
|
+
'grepr.test_run_id': options.testTag || generateUUID()
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
if (!transformedJob.jobGraph) {
|
|
64
|
+
throw new Error('Job graph is required');
|
|
65
|
+
}
|
|
66
|
+
const parsedGraph = parseGraph(transformedJob.jobGraph);
|
|
67
|
+
// Step 1: Add test tagging operations on all edges BEFORE transforming sources/sinks
|
|
68
|
+
// This captures the original source/sink names in the edge tags
|
|
69
|
+
addTestTagging(parsedGraph, transformedJob.tags?.['grepr.test_run_id'] || generateUUID());
|
|
70
|
+
// Step 2: Transform sources (replace with dataset, sample data, or add limits)
|
|
71
|
+
transformSources(parsedGraph, targetProcessing, options);
|
|
72
|
+
// Step 3: Transform sinks (replace with sync sink or test dataset sinks)
|
|
73
|
+
transformSinks(parsedGraph, targetExecution, options);
|
|
74
|
+
// Convert the parsed/modified graph back to SchemaGreprJobGraph format
|
|
75
|
+
const transformedVertices = [];
|
|
76
|
+
const transformedEdges = [];
|
|
77
|
+
for (const vertex of parsedGraph.values()) {
|
|
78
|
+
transformedVertices.push(vertex.operation);
|
|
79
|
+
for (const [outputPort, nextIos] of vertex.next) {
|
|
80
|
+
for (const nextIo of nextIos) {
|
|
81
|
+
const edgeStr = `${vertex.name}:${outputPort} -> ${nextIo.vertex.name}:${nextIo.name}`;
|
|
82
|
+
transformedEdges.push(edgeStr);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
transformedJob.jobGraph = {
|
|
87
|
+
vertices: transformedVertices,
|
|
88
|
+
edges: transformedEdges
|
|
89
|
+
};
|
|
90
|
+
return transformedJob;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Parses the job graph into a vertex-based representation, returning all vertices.
|
|
94
|
+
*/
|
|
95
|
+
function parseGraph(jobGraph) {
|
|
96
|
+
const verticesMap = new Map();
|
|
97
|
+
// Create Vertex objects for each operation
|
|
98
|
+
for (const operation of jobGraph.vertices) {
|
|
99
|
+
verticesMap.set(operation.name, new Vertex(operation));
|
|
100
|
+
}
|
|
101
|
+
// Link vertices based on edges
|
|
102
|
+
for (const edge of jobGraph.edges) {
|
|
103
|
+
const { sourceVertex: sourceVertexName, targetVertex: targetVertexName, sourcePort, targetPort } = parseEdge(edge);
|
|
104
|
+
const sourceVertex = verticesMap.get(sourceVertexName);
|
|
105
|
+
const targetVertex = verticesMap.get(targetVertexName);
|
|
106
|
+
if (sourceVertex && targetVertex) {
|
|
107
|
+
sourceVertex.addNext(sourcePort, { name: targetPort, vertex: targetVertex });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return verticesMap;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Transforms job graph sources based on the specified options.
|
|
114
|
+
*
|
|
115
|
+
* Three transformation strategies are supported:
|
|
116
|
+
* 1. Sample data file: Replace all sources with a LogsValuesSource (not yet implemented)
|
|
117
|
+
* 2. Dataset query: Replace all sources with a single IcebergTableSource
|
|
118
|
+
* 3. In-place: Keep original sources but add record limits for batch processing
|
|
119
|
+
*
|
|
120
|
+
* @param jobGraph - The job graph to transform
|
|
121
|
+
* @param processing - Target processing type
|
|
122
|
+
* @param options - Source transformation options
|
|
123
|
+
* @returns Transformed job graph with updated sources
|
|
124
|
+
*/
|
|
125
|
+
function transformSources(jobGraph, processing, options) {
|
|
126
|
+
if (options.sampleDataFile) {
|
|
127
|
+
transformSourcesToSampleData(jobGraph, options.sampleDataFile);
|
|
128
|
+
}
|
|
129
|
+
else if (options.datasetId) {
|
|
130
|
+
transformSourcesToDatasetQuery(jobGraph, options.datasetId, options.query, options.start, options.end, processing, options.limitRecords);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
transformSourcesInPlace(jobGraph, processing, options.limitRecords);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Transforms sources to use sample data from a file.
|
|
138
|
+
*
|
|
139
|
+
* This replaces all existing sources with a single LogsValuesSource that
|
|
140
|
+
* emits the log events from the sample data file. The file should contain
|
|
141
|
+
* a JSON array of log events matching the LogEvent schema.
|
|
142
|
+
*
|
|
143
|
+
* All edges from the old sources are rewired to connect from the new source
|
|
144
|
+
* to the first downstream operation in the pipeline.
|
|
145
|
+
*
|
|
146
|
+
* @param jobGraph - The job graph to transform
|
|
147
|
+
* @param sampleDataFile - Path to sample data file (JSON array of log events)
|
|
148
|
+
* @throws Error if the file cannot be read or parsed
|
|
149
|
+
*/
|
|
150
|
+
function transformSourcesToSampleData(jobGraph, sampleDataFile) {
|
|
151
|
+
// Read and parse the sample data file
|
|
152
|
+
if (!fs.existsSync(sampleDataFile)) {
|
|
153
|
+
throw new Error(`Sample data file not found: ${sampleDataFile}`);
|
|
154
|
+
}
|
|
155
|
+
let sampleLogs;
|
|
156
|
+
try {
|
|
157
|
+
const fileContent = fs.readFileSync(sampleDataFile, 'utf-8');
|
|
158
|
+
sampleLogs = JSON.parse(fileContent);
|
|
159
|
+
if (!Array.isArray(sampleLogs)) {
|
|
160
|
+
throw new Error('Sample data must be a JSON array of log events');
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
if (error.message.includes('Sample data')) {
|
|
165
|
+
throw error;
|
|
166
|
+
}
|
|
167
|
+
throw new Error(`Failed to parse sample data file: ${error.message}`);
|
|
168
|
+
}
|
|
169
|
+
// Create a new LogsValuesSource with the sample data
|
|
170
|
+
const newSource = {
|
|
171
|
+
type: LogsValuesSourceType.logs_values_source,
|
|
172
|
+
name: 'test_sample_source',
|
|
173
|
+
values: sampleLogs,
|
|
174
|
+
indefinite: false
|
|
175
|
+
};
|
|
176
|
+
const newSourceVertex = new Vertex(newSource);
|
|
177
|
+
// Remove all old sources and connect them to the new source
|
|
178
|
+
for (const vertex of Array.from(jobGraph.values())) {
|
|
179
|
+
if (isSource(vertex)) {
|
|
180
|
+
// Rewire edges from old source's next vertices to new source
|
|
181
|
+
for (const [port, nextIos] of vertex.next) {
|
|
182
|
+
for (const nextIo of nextIos) {
|
|
183
|
+
vertex.removeNext(port, nextIo);
|
|
184
|
+
newSourceVertex.addNext(DEFAULT_OUTPUT, nextIo);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
jobGraph.delete(vertex.name);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
// Add the new source vertex to the graph
|
|
191
|
+
jobGraph.set(newSourceVertex.name, newSourceVertex);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Transforms sources to use an Iceberg dataset as the data source.
|
|
195
|
+
*
|
|
196
|
+
* This replaces all existing sources with a single IcebergTableSource that:
|
|
197
|
+
* - Reads from the specified dataset
|
|
198
|
+
* - Optionally filters data using a query
|
|
199
|
+
* - Reads data within the specified time range
|
|
200
|
+
* - Limits records for batch processing if specified
|
|
201
|
+
*
|
|
202
|
+
* All edges from the old sources are rewired to connect from the new source
|
|
203
|
+
* to the first downstream operation in the pipeline.
|
|
204
|
+
*
|
|
205
|
+
* @param jobGraph - The job graph to transform
|
|
206
|
+
* @param datasetId - ID of the dataset to read from
|
|
207
|
+
* @param query - Optional query to filter dataset data
|
|
208
|
+
* @param start - Start time for data query
|
|
209
|
+
* @param end - End time for data query
|
|
210
|
+
* @param processing - Processing type (BATCH or STREAMING)
|
|
211
|
+
* @param limitRecords - Optional record limit for batch processing
|
|
212
|
+
* @returns Transformed job graph with dataset source
|
|
213
|
+
*/
|
|
214
|
+
function transformSourcesToDatasetQuery(jobGraph, datasetId, query, start, end, processing, limitRecords) {
|
|
215
|
+
// Create a new Iceberg table source with the specified configuration
|
|
216
|
+
const newSource = {
|
|
217
|
+
type: LogsIcebergTableSourceType.logs_iceberg_table_source,
|
|
218
|
+
name: 'test_dataset_source',
|
|
219
|
+
datasetId,
|
|
220
|
+
query: {
|
|
221
|
+
type: DatadogQueryPredicateType.datadog_query,
|
|
222
|
+
query: query || ''
|
|
223
|
+
},
|
|
224
|
+
start: start || '',
|
|
225
|
+
end: end || '',
|
|
226
|
+
limit: limitRecords ?? DEFAULT_LIMIT
|
|
227
|
+
};
|
|
228
|
+
const newSourceVertex = new Vertex(newSource);
|
|
229
|
+
// Remove all old sources and connect them to the new source
|
|
230
|
+
for (const vertex of Array.from(jobGraph.values())) {
|
|
231
|
+
if (isSource(vertex)) {
|
|
232
|
+
// This is a source vertex since it has no inputs.
|
|
233
|
+
// Rewire edges from old source's next vertices to new source
|
|
234
|
+
for (const [port, nextIos] of vertex.next) {
|
|
235
|
+
for (const nextIo of nextIos) {
|
|
236
|
+
vertex.removeNext(port, nextIo);
|
|
237
|
+
newSourceVertex.addNext(DEFAULT_OUTPUT, nextIo);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
jobGraph.delete(vertex.name);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
// Add the new source vertex to the graph
|
|
244
|
+
jobGraph.set(newSourceVertex.name, newSourceVertex);
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Transforms sources in place by adding record limits for batch processing.
|
|
248
|
+
*
|
|
249
|
+
* This keeps the original sources but adds a 'limit' parameter to sources
|
|
250
|
+
* that support it (e.g., IcebergTableSource). This is useful when you want
|
|
251
|
+
* to test with the same data sources but limit the amount of data processed.
|
|
252
|
+
*
|
|
253
|
+
* @param jobGraph - The job graph to transform
|
|
254
|
+
* @param processing - Processing type
|
|
255
|
+
* @param limitRecords - Optional record limit to apply
|
|
256
|
+
* @returns Transformed job graph with limited sources
|
|
257
|
+
*/
|
|
258
|
+
function transformSourcesInPlace(jobGraph, processing, limitRecords) {
|
|
259
|
+
for (const vertex of jobGraph.values()) {
|
|
260
|
+
if (!isSource(vertex)) {
|
|
261
|
+
// Not a source vertex
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
if (processing === JobProcessing.BATCH && limitRecords && canLimit(vertex.operation)) {
|
|
265
|
+
vertex.operation = {
|
|
266
|
+
...vertex.operation,
|
|
267
|
+
limit: limitRecords
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Transforms job graph sinks based on the target execution type.
|
|
274
|
+
*
|
|
275
|
+
* Two transformation strategies:
|
|
276
|
+
* 1. SYNCHRONOUS: Replace all sinks with a single synchronous sink that returns results
|
|
277
|
+
* 2. ASYNCHRONOUS: Replace vendor sinks with test dataset sinks (if testDataset provided)
|
|
278
|
+
*
|
|
279
|
+
* @param jobGraph - The job graph to transform
|
|
280
|
+
* @param execution - Target execution type
|
|
281
|
+
* @param options - Sink transformation options
|
|
282
|
+
* @returns Transformed job graph with updated sinks
|
|
283
|
+
*/
|
|
284
|
+
function transformSinks(jobGraph, execution, options) {
|
|
285
|
+
if (execution === JobExecution.SYNCHRONOUS) {
|
|
286
|
+
return transformSinksToSynchronous(jobGraph);
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
if (!options.testDataset) {
|
|
290
|
+
throw new Error('Test dataset ID is required for ASYNCHRONOUS test job');
|
|
291
|
+
}
|
|
292
|
+
return transformSinksToAsynchronous(jobGraph, options.testDataset);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Transforms all sinks to a single synchronous sink.
|
|
297
|
+
*
|
|
298
|
+
* For synchronous testing, we replace all sink operations with a single
|
|
299
|
+
* LogsSyncSink that returns the processed data in the API response.
|
|
300
|
+
* This allows immediate verification of results.
|
|
301
|
+
*
|
|
302
|
+
* All operations that were feeding into the original sinks are rewired
|
|
303
|
+
* to feed into the new synchronous sink.
|
|
304
|
+
*
|
|
305
|
+
* @param jobGraph - The job graph to transform
|
|
306
|
+
*/
|
|
307
|
+
function transformSinksToSynchronous(jobGraph) {
|
|
308
|
+
// Create a single synchronous sink to replace them all
|
|
309
|
+
const syncSink = {
|
|
310
|
+
type: LogsSynchronousSinkType.logs_sync_sink,
|
|
311
|
+
name: 'test_synchronous_sink'
|
|
312
|
+
};
|
|
313
|
+
const sinkVertex = new Vertex(syncSink);
|
|
314
|
+
wireNewSink(jobGraph, sinkVertex);
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Transforms sinks for asynchronous testing with a test dataset.
|
|
318
|
+
*
|
|
319
|
+
* If a test dataset ID is provided, this replaces vendor sinks, raw data sinks,
|
|
320
|
+
* and event dedup sinks with Iceberg table sinks that write to the test dataset.
|
|
321
|
+
*
|
|
322
|
+
* The original sink names are preserved to maintain the graph structure.
|
|
323
|
+
* Test tagging (added separately) allows distinguishing which sink the data came from.
|
|
324
|
+
*
|
|
325
|
+
* @param jobGraph - The job graph to transform
|
|
326
|
+
* @param testDatasetId - Optional test dataset ID for output
|
|
327
|
+
*/
|
|
328
|
+
function transformSinksToAsynchronous(jobGraph, testDatasetId) {
|
|
329
|
+
// For each sink (no outputs), replace with test dataset sink.
|
|
330
|
+
const sinkOp = {
|
|
331
|
+
type: LogsIcebergTableSinkType.logs_iceberg_table_sink,
|
|
332
|
+
name: 'test_async_sink',
|
|
333
|
+
datasetId: testDatasetId
|
|
334
|
+
};
|
|
335
|
+
const sinkVertex = new Vertex(sinkOp);
|
|
336
|
+
wireNewSink(jobGraph, sinkVertex);
|
|
337
|
+
}
|
|
338
|
+
function wireNewSink(jobGraph, sinkVertex) {
|
|
339
|
+
// Find all vertices that feed into sinks and rewire them to the new sync sink
|
|
340
|
+
for (const vertex of Array.from(jobGraph.values())) {
|
|
341
|
+
if (isSink(vertex)) {
|
|
342
|
+
// This is a sink vertex since it has no outputs.
|
|
343
|
+
// Rewire edges from old sink's prev vertices to new sync sink
|
|
344
|
+
for (const [port, prevIos] of vertex.prev) {
|
|
345
|
+
for (const prevIo of prevIos) {
|
|
346
|
+
vertex.removePrev(port, prevIo);
|
|
347
|
+
prevIo.vertex.addNext(prevIo.name, { name: DEFAULT_INPUT, vertex: sinkVertex });
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
jobGraph.delete(vertex.name);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
// Add the new sink vertex to the graph
|
|
354
|
+
jobGraph.set(sinkVertex.name, sinkVertex);
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Adds test tagging operations on all edges, with the id of the
|
|
358
|
+
* original edge and the test run ID.
|
|
359
|
+
*
|
|
360
|
+
* @param jobGraph - The job graph to transform
|
|
361
|
+
* @param testRunId - Unique test run identifier
|
|
362
|
+
*/
|
|
363
|
+
function addTestTagging(jobGraph, testRunId) {
|
|
364
|
+
for (const vertex of Array.from(jobGraph.values())) {
|
|
365
|
+
for (const [output, nextIos] of Array.from(vertex.next)) {
|
|
366
|
+
for (const nextIo of nextIos) {
|
|
367
|
+
// insert a tagging operation before this io
|
|
368
|
+
const edge = `${vertex.name}_${output}_${nextIo.vertex.name}_${nextIo.name}`;
|
|
369
|
+
const tagOpName = `${edge}_test_tag`;
|
|
370
|
+
const tagOp = createTestTagOperation(tagOpName, testRunId, edge);
|
|
371
|
+
const tagVertex = new Vertex(tagOp);
|
|
372
|
+
// Rewire edges: vertex -> tagOp -> nextIo.vertex
|
|
373
|
+
vertex.removeNext(output, nextIo);
|
|
374
|
+
vertex.addNext(output, { name: DEFAULT_INPUT, vertex: tagVertex });
|
|
375
|
+
tagVertex.addNext(DEFAULT_OUTPUT, nextIo);
|
|
376
|
+
// Add the new tagging vertex to the graph
|
|
377
|
+
jobGraph.set(tagVertex.name, tagVertex);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Creates a log transform operation that adds test tags.
|
|
384
|
+
*
|
|
385
|
+
* The operation adds two tags:
|
|
386
|
+
* - grepr.test_run_id: Identifies which test run this data belongs to
|
|
387
|
+
* - grepr.edge: Identifies edge this data was going through
|
|
388
|
+
*
|
|
389
|
+
* These tags are added using the ADD modification, which appends to existing tag arrays.
|
|
390
|
+
*
|
|
391
|
+
* @param name - Name for the tagging operation
|
|
392
|
+
* @param testRunId - Unique test run identifier
|
|
393
|
+
* @param edge - Name of the edge
|
|
394
|
+
* @returns A LogTransformAction operation that adds the tags
|
|
395
|
+
*/
|
|
396
|
+
function createTestTagOperation(name, testRunId, edge) {
|
|
397
|
+
return {
|
|
398
|
+
type: LogTransformActionType.log_transform,
|
|
399
|
+
name,
|
|
400
|
+
transforms: [
|
|
401
|
+
{
|
|
402
|
+
order: 0,
|
|
403
|
+
type: TagActionType.tag_action,
|
|
404
|
+
modification: TagActionModification.ADD,
|
|
405
|
+
tagKey: 'grepr.test_run_id',
|
|
406
|
+
values: [testRunId]
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
order: 1,
|
|
410
|
+
type: TagActionType.tag_action,
|
|
411
|
+
modification: TagActionModification.ADD,
|
|
412
|
+
tagKey: 'grepr.edge',
|
|
413
|
+
values: [edge]
|
|
414
|
+
}
|
|
415
|
+
]
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
const isSource = (vertex) => vertex.prev.size === 0;
|
|
419
|
+
const isSink = (vertex) => vertex.next.size === 0;
|
|
420
|
+
/**
|
|
421
|
+
* Displays a summary of the transformations applied to a job.
|
|
422
|
+
*
|
|
423
|
+
* This shows a before/after comparison including:
|
|
424
|
+
* - Job name changes
|
|
425
|
+
* - Execution type changes
|
|
426
|
+
* - Processing type changes
|
|
427
|
+
* - operation and edge changes
|
|
428
|
+
* - Test run ID
|
|
429
|
+
*
|
|
430
|
+
* The output is formatted for console display.
|
|
431
|
+
*
|
|
432
|
+
* @param originalJob - The original production job
|
|
433
|
+
* @param transformedJob - The transformed test job
|
|
434
|
+
*/
|
|
435
|
+
export function showDiff(originalJob, transformedJob) {
|
|
436
|
+
console.log('\n=== TRANSFORMATION SUMMARY ===\n');
|
|
437
|
+
console.log(`Name: ${originalJob.name} → ${transformedJob.name}`);
|
|
438
|
+
console.log(`Execution: ${originalJob.execution} → ${transformedJob.execution}`);
|
|
439
|
+
console.log(`Processing: ${originalJob.processing} → ${transformedJob.processing}`);
|
|
440
|
+
if (originalJob.jobGraph && transformedJob.jobGraph) {
|
|
441
|
+
// Show added/removed operations and added/removed edges
|
|
442
|
+
// For each operation in original, check if in transformed, and if changed
|
|
443
|
+
const originalOps = new Set(originalJob.jobGraph.vertices.map(v => v.name));
|
|
444
|
+
const transformedOps = new Set(transformedJob.jobGraph.vertices.map(v => v.name));
|
|
445
|
+
const originalOpsMap = new Map(originalJob.jobGraph.vertices.map(v => [v.name, v]));
|
|
446
|
+
const transformedOpsMap = new Map(transformedJob.jobGraph.vertices.map(v => [v.name, v]));
|
|
447
|
+
const addedOps = Array.from(transformedOps).filter(op => !originalOps.has(op));
|
|
448
|
+
const removedOps = Array.from(originalOps).filter(op => !transformedOps.has(op));
|
|
449
|
+
const changedOps = Array.from(originalOps).filter(op => transformedOps.has(op) &&
|
|
450
|
+
JSON.stringify(originalOpsMap.get(op)) !== JSON.stringify(transformedOpsMap.get(op)));
|
|
451
|
+
if (addedOps.length > 0) {
|
|
452
|
+
console.log(`Added Operations:`);
|
|
453
|
+
for (const opName of addedOps) {
|
|
454
|
+
const op = transformedOpsMap.get(opName);
|
|
455
|
+
console.log(`${JSON.stringify(op, null, 2)}`);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
if (removedOps.length > 0) {
|
|
459
|
+
console.log(`Removed Operations:`);
|
|
460
|
+
for (const opName of removedOps) {
|
|
461
|
+
const op = originalOpsMap.get(opName);
|
|
462
|
+
console.log(`${JSON.stringify(op, null, 2)}`);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
if (changedOps.length > 0) {
|
|
466
|
+
console.log(` Changed Operations:`);
|
|
467
|
+
for (const opName of changedOps) {
|
|
468
|
+
const originalOp = originalOpsMap.get(opName);
|
|
469
|
+
const transformedOp = transformedOpsMap.get(opName);
|
|
470
|
+
console.log(`- Original: ${JSON.stringify(originalOp, null, 2)}`);
|
|
471
|
+
console.log(`+ Transformed: ${JSON.stringify(transformedOp, null, 2)}`);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
// Show edge changes
|
|
475
|
+
const originalEdges = new Set(originalJob.jobGraph.edges);
|
|
476
|
+
const transformedEdges = new Set(transformedJob.jobGraph.edges);
|
|
477
|
+
const addedEdges = Array.from(transformedEdges).filter(edge => !originalEdges.has(edge));
|
|
478
|
+
const removedEdges = Array.from(originalEdges).filter(edge => !transformedEdges.has(edge));
|
|
479
|
+
if (addedEdges.length > 0) {
|
|
480
|
+
console.log(`\n Added Edges:`);
|
|
481
|
+
for (const edge of addedEdges) {
|
|
482
|
+
console.log(`+ ${edge}`);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
if (removedEdges.length > 0) {
|
|
486
|
+
console.log(`\n Removed Edges:`);
|
|
487
|
+
for (const edge of removedEdges) {
|
|
488
|
+
console.log(`- ${edge}`);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
console.log('\nOperations:');
|
|
492
|
+
}
|
|
493
|
+
console.log('\nTest Tag:');
|
|
494
|
+
console.log(` ${transformedJob.tags?.['grepr.test_run_id']}`);
|
|
495
|
+
console.log('\n=== TRANSFORMED JOB JSON ===\n');
|
|
496
|
+
}
|
|
497
|
+
//# sourceMappingURL=job-graph-transformer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-graph-transformer.js","sourceRoot":"","sources":["../../../src/main/typescript/lib/job-graph-transformer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for working with Grepr job graphs.
|
|
3
|
+
*
|
|
4
|
+
* This module provides helper functions for:
|
|
5
|
+
* - Identifying different types of operations (sources, sinks, etc.)
|
|
6
|
+
* - Parsing and manipulating job graph edges
|
|
7
|
+
* - Traversing the job graph to find related vertices
|
|
8
|
+
* - Generating test identifiers
|
|
9
|
+
*
|
|
10
|
+
* All functions work with the OpenAPI-generated types to ensure type safety.
|
|
11
|
+
*/
|
|
12
|
+
import { SchemaOperation } from '../openapi/openApiTypes.js';
|
|
13
|
+
/**
|
|
14
|
+
* Checks if a source vertex supports record limiting.
|
|
15
|
+
*
|
|
16
|
+
* Some source operations (like Iceberg table sources and Grepr internal sources)
|
|
17
|
+
* support a 'limit' parameter to restrict the number of records read, which is
|
|
18
|
+
* useful for batch testing.
|
|
19
|
+
*
|
|
20
|
+
* @param vertex - The operation to check
|
|
21
|
+
* @returns true if the vertex supports limiting
|
|
22
|
+
*/
|
|
23
|
+
export declare function canLimit(vertex: SchemaOperation): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Parses a job graph edge string into source and target vertex names.
|
|
26
|
+
*
|
|
27
|
+
* Edges are represented as strings in the format "source -> target".
|
|
28
|
+
* Or "source:out -> target:in".
|
|
29
|
+
* This function splits the edge and validates the format.
|
|
30
|
+
*
|
|
31
|
+
* @param edge - The edge string to parse (e.g., "source -> target")
|
|
32
|
+
* @returns A tuple of [source, target] vertex/port names
|
|
33
|
+
* @throws Error if the edge format is invalid
|
|
34
|
+
*/
|
|
35
|
+
export declare function parseEdge(edge: string): {
|
|
36
|
+
sourceVertex: string;
|
|
37
|
+
sourcePort: string;
|
|
38
|
+
targetVertex: string;
|
|
39
|
+
targetPort: string;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Generates a unique test identifier.
|
|
43
|
+
*
|
|
44
|
+
* Creates a unique ID for test runs using a combination of timestamp and random string.
|
|
45
|
+
* Format: test_{timestamp}_{random}
|
|
46
|
+
*
|
|
47
|
+
* @returns A unique test identifier string
|
|
48
|
+
*/
|
|
49
|
+
export declare function generateUUID(): string;
|
|
50
|
+
//# sourceMappingURL=job-graph-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-graph-utils.d.ts","sourceRoot":"","sources":["../../../src/main/typescript/lib/job-graph-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,eAAe,EAGhB,MAAM,wBAAwB,CAAC;AAGhC;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAazD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG;IACvC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAA;CACnB,CA6BA;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC"}
|