@aws/lsp-codewhisperer 0.0.96 → 0.0.97
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/CHANGELOG.md +12 -0
- package/out/language-server/agenticChat/agenticChatController.d.ts +3 -1
- package/out/language-server/agenticChat/agenticChatController.js +38 -17
- package/out/language-server/agenticChat/agenticChatController.js.map +1 -1
- package/out/language-server/agenticChat/constants/constants.d.ts +0 -3
- package/out/language-server/agenticChat/constants/constants.js +1 -7
- package/out/language-server/agenticChat/constants/constants.js.map +1 -1
- package/out/language-server/agenticChat/constants/modelSelection.d.ts +1 -0
- package/out/language-server/agenticChat/constants/modelSelection.js +5 -1
- package/out/language-server/agenticChat/constants/modelSelection.js.map +1 -1
- package/out/language-server/agenticChat/tools/mcp/mcpOauthClient.js.map +1 -1
- package/out/language-server/agenticChat/utils/tokenLimitsCalculator.d.ts +48 -0
- package/out/language-server/agenticChat/utils/tokenLimitsCalculator.js +48 -0
- package/out/language-server/agenticChat/utils/tokenLimitsCalculator.js.map +1 -0
- package/out/language-server/chat/chatSessionService.d.ts +17 -1
- package/out/language-server/chat/chatSessionService.js +28 -1
- package/out/language-server/chat/chatSessionService.js.map +1 -1
- package/out/language-server/configuration/transformConfigurationServer.d.ts +0 -13
- package/out/language-server/configuration/transformConfigurationServer.js +4 -112
- package/out/language-server/configuration/transformConfigurationServer.js.map +1 -1
- package/out/language-server/netTransform/atxTransformHandler.d.ts +2 -33
- package/out/language-server/netTransform/atxTransformHandler.js +130 -428
- package/out/language-server/netTransform/atxTransformHandler.js.map +1 -1
- package/out/language-server/netTransform/transformHandler.d.ts +0 -4
- package/out/language-server/netTransform/transformHandler.js +11 -39
- package/out/language-server/netTransform/transformHandler.js.map +1 -1
- package/out/language-server/netTransform/utils.d.ts +49 -0
- package/out/language-server/netTransform/utils.js +187 -0
- package/out/language-server/netTransform/utils.js.map +1 -0
- package/out/shared/amazonQServiceManager/AtxTokenServiceManager.d.ts +0 -1
- package/out/shared/amazonQServiceManager/AtxTokenServiceManager.js +14 -38
- package/out/shared/amazonQServiceManager/AtxTokenServiceManager.js.map +1 -1
- package/out/shared/codeWhispererService.js +1 -1
- package/out/shared/codeWhispererService.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ATXTransformHandler =
|
|
4
|
-
const fs = require("fs");
|
|
5
|
-
const archiver = require("archiver");
|
|
6
|
-
const got_1 = require("got");
|
|
3
|
+
exports.ATXTransformHandler = void 0;
|
|
7
4
|
const path = require("path");
|
|
8
|
-
const crypto = require("crypto");
|
|
9
|
-
const AdmZip = require("adm-zip");
|
|
10
5
|
const artifactManager_1 = require("./artifactManager");
|
|
11
6
|
const elastic_gumby_frontend_client_1 = require("@amazon/elastic-gumby-frontend-client");
|
|
12
7
|
const AtxTokenServiceManager_1 = require("../../shared/amazonQServiceManager/AtxTokenServiceManager");
|
|
13
8
|
const constants_1 = require("../../shared/constants");
|
|
14
9
|
const uuid_1 = require("uuid");
|
|
15
|
-
|
|
10
|
+
const utils_1 = require("./utils");
|
|
16
11
|
/**
|
|
17
12
|
* ATX Transform Handler - Business logic for ATX FES Transform operations
|
|
18
13
|
* Parallel to RTS TransformHandler but uses AtxTokenServiceManager and ATX FES APIs
|
|
@@ -23,80 +18,62 @@ class ATXTransformHandler {
|
|
|
23
18
|
logging;
|
|
24
19
|
runtime;
|
|
25
20
|
atxClient = null;
|
|
26
|
-
cachedApplicationUrl = null;
|
|
27
21
|
cachedHitl = null;
|
|
28
22
|
constructor(serviceManager, workspace, logging, runtime) {
|
|
29
23
|
this.serviceManager = serviceManager;
|
|
30
24
|
this.workspace = workspace;
|
|
31
25
|
this.logging = logging;
|
|
32
26
|
this.runtime = runtime;
|
|
33
|
-
this.serviceManager.registerCacheCallback(() => this.
|
|
27
|
+
this.serviceManager.registerCacheCallback(() => this.onProfileUpdate());
|
|
34
28
|
}
|
|
35
29
|
/**
|
|
36
30
|
* Initialize ATX FES client
|
|
37
31
|
*/
|
|
38
32
|
async initializeAtxClient() {
|
|
39
33
|
try {
|
|
40
|
-
this.logging.log('
|
|
34
|
+
this.logging.log('ATX: Starting client initialization');
|
|
41
35
|
let region = process.env[constants_1.ATX_FES_REGION_ENV_VAR];
|
|
42
|
-
this.logging.log(`DEBUG-ATX-INIT: Environment region: ${region || 'not set'}`);
|
|
43
36
|
if (!region) {
|
|
44
37
|
// Try to get region from active profile
|
|
45
38
|
region = await this.getRegionFromProfile();
|
|
46
|
-
if (region) {
|
|
47
|
-
this.logging.
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
this.logging.log('DEBUG-ATX-INIT: No region available - cannot initialize client without region');
|
|
51
|
-
this.logging.log('DEBUG-ATX-INIT: Profile selection or multi-region discovery needed first');
|
|
39
|
+
if (!region) {
|
|
40
|
+
this.logging.error('ATX: No region available - cannot initialize client');
|
|
52
41
|
return false;
|
|
53
42
|
}
|
|
54
43
|
}
|
|
55
44
|
const endpoint = process.env.TCP_ENDPOINT || (0, constants_1.getAtxEndPointByRegion)(region);
|
|
56
|
-
this.logging.log(`
|
|
57
|
-
this.clearApplicationUrlCache();
|
|
58
|
-
this.logging.log('DEBUG-ATX-INIT: Cleared application URL cache');
|
|
59
|
-
this.logging.log('DEBUG-ATX-INIT: About to create ElasticGumbyFrontendClient');
|
|
45
|
+
this.logging.log(`ATX: Using region ${region} with endpoint ${endpoint}`);
|
|
60
46
|
this.atxClient = new elastic_gumby_frontend_client_1.ElasticGumbyFrontendClient({
|
|
61
47
|
region: region,
|
|
62
48
|
endpoint: endpoint,
|
|
63
49
|
});
|
|
64
|
-
this.logging.log('
|
|
50
|
+
this.logging.log('ATX: Client initialization completed');
|
|
65
51
|
return true;
|
|
66
52
|
}
|
|
67
53
|
catch (error) {
|
|
68
|
-
|
|
69
|
-
const endpoint = process.env.TCP_ENDPOINT || constants_1.DEFAULT_ATX_FES_ENDPOINT_URL;
|
|
70
|
-
this.logging.log(`DEBUG-ATX-INIT: Failed to initialize with region: ${region}, endpoint: ${endpoint}. Error: ${error}`);
|
|
54
|
+
this.logging.error(`ATX: Failed to initialize client: ${String(error)}`);
|
|
71
55
|
return false;
|
|
72
56
|
}
|
|
73
57
|
}
|
|
74
58
|
async getRegionFromProfile() {
|
|
75
59
|
try {
|
|
76
|
-
this.logging.log('DEBUG-ATX-REGION: Starting getRegionFromProfile()');
|
|
77
60
|
if (!this.serviceManager.hasValidCredentials()) {
|
|
78
|
-
this.logging.log('DEBUG-ATX-REGION: No valid credentials, returning undefined');
|
|
79
61
|
return undefined;
|
|
80
62
|
}
|
|
81
|
-
this.logging.log('DEBUG-ATX-REGION: Valid credentials found');
|
|
82
63
|
// Get active profile applicationURL and extract region from it
|
|
83
64
|
const atxServiceManager = AtxTokenServiceManager_1.AtxTokenServiceManager.getInstance();
|
|
84
65
|
const applicationUrl = atxServiceManager.getActiveApplicationUrl();
|
|
85
66
|
if (applicationUrl) {
|
|
86
|
-
this.logging.log(`DEBUG-ATX-REGION: Found applicationURL: ${applicationUrl}`);
|
|
87
67
|
// Extract region from applicationURL: https://xxx.transform.REGION.on.aws
|
|
88
68
|
const urlMatch = applicationUrl.match(/\.transform(?:-gamma)?\.([^.]+)\.on\.aws/);
|
|
89
69
|
if (urlMatch && urlMatch[1]) {
|
|
90
|
-
|
|
91
|
-
this.logging.log(`DEBUG-ATX-REGION: Extracted region from applicationURL: ${region}`);
|
|
92
|
-
return region;
|
|
70
|
+
return urlMatch[1];
|
|
93
71
|
}
|
|
94
72
|
}
|
|
95
|
-
this.logging.log('DEBUG-ATX-REGION: No active applicationURL, using default region');
|
|
96
73
|
return constants_1.DEFAULT_ATX_FES_REGION;
|
|
97
74
|
}
|
|
98
75
|
catch (error) {
|
|
99
|
-
this.logging.
|
|
76
|
+
this.logging.error(`ATX: Error getting region from profile: ${String(error)}`);
|
|
100
77
|
return undefined;
|
|
101
78
|
}
|
|
102
79
|
}
|
|
@@ -132,61 +109,41 @@ class ATXTransformHandler {
|
|
|
132
109
|
*/
|
|
133
110
|
async getActiveTransformProfileApplicationUrl() {
|
|
134
111
|
try {
|
|
135
|
-
// Return cached URL if available (avoids expensive profile discovery)
|
|
136
|
-
if (this.cachedApplicationUrl) {
|
|
137
|
-
this.logging.log(`DEBUG-ATX-URL: Using cached applicationUrl: ${this.cachedApplicationUrl}`);
|
|
138
|
-
return this.cachedApplicationUrl;
|
|
139
|
-
}
|
|
140
112
|
// Get applicationUrl from service manager (cached from configuration)
|
|
141
113
|
const applicationUrl = this.serviceManager.getActiveApplicationUrl();
|
|
142
114
|
if (!applicationUrl) {
|
|
143
|
-
this.logging.error('
|
|
144
|
-
this.logging.error('DEBUG-ATX-URL: Profile not selected or not cached yet');
|
|
115
|
+
this.logging.error('ATX: No applicationUrl found - profile not selected');
|
|
145
116
|
return null;
|
|
146
117
|
}
|
|
147
|
-
this.logging.log(`DEBUG-ATX-URL: Using service manager applicationUrl: ${applicationUrl}`);
|
|
148
|
-
// Cache the applicationUrl for future use
|
|
149
|
-
this.cachedApplicationUrl = applicationUrl;
|
|
150
118
|
return applicationUrl;
|
|
151
119
|
}
|
|
152
120
|
catch (error) {
|
|
153
|
-
this.logging.error(`
|
|
121
|
+
this.logging.error(`ATX: Error getting applicationUrl: ${String(error)}`);
|
|
154
122
|
return null;
|
|
155
123
|
}
|
|
156
124
|
}
|
|
157
125
|
/**
|
|
158
|
-
*
|
|
126
|
+
* Reset atx client (for profile update scenarios)
|
|
159
127
|
*/
|
|
160
|
-
|
|
161
|
-
this.
|
|
128
|
+
onProfileUpdate() {
|
|
129
|
+
this.atxClient = null;
|
|
162
130
|
}
|
|
163
131
|
/**
|
|
164
132
|
* Verify session (internal LSP method called before each ATX API)
|
|
165
133
|
*/
|
|
166
134
|
async verifySession() {
|
|
167
135
|
try {
|
|
168
|
-
this.logging.log('DEBUG-ATX: VerifySession operation started');
|
|
169
|
-
this.logging.log('DEBUG-ATX: About to call initializeAtxClient()');
|
|
170
136
|
if (!(await this.initializeAtxClient())) {
|
|
171
|
-
this.logging.error('
|
|
137
|
+
this.logging.error('ATX: Failed to initialize client for session verification');
|
|
172
138
|
return false;
|
|
173
139
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
this.
|
|
177
|
-
const bearerToken = await this.serviceManager.getBearerToken();
|
|
178
|
-
this.logging.log('DEBUG-ATX: getBearerToken() completed');
|
|
179
|
-
this.logging.log('DEBUG-ATX: About to call getActiveTransformProfileApplicationUrl()');
|
|
180
|
-
const applicationUrl = await this.getActiveTransformProfileApplicationUrl();
|
|
181
|
-
this.logging.log('DEBUG-ATX: getActiveTransformProfileApplicationUrl() completed');
|
|
182
|
-
this.logging.log(`DEBUG-ATX: VerifySession - applicationUrl: ${applicationUrl || 'null'}`);
|
|
183
|
-
this.logging.log(`DEBUG-ATX: VerifySession - bearer token length: ${bearerToken ? bearerToken.length : 0} characters`);
|
|
184
|
-
// Always return true like reference repo
|
|
185
|
-
this.logging.log(`DEBUG-ATX: VerifySession successful`);
|
|
140
|
+
// Verify authentication details
|
|
141
|
+
await this.serviceManager.getBearerToken();
|
|
142
|
+
await this.getActiveTransformProfileApplicationUrl();
|
|
186
143
|
return true;
|
|
187
144
|
}
|
|
188
145
|
catch (error) {
|
|
189
|
-
this.logging.error(`
|
|
146
|
+
this.logging.error(`ATX: Session verification error: ${String(error)}`);
|
|
190
147
|
return false;
|
|
191
148
|
}
|
|
192
149
|
}
|
|
@@ -195,16 +152,15 @@ class ATXTransformHandler {
|
|
|
195
152
|
*/
|
|
196
153
|
async listWorkspaces() {
|
|
197
154
|
try {
|
|
198
|
-
this.logging.log('
|
|
155
|
+
this.logging.log('ATX: Starting ListWorkspaces operation');
|
|
199
156
|
if (!this.atxClient && !(await this.initializeAtxClient())) {
|
|
200
157
|
throw new Error('ATX FES client not initialized');
|
|
201
158
|
}
|
|
202
159
|
const { ListWorkspacesCommand } = await Promise.resolve().then(() => require('@amazon/elastic-gumby-frontend-client'));
|
|
203
160
|
const command = new ListWorkspacesCommand({});
|
|
204
161
|
await this.addAuthToCommand(command);
|
|
205
|
-
this.logging.log('DEBUG-ATX: Sending ListWorkspaces command to ATX FES');
|
|
206
162
|
const response = await this.atxClient.send(command);
|
|
207
|
-
this.logging.log(`
|
|
163
|
+
this.logging.log(`ATX: ListWorkspaces completed - found ${response.items?.length || 0} workspaces`);
|
|
208
164
|
this.logging.log(`ATX: ListWorkspaces RequestId: ${response.$metadata?.requestId}`);
|
|
209
165
|
// Convert ATX API format to IDE expected format
|
|
210
166
|
const workspaces = (response.items || []).map(workspace => ({
|
|
@@ -212,11 +168,10 @@ class ATXTransformHandler {
|
|
|
212
168
|
Name: workspace.name,
|
|
213
169
|
CreatedDate: new Date().toISOString(), // Use current date since createdDate not available
|
|
214
170
|
}));
|
|
215
|
-
this.logging.log(`DEBUG-ATX: Converted workspaces: ${JSON.stringify(workspaces, null, 2)}`);
|
|
216
171
|
return workspaces;
|
|
217
172
|
}
|
|
218
173
|
catch (error) {
|
|
219
|
-
this.logging.error(`
|
|
174
|
+
this.logging.error(`ATX: ListWorkspaces error: ${String(error)}`);
|
|
220
175
|
return [];
|
|
221
176
|
}
|
|
222
177
|
}
|
|
@@ -225,7 +180,7 @@ class ATXTransformHandler {
|
|
|
225
180
|
*/
|
|
226
181
|
async createWorkspace(workspaceName) {
|
|
227
182
|
try {
|
|
228
|
-
this.logging.log(`
|
|
183
|
+
this.logging.log(`ATX: Starting CreateWorkspace with name: ${workspaceName || 'auto-generated'}`);
|
|
229
184
|
if (!this.atxClient && !(await this.initializeAtxClient())) {
|
|
230
185
|
throw new Error('ATX FES client not initialized');
|
|
231
186
|
}
|
|
@@ -235,23 +190,21 @@ class ATXTransformHandler {
|
|
|
235
190
|
description: workspaceName ? `Workspace: ${workspaceName}` : 'Auto-generated workspace',
|
|
236
191
|
});
|
|
237
192
|
await this.addAuthToCommand(command);
|
|
238
|
-
this.logging.log('DEBUG-ATX: Sending CreateWorkspace command to ATX FES');
|
|
239
193
|
const response = await this.atxClient.send(command);
|
|
240
|
-
this.logging.log(`DEBUG-ATX: CreateWorkspace API returned workspaceId: ${response.workspace?.id}`);
|
|
241
194
|
this.logging.log(`ATX: CreateWorkspace RequestId: ${response.$metadata?.requestId}`);
|
|
242
195
|
if (response.workspace?.id && response.workspace?.name) {
|
|
243
196
|
const result = {
|
|
244
197
|
workspaceId: response.workspace.id,
|
|
245
198
|
workspaceName: response.workspace.name,
|
|
246
199
|
};
|
|
247
|
-
this.logging.log(`
|
|
200
|
+
this.logging.log(`ATX: CreateWorkspace completed successfully: ${response.workspace.id}`);
|
|
248
201
|
return result;
|
|
249
202
|
}
|
|
250
|
-
this.logging.
|
|
203
|
+
this.logging.error('ATX: CreateWorkspace failed - no workspace in response');
|
|
251
204
|
return null;
|
|
252
205
|
}
|
|
253
206
|
catch (error) {
|
|
254
|
-
this.logging.error(`
|
|
207
|
+
this.logging.error(`ATX: CreateWorkspace error: ${String(error)}`);
|
|
255
208
|
return null;
|
|
256
209
|
}
|
|
257
210
|
}
|
|
@@ -260,15 +213,13 @@ class ATXTransformHandler {
|
|
|
260
213
|
*/
|
|
261
214
|
async listOrCreateWorkspace(request) {
|
|
262
215
|
try {
|
|
263
|
-
this.logging.log('
|
|
264
|
-
this.logging.log(`DEBUG-ATX: Request: ${JSON.stringify(request, null, 2)}`);
|
|
216
|
+
this.logging.log('ATX: Starting ListOrCreateWorkspace operation');
|
|
265
217
|
// Call verifySession ONCE at the beginning
|
|
266
218
|
if (!(await this.verifySession())) {
|
|
267
|
-
this.logging.error('
|
|
219
|
+
this.logging.error('ATX: Session verification failed for listOrCreateWorkspace');
|
|
268
220
|
return null;
|
|
269
221
|
}
|
|
270
222
|
// Always get list of existing workspaces
|
|
271
|
-
this.logging.log('DEBUG-ATX: Getting list of existing workspaces');
|
|
272
223
|
const workspaces = await this.listWorkspaces();
|
|
273
224
|
const response = {
|
|
274
225
|
AvailableWorkspaces: workspaces,
|
|
@@ -276,7 +227,6 @@ class ATXTransformHandler {
|
|
|
276
227
|
};
|
|
277
228
|
// Optionally create new workspace
|
|
278
229
|
if (request.CreateWorkspaceName !== undefined) {
|
|
279
|
-
this.logging.log(`DEBUG-ATX: Creating new workspace: ${request.CreateWorkspaceName || 'auto-generated'}`);
|
|
280
230
|
const newWorkspace = await this.createWorkspace(request.CreateWorkspaceName);
|
|
281
231
|
if (newWorkspace) {
|
|
282
232
|
response.CreatedWorkspace = {
|
|
@@ -289,15 +239,13 @@ class ATXTransformHandler {
|
|
|
289
239
|
Name: newWorkspace.workspaceName,
|
|
290
240
|
CreatedDate: new Date().toISOString(),
|
|
291
241
|
});
|
|
292
|
-
this.logging.log(`DEBUG-ATX: Added new workspace to available list`);
|
|
293
242
|
}
|
|
294
243
|
}
|
|
295
|
-
this.logging.log(`
|
|
296
|
-
this.logging.log(`DEBUG-ATX: Final response: ${JSON.stringify(response, null, 2)}`);
|
|
244
|
+
this.logging.log(`ATX: ListOrCreateWorkspace completed - ${response.AvailableWorkspaces.length} workspaces available`);
|
|
297
245
|
return response;
|
|
298
246
|
}
|
|
299
247
|
catch (error) {
|
|
300
|
-
this.logging.error(`
|
|
248
|
+
this.logging.error(`ATX: ListOrCreateWorkspace error: ${String(error)}`);
|
|
301
249
|
return null;
|
|
302
250
|
}
|
|
303
251
|
}
|
|
@@ -306,16 +254,11 @@ class ATXTransformHandler {
|
|
|
306
254
|
*/
|
|
307
255
|
async createJob(request) {
|
|
308
256
|
try {
|
|
309
|
-
this.logging.log(`
|
|
310
|
-
this.logging.log(`DEBUG-ATX-CREATE-JOB: jobName: ${request.jobName || 'auto-generated'}`);
|
|
257
|
+
this.logging.log(`ATX: Starting CreateJob for workspace: ${request.workspaceId}`);
|
|
311
258
|
// Call ATX FES createJob API
|
|
312
|
-
this.
|
|
313
|
-
|
|
314
|
-
if (!this.atxClient) {
|
|
315
|
-
throw new Error('ATX client not initialized');
|
|
259
|
+
if (!this.atxClient && !(await this.initializeAtxClient())) {
|
|
260
|
+
throw new Error('ATX FES client not initialized');
|
|
316
261
|
}
|
|
317
|
-
this.logging.log('DEBUG-ATX-CREATE-JOB: ATX client initialized successfully');
|
|
318
|
-
this.logging.log(`DEBUG-ATX-CREATE-JOB: creating CreateJobCommand with targetFramework ${request.targetFramework}`);
|
|
319
262
|
const command = new elastic_gumby_frontend_client_1.CreateJobCommand({
|
|
320
263
|
workspaceId: request.workspaceId,
|
|
321
264
|
objective: JSON.stringify({ target_framework: request.targetFramework || 'net10.0' }),
|
|
@@ -324,47 +267,33 @@ class ATXTransformHandler {
|
|
|
324
267
|
intent: 'LANGUAGE_UPGRADE',
|
|
325
268
|
idempotencyToken: (0, uuid_1.v4)(),
|
|
326
269
|
});
|
|
327
|
-
this.logging.log('DEBUG-ATX-CREATE-JOB: command created, adding auth...');
|
|
328
270
|
await this.addAuthToCommand(command);
|
|
329
|
-
this.logging.log('DEBUG-ATX-CREATE-JOB: auth added, sending command...');
|
|
330
271
|
const response = (await this.atxClient.send(command));
|
|
331
|
-
this.logging.log(`
|
|
272
|
+
this.logging.log(`ATX: CreateJob completed - jobId: ${response.jobId}, status: ${response.status}`);
|
|
332
273
|
this.logging.log(`ATX: CreateJob RequestId: ${response.$metadata?.requestId}`);
|
|
333
274
|
if (response.jobId && response.status) {
|
|
334
275
|
return { jobId: response.jobId, status: response.status };
|
|
335
276
|
}
|
|
336
|
-
this.logging.error('
|
|
277
|
+
this.logging.error('ATX: CreateJob failed - no jobId or status in response');
|
|
337
278
|
return null;
|
|
338
279
|
}
|
|
339
280
|
catch (error) {
|
|
340
|
-
this.logging.error(`
|
|
281
|
+
this.logging.error(`ATX: CreateJob error: ${String(error)}`);
|
|
341
282
|
return null;
|
|
342
283
|
}
|
|
343
284
|
}
|
|
344
|
-
/**
|
|
345
|
-
* Calculate SHA256 hash of file contents using streaming (matches reference repo)
|
|
346
|
-
*/
|
|
347
|
-
static async getSha256Async(fileName) {
|
|
348
|
-
const hasher = crypto.createHash('sha256');
|
|
349
|
-
const stream = fs.createReadStream(fileName);
|
|
350
|
-
for await (const chunk of stream) {
|
|
351
|
-
hasher.update(chunk);
|
|
352
|
-
}
|
|
353
|
-
return hasher.digest('base64');
|
|
354
|
-
}
|
|
355
285
|
/**
|
|
356
286
|
* Create artifact upload URL
|
|
357
287
|
*/
|
|
358
288
|
async createArtifactUploadUrl(workspaceId, jobId, filePath, categoryType, fileType) {
|
|
359
289
|
try {
|
|
360
|
-
this.logging.log(`
|
|
290
|
+
this.logging.log(`ATX: Starting CreateArtifactUploadUrl for job: ${jobId}`);
|
|
361
291
|
// Initialize ATX client
|
|
362
|
-
await this.initializeAtxClient()
|
|
363
|
-
|
|
364
|
-
throw new Error('ATX client not initialized');
|
|
292
|
+
if (!this.atxClient && !(await this.initializeAtxClient())) {
|
|
293
|
+
throw new Error('ATX FES client not initialized');
|
|
365
294
|
}
|
|
366
295
|
// Calculate file checksum - exact reference repo implementation
|
|
367
|
-
const sha256 = await
|
|
296
|
+
const sha256 = await utils_1.Utils.getSha256Async(filePath);
|
|
368
297
|
const command = new elastic_gumby_frontend_client_1.CreateArtifactUploadUrlCommand({
|
|
369
298
|
workspaceId: workspaceId,
|
|
370
299
|
jobId: jobId,
|
|
@@ -380,7 +309,7 @@ class ATXTransformHandler {
|
|
|
380
309
|
const result = (await this.atxClient.send(command));
|
|
381
310
|
this.logging.log(`ATX: CreateArtifactUploadUrl RequestId: ${result.$metadata?.requestId}`);
|
|
382
311
|
if (result && result.artifactId && result.s3PreSignedUrl) {
|
|
383
|
-
this.logging.log(`
|
|
312
|
+
this.logging.log(`ATX: CreateArtifactUploadUrl completed successfully`);
|
|
384
313
|
return {
|
|
385
314
|
uploadId: result.artifactId,
|
|
386
315
|
uploadUrl: result.s3PreSignedUrl,
|
|
@@ -388,12 +317,12 @@ class ATXTransformHandler {
|
|
|
388
317
|
};
|
|
389
318
|
}
|
|
390
319
|
else {
|
|
391
|
-
this.logging.error('
|
|
320
|
+
this.logging.error('ATX: CreateArtifactUploadUrl failed - missing artifactId or s3PreSignedUrl');
|
|
392
321
|
return null;
|
|
393
322
|
}
|
|
394
323
|
}
|
|
395
324
|
catch (error) {
|
|
396
|
-
this.logging.error(`
|
|
325
|
+
this.logging.error(`ATX: CreateArtifactUploadUrl error: ${String(error)}`);
|
|
397
326
|
return null;
|
|
398
327
|
}
|
|
399
328
|
}
|
|
@@ -402,11 +331,10 @@ class ATXTransformHandler {
|
|
|
402
331
|
*/
|
|
403
332
|
async completeArtifactUpload(workspaceId, jobId, artifactId) {
|
|
404
333
|
try {
|
|
405
|
-
this.logging.log(`
|
|
334
|
+
this.logging.log(`ATX: Starting CompleteArtifactUpload for artifact: ${artifactId}`);
|
|
406
335
|
// Initialize ATX client
|
|
407
|
-
await this.initializeAtxClient()
|
|
408
|
-
|
|
409
|
-
throw new Error('ATX client not initialized');
|
|
336
|
+
if (!this.atxClient && !(await this.initializeAtxClient())) {
|
|
337
|
+
throw new Error('ATX FES client not initialized');
|
|
410
338
|
}
|
|
411
339
|
const command = new elastic_gumby_frontend_client_1.CompleteArtifactUploadCommand({
|
|
412
340
|
workspaceId: workspaceId,
|
|
@@ -415,11 +343,11 @@ class ATXTransformHandler {
|
|
|
415
343
|
});
|
|
416
344
|
await this.addAuthToCommand(command);
|
|
417
345
|
const result = (await this.atxClient.send(command));
|
|
418
|
-
this.logging.log(`
|
|
346
|
+
this.logging.log(`ATX: CompleteArtifactUpload completed successfully`);
|
|
419
347
|
return { success: true };
|
|
420
348
|
}
|
|
421
349
|
catch (error) {
|
|
422
|
-
this.logging.error(`
|
|
350
|
+
this.logging.error(`ATX: CompleteArtifactUpload error: ${String(error)}`);
|
|
423
351
|
return null;
|
|
424
352
|
}
|
|
425
353
|
}
|
|
@@ -428,11 +356,10 @@ class ATXTransformHandler {
|
|
|
428
356
|
*/
|
|
429
357
|
async startJob(workspaceId, jobId) {
|
|
430
358
|
try {
|
|
431
|
-
this.logging.log(`
|
|
359
|
+
this.logging.log(`ATX: Starting job: ${jobId}`);
|
|
432
360
|
// Initialize ATX client
|
|
433
|
-
await this.initializeAtxClient()
|
|
434
|
-
|
|
435
|
-
throw new Error('ATX client not initialized');
|
|
361
|
+
if (!this.atxClient && !(await this.initializeAtxClient())) {
|
|
362
|
+
throw new Error('ATX FES client not initialized');
|
|
436
363
|
}
|
|
437
364
|
const command = new elastic_gumby_frontend_client_1.StartJobCommand({
|
|
438
365
|
workspaceId: workspaceId,
|
|
@@ -441,11 +368,11 @@ class ATXTransformHandler {
|
|
|
441
368
|
await this.addAuthToCommand(command);
|
|
442
369
|
const result = (await this.atxClient.send(command));
|
|
443
370
|
this.logging.log(`ATX: StartJob RequestId: ${result.$metadata?.requestId}`);
|
|
444
|
-
this.logging.log(`
|
|
371
|
+
this.logging.log(`ATX: Job started successfully`);
|
|
445
372
|
return { success: true };
|
|
446
373
|
}
|
|
447
374
|
catch (error) {
|
|
448
|
-
this.logging.error(`
|
|
375
|
+
this.logging.error(`ATX: StartJob error: ${String(error)}`);
|
|
449
376
|
return null;
|
|
450
377
|
}
|
|
451
378
|
}
|
|
@@ -454,73 +381,18 @@ class ATXTransformHandler {
|
|
|
454
381
|
*/
|
|
455
382
|
async createZip(request) {
|
|
456
383
|
try {
|
|
457
|
-
this.logging.log('
|
|
458
|
-
const workspacePath =
|
|
384
|
+
this.logging.log('ATX: Starting ZIP file creation from solution');
|
|
385
|
+
const workspacePath = utils_1.Utils.getWorkspacePath(request.SolutionRootPath);
|
|
459
386
|
const artifactManager = new artifactManager_1.ArtifactManager(this.workspace, this.logging, workspacePath, request.SolutionRootPath);
|
|
460
387
|
const zipFilePath = await artifactManager.createZip(request);
|
|
461
|
-
this.logging.log(`
|
|
388
|
+
this.logging.log(`ATX: ZIP file created successfully: ${zipFilePath}`);
|
|
462
389
|
return zipFilePath;
|
|
463
390
|
}
|
|
464
391
|
catch (error) {
|
|
465
|
-
this.logging.error(`
|
|
392
|
+
this.logging.error(`ATX: createZip error: ${String(error)}`);
|
|
466
393
|
throw error;
|
|
467
394
|
}
|
|
468
395
|
}
|
|
469
|
-
/**
|
|
470
|
-
* Create workspace path like RTS does: {solutionRoot}/artifactWorkspace/{uuid}
|
|
471
|
-
*/
|
|
472
|
-
getWorkspacePath(solutionRootPath) {
|
|
473
|
-
const { v4: uuidv4 } = require('uuid');
|
|
474
|
-
const randomPath = uuidv4().substring(0, 8);
|
|
475
|
-
const path = require('path');
|
|
476
|
-
const workspacePath = path.join(solutionRootPath, 'artifactWorkspace', randomPath);
|
|
477
|
-
if (!fs.existsSync(workspacePath)) {
|
|
478
|
-
fs.mkdirSync(workspacePath, { recursive: true });
|
|
479
|
-
}
|
|
480
|
-
return workspacePath;
|
|
481
|
-
}
|
|
482
|
-
/**
|
|
483
|
-
* Upload artifact to S3 using presigned URL and headers from ATX FES
|
|
484
|
-
*/
|
|
485
|
-
async uploadArtifact(s3PreSignedUrl, filePath, requestHeaders) {
|
|
486
|
-
try {
|
|
487
|
-
this.logging.log(`DEBUG-ATX: Starting S3 upload to ${s3PreSignedUrl}`);
|
|
488
|
-
this.logging.log(`DEBUG-ATX: File path: ${filePath}`);
|
|
489
|
-
const headers = {};
|
|
490
|
-
// Add required headers from ATX FES response
|
|
491
|
-
if (requestHeaders) {
|
|
492
|
-
Object.keys(requestHeaders).forEach(key => {
|
|
493
|
-
const value = requestHeaders[key];
|
|
494
|
-
// Handle array values (take first element)
|
|
495
|
-
headers[key] = Array.isArray(value) ? value[0] : value;
|
|
496
|
-
});
|
|
497
|
-
}
|
|
498
|
-
this.logging.log(`DEBUG-ATX: S3 Upload headers: ${JSON.stringify(Object.keys(headers))}`);
|
|
499
|
-
// Create file stream
|
|
500
|
-
const fileStream = fs.createReadStream(filePath);
|
|
501
|
-
// Upload to S3 using PUT request
|
|
502
|
-
const got = (await Promise.resolve().then(() => require('got'))).default;
|
|
503
|
-
const response = await got.put(s3PreSignedUrl, {
|
|
504
|
-
body: fileStream,
|
|
505
|
-
headers: headers,
|
|
506
|
-
timeout: { request: 300000 }, // 5 minutes timeout
|
|
507
|
-
retry: { limit: 0 },
|
|
508
|
-
});
|
|
509
|
-
this.logging.log(`DEBUG-ATX: S3 Upload response status: ${response.statusCode} ${response.statusMessage}`);
|
|
510
|
-
if (response.statusCode === 200) {
|
|
511
|
-
this.logging.log('DEBUG-ATX: S3 Upload SUCCESS');
|
|
512
|
-
return true;
|
|
513
|
-
}
|
|
514
|
-
else {
|
|
515
|
-
this.logging.error(`DEBUG-ATX: S3 Upload failed with status ${response.statusCode}`);
|
|
516
|
-
return false;
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
catch (error) {
|
|
520
|
-
this.logging.error(`DEBUG-ATX: S3 Upload error: ${String(error)}`);
|
|
521
|
-
return false;
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
396
|
/**
|
|
525
397
|
* Start ATX Transform - Orchestrates the full workflow
|
|
526
398
|
* Step 1: CreateJob ✅
|
|
@@ -528,9 +400,8 @@ class ATXTransformHandler {
|
|
|
528
400
|
*/
|
|
529
401
|
async startTransform(request) {
|
|
530
402
|
try {
|
|
531
|
-
this.logging.log(`
|
|
403
|
+
this.logging.log(`ATX: Starting transform workflow for workspace: ${request.workspaceId}`);
|
|
532
404
|
// Step 1: Create transformation job
|
|
533
|
-
this.logging.log('DEBUG-ATX-START: Step 1 - Creating transformation job');
|
|
534
405
|
const createJobResponse = await this.createJob({
|
|
535
406
|
workspaceId: request.workspaceId,
|
|
536
407
|
jobName: request.jobName || 'Transform Job',
|
|
@@ -539,43 +410,32 @@ class ATXTransformHandler {
|
|
|
539
410
|
if (!createJobResponse?.jobId) {
|
|
540
411
|
throw new Error('Failed to create ATX transformation job');
|
|
541
412
|
}
|
|
542
|
-
this.logging.log(`DEBUG-ATX-START: Step 1 - Created job: ${createJobResponse.jobId} with status: ${createJobResponse.status}`);
|
|
543
413
|
// Step 2: Create ZIP file
|
|
544
|
-
this.logging.log('DEBUG-ATX-START: Step 2 - Creating ZIP file from solution');
|
|
545
414
|
const zipFilePath = await this.createZip(request.startTransformRequest);
|
|
546
415
|
if (!zipFilePath) {
|
|
547
416
|
throw new Error('Failed to create ZIP file for ATX transformation');
|
|
548
417
|
}
|
|
549
|
-
this.logging.log(`DEBUG-ATX-START: Step 2 - Created ZIP file: ${zipFilePath}`);
|
|
550
418
|
// Step 3: Create artifact upload URL
|
|
551
|
-
this.logging.log('DEBUG-ATX-START: Step 3 - Creating artifact upload URL');
|
|
552
419
|
const uploadResponse = await this.createArtifactUploadUrl(request.workspaceId, createJobResponse.jobId, zipFilePath, elastic_gumby_frontend_client_1.CategoryType.CUSTOMER_INPUT, elastic_gumby_frontend_client_1.FileType.ZIP);
|
|
553
420
|
if (!uploadResponse?.uploadUrl) {
|
|
554
421
|
throw new Error('Failed to create artifact upload URL');
|
|
555
422
|
}
|
|
556
|
-
this.logging.log(`DEBUG-ATX-START: Step 3 - Created upload URL with uploadId: ${uploadResponse.uploadId}`);
|
|
557
423
|
// Step 4: Upload ZIP file to S3
|
|
558
|
-
|
|
559
|
-
const uploadSuccess = await this.uploadArtifact(uploadResponse.uploadUrl, zipFilePath, uploadResponse.requestHeaders);
|
|
424
|
+
const uploadSuccess = await utils_1.Utils.uploadArtifact(uploadResponse.uploadUrl, zipFilePath, uploadResponse.requestHeaders, this.logging);
|
|
560
425
|
if (!uploadSuccess) {
|
|
561
426
|
throw new Error('Failed to upload ZIP file to S3');
|
|
562
427
|
}
|
|
563
|
-
this.logging.log('DEBUG-ATX-START: Step 4 - Successfully uploaded ZIP file to S3');
|
|
564
428
|
// Step 5: Complete artifact upload
|
|
565
|
-
this.logging.log('DEBUG-ATX-START: Step 5 - Completing artifact upload');
|
|
566
429
|
const completeResponse = await this.completeArtifactUpload(request.workspaceId, createJobResponse.jobId, uploadResponse.uploadId);
|
|
567
430
|
if (!completeResponse?.success) {
|
|
568
431
|
throw new Error('Failed to complete artifact upload');
|
|
569
432
|
}
|
|
570
|
-
this.logging.log('DEBUG-ATX-START: Step 5 - Successfully completed artifact upload');
|
|
571
433
|
// Step 6: Start the transformation job
|
|
572
|
-
this.logging.log('DEBUG-ATX-START: Step 6 - Starting transformation job');
|
|
573
434
|
const startJobResponse = await this.startJob(request.workspaceId, createJobResponse.jobId);
|
|
574
435
|
if (!startJobResponse?.success) {
|
|
575
436
|
throw new Error('Failed to start ATX transformation job');
|
|
576
437
|
}
|
|
577
|
-
this.logging.log('
|
|
578
|
-
this.logging.log('DEBUG-ATX-START: Full workflow completed successfully!');
|
|
438
|
+
this.logging.log('ATX: Transform workflow completed successfully');
|
|
579
439
|
return {
|
|
580
440
|
TransformationJobId: createJobResponse.jobId,
|
|
581
441
|
ArtifactPath: zipFilePath,
|
|
@@ -583,16 +443,13 @@ class ATXTransformHandler {
|
|
|
583
443
|
};
|
|
584
444
|
}
|
|
585
445
|
catch (error) {
|
|
586
|
-
this.logging.error(`
|
|
446
|
+
this.logging.error(`ATX: StartTransform workflow error: ${String(error)}`);
|
|
587
447
|
return null;
|
|
588
448
|
}
|
|
589
449
|
}
|
|
590
|
-
async sleep(duration = 0) {
|
|
591
|
-
return new Promise(r => setTimeout(r, Math.max(duration, 0)));
|
|
592
|
-
}
|
|
593
450
|
async getJob(workspaceId, jobId) {
|
|
594
451
|
try {
|
|
595
|
-
this.logging.log(`Getting job: ${jobId} in workspace: ${workspaceId}`);
|
|
452
|
+
this.logging.log(`ATX: Getting job: ${jobId} in workspace: ${workspaceId}`);
|
|
596
453
|
if (!this.atxClient && !(await this.initializeAtxClient())) {
|
|
597
454
|
this.logging.error('ATX: GetJob client not initialized');
|
|
598
455
|
return null;
|
|
@@ -604,7 +461,7 @@ class ATXTransformHandler {
|
|
|
604
461
|
});
|
|
605
462
|
await this.addAuthToCommand(command);
|
|
606
463
|
const response = await this.atxClient.send(command);
|
|
607
|
-
this.logging.log(`ATX: GetJob
|
|
464
|
+
this.logging.log(`ATX: GetJob completed - Job status: ${response.job?.statusDetails?.status}`);
|
|
608
465
|
return response.job || null;
|
|
609
466
|
}
|
|
610
467
|
catch (error) {
|
|
@@ -614,7 +471,7 @@ class ATXTransformHandler {
|
|
|
614
471
|
}
|
|
615
472
|
async createArtifactDownloadUrl(workspaceId, jobId, artifactId) {
|
|
616
473
|
try {
|
|
617
|
-
this.logging.log(`
|
|
474
|
+
this.logging.log(`ATX: Starting CreateArtifactDownloadUrl for job: ${jobId}`);
|
|
618
475
|
if (!this.atxClient && !(await this.initializeAtxClient())) {
|
|
619
476
|
throw new Error('ATX client not initialized');
|
|
620
477
|
}
|
|
@@ -626,7 +483,7 @@ class ATXTransformHandler {
|
|
|
626
483
|
await this.addAuthToCommand(command);
|
|
627
484
|
const result = (await this.atxClient.send(command));
|
|
628
485
|
if (result && result.s3PreSignedUrl) {
|
|
629
|
-
this.logging.log(`ATX:
|
|
486
|
+
this.logging.log(`ATX: CreateArtifactDownloadUrl completed successfully`);
|
|
630
487
|
const normalizedHeaders = {};
|
|
631
488
|
if (result.requestHeaders) {
|
|
632
489
|
for (const [key, value] of Object.entries(result.requestHeaders)) {
|
|
@@ -639,21 +496,20 @@ class ATXTransformHandler {
|
|
|
639
496
|
};
|
|
640
497
|
}
|
|
641
498
|
else {
|
|
642
|
-
this.logging.error('ATX:
|
|
499
|
+
this.logging.error('ATX: CreateArtifactDownloadUrl failed - missing s3PreSignedUrl');
|
|
643
500
|
return null;
|
|
644
501
|
}
|
|
645
502
|
}
|
|
646
503
|
catch (error) {
|
|
647
|
-
this.logging.error(`
|
|
504
|
+
this.logging.error(`ATX: CreateArtifactDownloadUrl error: ${String(error)}`);
|
|
648
505
|
return null;
|
|
649
506
|
}
|
|
650
507
|
}
|
|
651
508
|
async listHitls(workspaceId, jobId) {
|
|
652
509
|
try {
|
|
653
|
-
this.logging.log(
|
|
654
|
-
this.logging.log(`Listing Hitls for job: ${jobId} in workspace: ${workspaceId}`);
|
|
510
|
+
this.logging.log(`ATX: Starting ListHitls for job: ${jobId}`);
|
|
655
511
|
if (!this.atxClient && !(await this.initializeAtxClient())) {
|
|
656
|
-
this.logging.error('
|
|
512
|
+
this.logging.error('ATX: Failed to initialize client for ListHitls');
|
|
657
513
|
return null;
|
|
658
514
|
}
|
|
659
515
|
const command = new elastic_gumby_frontend_client_1.ListHitlTasksCommand({
|
|
@@ -666,20 +522,19 @@ class ATXTransformHandler {
|
|
|
666
522
|
});
|
|
667
523
|
await this.addAuthToCommand(command);
|
|
668
524
|
const result = await this.atxClient.send(command);
|
|
669
|
-
this.logging.log(`
|
|
525
|
+
this.logging.log(`ATX: ListHitls completed - Found ${result.hitlTasks?.length || 0} tasks`);
|
|
670
526
|
return result.hitlTasks || [];
|
|
671
527
|
}
|
|
672
528
|
catch (error) {
|
|
673
|
-
this.logging.error(`ListHitls error: ${String(error)}`);
|
|
529
|
+
this.logging.error(`ATX: ListHitls error: ${String(error)}`);
|
|
674
530
|
return null;
|
|
675
531
|
}
|
|
676
532
|
}
|
|
677
533
|
async submitHitl(workspaceId, jobId, taskId, humanArtifactId) {
|
|
678
534
|
try {
|
|
679
|
-
this.logging.log(
|
|
680
|
-
this.logging.log(`Updating Hitl: ${taskId} for job: ${jobId} in workspace: ${workspaceId}`);
|
|
535
|
+
this.logging.log(`ATX: Starting SubmitHitl for task: ${taskId}`);
|
|
681
536
|
if (!this.atxClient && !(await this.initializeAtxClient())) {
|
|
682
|
-
this.logging.error('
|
|
537
|
+
this.logging.error('ATX: Failed to initialize client for SubmitHitl');
|
|
683
538
|
return null;
|
|
684
539
|
}
|
|
685
540
|
const command = new elastic_gumby_frontend_client_1.SubmitCriticalHitlTaskCommand({
|
|
@@ -693,20 +548,19 @@ class ATXTransformHandler {
|
|
|
693
548
|
});
|
|
694
549
|
await this.addAuthToCommand(command);
|
|
695
550
|
const result = await this.atxClient.send(command);
|
|
696
|
-
this.logging.log(`
|
|
551
|
+
this.logging.log(`ATX: SubmitHitl completed - task status: ${result.status || 'UNKNOWN'}`);
|
|
697
552
|
return result;
|
|
698
553
|
}
|
|
699
554
|
catch (error) {
|
|
700
|
-
this.logging.error(`
|
|
555
|
+
this.logging.error(`ATX: SubmitHitl error: ${String(error)}`);
|
|
701
556
|
return null;
|
|
702
557
|
}
|
|
703
558
|
}
|
|
704
559
|
async getHitl(workspaceId, jobId, taskId) {
|
|
705
560
|
try {
|
|
706
|
-
this.logging.log(
|
|
707
|
-
this.logging.log(`Getting Hitl: ${jobId} in workspace: ${workspaceId}`);
|
|
561
|
+
this.logging.log(`ATX: Getting Hitl task: ${taskId}`);
|
|
708
562
|
if (!this.atxClient && !(await this.initializeAtxClient())) {
|
|
709
|
-
this.logging.error('
|
|
563
|
+
this.logging.error('ATX: Failed to initialize client for GetHitl');
|
|
710
564
|
return null;
|
|
711
565
|
}
|
|
712
566
|
const command = new elastic_gumby_frontend_client_1.GetHitlTaskCommand({
|
|
@@ -716,63 +570,56 @@ class ATXTransformHandler {
|
|
|
716
570
|
});
|
|
717
571
|
await this.addAuthToCommand(command);
|
|
718
572
|
const result = await this.atxClient.send(command);
|
|
719
|
-
this.logging.log(`
|
|
573
|
+
this.logging.log(`ATX: GetHitl completed successfully`);
|
|
720
574
|
return result.task || null;
|
|
721
575
|
}
|
|
722
576
|
catch (error) {
|
|
723
|
-
this.logging.error(`GetHitl error: ${String(error)}`);
|
|
577
|
+
this.logging.error(`ATX: GetHitl error: ${String(error)}`);
|
|
724
578
|
return null;
|
|
725
579
|
}
|
|
726
580
|
}
|
|
727
581
|
async pollHitlTask(workspaceId, jobId, taskId) {
|
|
728
|
-
this.logging.log('Starting polling for hitl after upload');
|
|
582
|
+
this.logging.log('ATX: Starting polling for hitl after upload');
|
|
729
583
|
try {
|
|
730
584
|
var count = 0;
|
|
731
585
|
while (count < 100) {
|
|
732
586
|
const jobStatus = await this.getHitl(workspaceId, jobId, taskId);
|
|
733
|
-
this.logging.log(`Hitl
|
|
587
|
+
this.logging.log(`ATX: Hitl polling status: ${jobStatus?.status}`);
|
|
734
588
|
if (jobStatus && jobStatus.status == 'CLOSED') {
|
|
735
|
-
this.logging.log('Hitl Polling get status CLOSED');
|
|
736
589
|
return 'Validation Success!';
|
|
737
590
|
}
|
|
738
591
|
else if (jobStatus && jobStatus.status == 'CLOSED_PENDING_NEXT_TASK') {
|
|
739
|
-
// Fallback to placeholder if API call fails
|
|
740
|
-
this.logging.log('Hitl Polling get status CLOSED_PENDING_NEXT_TASK');
|
|
741
592
|
return 'Submitted plan did not pass validation, please check the plan for details....';
|
|
742
593
|
}
|
|
743
594
|
else if (jobStatus && jobStatus.status == 'CANCELLED') {
|
|
744
|
-
// Fallback to placeholder if API call fails
|
|
745
|
-
this.logging.log('Hitl Polling get status CANCELLED');
|
|
746
595
|
return 'Timeout occured during planning, proceeding with default plan....';
|
|
747
596
|
}
|
|
748
597
|
else {
|
|
749
|
-
|
|
750
|
-
await this.sleep(10 * 1000);
|
|
598
|
+
await utils_1.Utils.sleep(10 * 1000);
|
|
751
599
|
count++;
|
|
752
600
|
}
|
|
753
601
|
}
|
|
754
|
-
this.logging.log('
|
|
602
|
+
this.logging.log('ATX: Hitl polling timeout after 100 attempts');
|
|
755
603
|
return null;
|
|
756
604
|
}
|
|
757
605
|
catch (error) {
|
|
758
|
-
this.logging.error(`Hitl polling error: ${String(error)}`);
|
|
606
|
+
this.logging.error(`ATX: Hitl polling error: ${String(error)}`);
|
|
759
607
|
return null;
|
|
760
608
|
}
|
|
761
609
|
}
|
|
762
610
|
async getHitlAgentArtifact(workspaceId, jobId, solutionRootPath) {
|
|
763
611
|
try {
|
|
764
|
-
this.logging.log(
|
|
765
|
-
this.logging.log(`Getting Hitl Agent Artifact: ${jobId} in workspace: ${workspaceId}`);
|
|
612
|
+
this.logging.log(`ATX: Getting Hitl Agent Artifact for job: ${jobId}`);
|
|
766
613
|
if (!this.atxClient && !(await this.initializeAtxClient())) {
|
|
767
|
-
this.logging.error('
|
|
614
|
+
this.logging.error('ATX: Failed to initialize client for GetHitlAgentArtifact');
|
|
768
615
|
return null;
|
|
769
616
|
}
|
|
770
617
|
const hitls = await this.listHitls(workspaceId, jobId);
|
|
771
618
|
if (hitls && hitls.length != 1) {
|
|
772
|
-
this.logging.log(`ATX
|
|
619
|
+
this.logging.log(`ATX: Found ${hitls.length} hitls (expected 1)`);
|
|
773
620
|
}
|
|
774
621
|
else if (!hitls) {
|
|
775
|
-
this.logging.
|
|
622
|
+
this.logging.error(`ATX: No hitls available for download`);
|
|
776
623
|
throw new Error('no or many HITLE_FROM_USER artifacts available for download (expects 1 artifact)');
|
|
777
624
|
}
|
|
778
625
|
const hitl = hitls[0];
|
|
@@ -781,15 +628,15 @@ class ATXTransformHandler {
|
|
|
781
628
|
if (!downloadInfo) {
|
|
782
629
|
throw new Error('Failed to get ATX FES download URL');
|
|
783
630
|
}
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
await this.downloadAndExtractArchive(downloadInfo.s3PresignedUrl, downloadInfo.requestHeaders, pathToDownload, 'transformation-plan-download.zip');
|
|
631
|
+
const pathToDownload = path.join(solutionRootPath, utils_1.workspaceFolderName, jobId);
|
|
632
|
+
await utils_1.Utils.downloadAndExtractArchive(downloadInfo.s3PresignedUrl, downloadInfo.requestHeaders, pathToDownload, 'transformation-plan-download.zip', this.logging);
|
|
787
633
|
const planPath = path.join(pathToDownload, 'transformation-plan.md');
|
|
788
634
|
const reportPath = path.join(pathToDownload, 'assessment-report.md');
|
|
635
|
+
this.logging.log(`ATX: GetHitlAgentArtifact completed successfully`);
|
|
789
636
|
return { PlanPath: planPath, ReportPath: reportPath };
|
|
790
637
|
}
|
|
791
638
|
catch (error) {
|
|
792
|
-
this.logging.error(`GetHitlAgentArtifact error: ${String(error)}`);
|
|
639
|
+
this.logging.error(`ATX: GetHitlAgentArtifact error: ${String(error)}`);
|
|
793
640
|
return null;
|
|
794
641
|
}
|
|
795
642
|
}
|
|
@@ -798,15 +645,14 @@ class ATXTransformHandler {
|
|
|
798
645
|
*/
|
|
799
646
|
async getTransformInfo(request) {
|
|
800
647
|
try {
|
|
801
|
-
this.logging.log(`
|
|
648
|
+
this.logging.log(`ATX: Getting transform info for job: ${request.TransformationJobId}`);
|
|
802
649
|
const job = await this.getJob(request.WorkspaceId, request.TransformationJobId);
|
|
803
650
|
if (!job) {
|
|
804
|
-
this.logging.
|
|
651
|
+
this.logging.error(`ATX: Job not found: ${request.TransformationJobId}`);
|
|
805
652
|
return null;
|
|
806
653
|
}
|
|
807
654
|
const jobStatus = job.statusDetails?.status;
|
|
808
655
|
if (jobStatus === 'COMPLETED') {
|
|
809
|
-
this.logging.log(`DEBUG-ATX-GET-INFO: Job completed successfully`);
|
|
810
656
|
const pathToArtifact = await this.downloadFinalArtifact(request.WorkspaceId, request.TransformationJobId, request.SolutionRootPath);
|
|
811
657
|
const plan = await this.getTransformationPlan(request.WorkspaceId, request.TransformationJobId, request.SolutionRootPath);
|
|
812
658
|
return {
|
|
@@ -820,7 +666,6 @@ class ATXTransformHandler {
|
|
|
820
666
|
};
|
|
821
667
|
}
|
|
822
668
|
else if (jobStatus === 'FAILED') {
|
|
823
|
-
this.logging.log(`DEBUG-ATX-GET-INFO: Job failed`);
|
|
824
669
|
return {
|
|
825
670
|
TransformationJob: {
|
|
826
671
|
WorkspaceId: request.WorkspaceId,
|
|
@@ -832,7 +677,6 @@ class ATXTransformHandler {
|
|
|
832
677
|
};
|
|
833
678
|
}
|
|
834
679
|
else if (jobStatus === 'STOPPING' || jobStatus === 'STOPPED') {
|
|
835
|
-
this.logging.log(`DEBUG-ATX-GET-INFO: Job stopping`);
|
|
836
680
|
return {
|
|
837
681
|
TransformationJob: {
|
|
838
682
|
WorkspaceId: request.WorkspaceId,
|
|
@@ -843,7 +687,6 @@ class ATXTransformHandler {
|
|
|
843
687
|
};
|
|
844
688
|
}
|
|
845
689
|
else if (jobStatus === 'PLANNED') {
|
|
846
|
-
this.logging.log(`DEBUG-ATX-GET-INFO: Job in PLANNED`);
|
|
847
690
|
const plan = await this.getTransformationPlan(request.WorkspaceId, request.TransformationJobId, request.SolutionRootPath);
|
|
848
691
|
return {
|
|
849
692
|
TransformationJob: {
|
|
@@ -855,7 +698,6 @@ class ATXTransformHandler {
|
|
|
855
698
|
};
|
|
856
699
|
}
|
|
857
700
|
else if (jobStatus === 'AWAITING_HUMAN_INPUT') {
|
|
858
|
-
this.logging.log(`DEBUG-ATX-GET-INFO: Job in AWAITING_HUMAN_INPUT`);
|
|
859
701
|
const response = await this.getHitlAgentArtifact(request.WorkspaceId, request.TransformationJobId, request.SolutionRootPath);
|
|
860
702
|
return {
|
|
861
703
|
TransformationJob: {
|
|
@@ -868,7 +710,6 @@ class ATXTransformHandler {
|
|
|
868
710
|
};
|
|
869
711
|
}
|
|
870
712
|
else {
|
|
871
|
-
this.logging.log(`DEBUG-ATX-GET-INFO: Job in PLANNING`);
|
|
872
713
|
await this.listWorklogs(request.WorkspaceId, request.TransformationJobId, request.SolutionRootPath);
|
|
873
714
|
return {
|
|
874
715
|
TransformationJob: {
|
|
@@ -880,46 +721,44 @@ class ATXTransformHandler {
|
|
|
880
721
|
}
|
|
881
722
|
}
|
|
882
723
|
catch (error) {
|
|
883
|
-
this.logging.error(`ATX:
|
|
724
|
+
this.logging.error(`ATX: GetTransformInfo error: ${String(error)}`);
|
|
884
725
|
return null;
|
|
885
726
|
}
|
|
886
727
|
}
|
|
887
728
|
async uploadPlan(request) {
|
|
888
|
-
this.logging.
|
|
729
|
+
this.logging.log('ATX: Starting upload plan');
|
|
889
730
|
if (!this.cachedHitl) {
|
|
890
731
|
this.logging.error('ATX: UploadPlan error: No cached hitl');
|
|
891
732
|
return null;
|
|
892
733
|
}
|
|
893
734
|
try {
|
|
894
|
-
const pathToZip = path.join(path.dirname(request.PlanPath), 'transformation-plan-upload.
|
|
895
|
-
await
|
|
735
|
+
const pathToZip = path.join(path.dirname(request.PlanPath), 'transformation-plan-upload.zip');
|
|
736
|
+
await utils_1.Utils.zipFile(request.PlanPath, pathToZip);
|
|
896
737
|
const uploadInfo = await this.createArtifactUploadUrl(request.WorkspaceId, request.TransformationJobId, pathToZip, elastic_gumby_frontend_client_1.CategoryType.HITL_FROM_USER, elastic_gumby_frontend_client_1.FileType.ZIP);
|
|
897
738
|
if (!uploadInfo) {
|
|
898
|
-
this.logging.error('ATX: UploadPlan error: Failed to get
|
|
739
|
+
this.logging.error('ATX: UploadPlan error: Failed to get upload URL');
|
|
899
740
|
return null;
|
|
900
741
|
}
|
|
901
|
-
|
|
902
|
-
const uploadSuccess = await this.uploadArtifact(uploadInfo.uploadUrl, pathToZip, uploadInfo.requestHeaders);
|
|
742
|
+
const uploadSuccess = await utils_1.Utils.uploadArtifact(uploadInfo.uploadUrl, pathToZip, uploadInfo.requestHeaders, this.logging);
|
|
903
743
|
if (!uploadSuccess) {
|
|
904
744
|
throw new Error('Failed to upload ZIP file to S3');
|
|
905
|
-
return null;
|
|
906
745
|
}
|
|
907
746
|
const completeResponse = await this.completeArtifactUpload(request.WorkspaceId, request.TransformationJobId, uploadInfo.uploadId);
|
|
908
747
|
if (!completeResponse?.success) {
|
|
909
748
|
throw new Error('Failed to complete artifact upload');
|
|
910
749
|
}
|
|
911
|
-
this.logging.
|
|
750
|
+
this.logging.log('ATX: Plan uploaded, submitting hitl');
|
|
912
751
|
const submitHitl = await this.submitHitl(request.WorkspaceId, request.TransformationJobId, this.cachedHitl, uploadInfo.uploadId);
|
|
913
752
|
if (!submitHitl) {
|
|
914
753
|
throw new Error('Failed to submit hitl');
|
|
915
754
|
}
|
|
916
|
-
this.logging.
|
|
755
|
+
this.logging.log('ATX: Hitl submitted, polling for status');
|
|
917
756
|
const validation = await this.pollHitlTask(request.WorkspaceId, request.TransformationJobId, this.cachedHitl);
|
|
918
757
|
if (!validation) {
|
|
919
758
|
throw new Error('Failed to poll hitl task');
|
|
920
759
|
}
|
|
921
760
|
if (validation === 'Submitted plan did not pass validation, please check the plan for details....') {
|
|
922
|
-
const response = await this.getHitlAgentArtifact(request.WorkspaceId, request.TransformationJobId, path.dirname(request.PlanPath));
|
|
761
|
+
const response = await this.getHitlAgentArtifact(request.WorkspaceId, request.TransformationJobId, path.dirname(path.dirname(path.dirname(request.PlanPath))));
|
|
923
762
|
return {
|
|
924
763
|
VerificationStatus: false,
|
|
925
764
|
Message: validation,
|
|
@@ -965,37 +804,32 @@ class ATXTransformHandler {
|
|
|
965
804
|
}
|
|
966
805
|
async downloadFinalArtifact(workspaceId, jobId, solutionRootPath) {
|
|
967
806
|
try {
|
|
968
|
-
this.logging.log(
|
|
969
|
-
this.logging.log(`Called with jobId: ${jobId}, solutionRootPath: ${solutionRootPath}`);
|
|
970
|
-
this.logging.log(`Listing CUSTOMER_OUTPUT artifacts for job: ${jobId}`);
|
|
807
|
+
this.logging.log(`ATX: Starting download final artifact for job: ${jobId}`);
|
|
971
808
|
const artifacts = await this.listArtifacts(workspaceId, jobId);
|
|
972
809
|
if (!artifacts || artifacts.length === 0) {
|
|
973
810
|
throw new Error('No CUSTOMER_OUTPUT artifacts available for download');
|
|
974
811
|
}
|
|
975
812
|
const artifact = artifacts[0];
|
|
976
813
|
const artifactId = artifact.artifactId;
|
|
977
|
-
this.logging.log(`Found artifact: ${artifactId}, size: ${artifact.sizeInBytes} bytes`);
|
|
978
|
-
this.logging.log(`Creating download URL for artifactId: ${artifactId}`);
|
|
814
|
+
this.logging.log(`ATX: Found artifact: ${artifactId}, size: ${artifact.sizeInBytes} bytes`);
|
|
979
815
|
const downloadInfo = await this.createArtifactDownloadUrl(workspaceId, jobId, artifactId);
|
|
980
816
|
if (!downloadInfo) {
|
|
981
817
|
throw new Error('Failed to get ATX FES download URL');
|
|
982
818
|
}
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
819
|
+
const pathToDownload = path.join(solutionRootPath, utils_1.workspaceFolderName, jobId);
|
|
820
|
+
await utils_1.Utils.downloadAndExtractArchive(downloadInfo.s3PresignedUrl, downloadInfo.requestHeaders, pathToDownload, 'ExportResultsArchive.zip', this.logging);
|
|
821
|
+
this.logging.log(`ATX: Download final artifact completed successfully`);
|
|
986
822
|
return pathToDownload;
|
|
987
823
|
}
|
|
988
824
|
catch (error) {
|
|
989
|
-
this.logging.error(`ATX
|
|
825
|
+
this.logging.error(`ATX: Download final artifact failed: ${String(error)}`);
|
|
990
826
|
return null;
|
|
991
827
|
}
|
|
992
828
|
}
|
|
993
829
|
async getTransformationPlan(workspaceId, jobId, solutionRootPath) {
|
|
994
|
-
this.logging.log('Using ATX FES for Transform profile - real ListJobPlanSteps');
|
|
995
830
|
try {
|
|
996
831
|
// Get real plan steps from ATX FES (only if job status >= PLANNED)
|
|
997
832
|
const planSteps = await this.getATXFESJobPlanSteps(workspaceId, jobId);
|
|
998
|
-
this.logging.log(`dbu ListWorklog all ${JSON.stringify(planSteps)}`);
|
|
999
833
|
if (planSteps) {
|
|
1000
834
|
this.logging.log(`ATX FES: Found ${planSteps.length} transformation steps`);
|
|
1001
835
|
// Sort steps by score (primary) and startTime (tiebreaker) to match RTS ordering
|
|
@@ -1008,7 +842,6 @@ class ATXTransformHandler {
|
|
|
1008
842
|
const timeB = b.startTime ? new Date(b.startTime).getTime() : 0;
|
|
1009
843
|
return timeA - timeB;
|
|
1010
844
|
});
|
|
1011
|
-
this.logging.log(`PlanSteps response: ` + JSON.stringify(planSteps));
|
|
1012
845
|
// Return in exact same format as RTS with all required fields
|
|
1013
846
|
const transformationPlan = {
|
|
1014
847
|
transformationSteps: planSteps.map((step, index) => {
|
|
@@ -1038,10 +871,8 @@ class ATXTransformHandler {
|
|
|
1038
871
|
substepStatus = 'IN_PROGRESS'; // No NOT_STARTED option in ProgressUpdate enum
|
|
1039
872
|
break;
|
|
1040
873
|
}
|
|
1041
|
-
this.logging.log(`this is progres update for step ${JSON.stringify(step)} and has substep is ${JSON.stringify(substep)}`);
|
|
1042
874
|
// Map nested progress updates (3rd level)
|
|
1043
875
|
const nestedProgressUpdates = (substep.substeps || []).map((nestedUpdate) => {
|
|
1044
|
-
this.logging.log(`Found nested progress update: ${nestedUpdate.stepName} with status: ${nestedUpdate.status}`);
|
|
1045
876
|
let nestedStatus = 'IN_PROGRESS';
|
|
1046
877
|
switch (nestedUpdate.status) {
|
|
1047
878
|
case 'SUCCEEDED':
|
|
@@ -1069,7 +900,6 @@ class ATXTransformHandler {
|
|
|
1069
900
|
stepId: nestedUpdate.stepId ?? undefined,
|
|
1070
901
|
};
|
|
1071
902
|
});
|
|
1072
|
-
this.logging.log(`Substep ${substep.stepName} has ${nestedProgressUpdates.length} nested progress updates`);
|
|
1073
903
|
return {
|
|
1074
904
|
name: substep.stepName || 'Unknown Substep',
|
|
1075
905
|
description: substep.description || '',
|
|
@@ -1095,7 +925,6 @@ class ATXTransformHandler {
|
|
|
1095
925
|
// Use ATX step data directly without hardcoded ordering
|
|
1096
926
|
const stepNumber = index + 1;
|
|
1097
927
|
const stepName = `Step ${stepNumber} - ${step.stepName || 'Unknown Step'}`;
|
|
1098
|
-
this.logging.log(`ATX Step ${stepNumber}: ${step.stepName} (${step.status} → ${mappedStatus}) with ${progressUpdates.length} substeps`);
|
|
1099
928
|
return {
|
|
1100
929
|
id: step.stepId || `step-${stepNumber}`,
|
|
1101
930
|
name: stepName,
|
|
@@ -1107,7 +936,7 @@ class ATXTransformHandler {
|
|
|
1107
936
|
};
|
|
1108
937
|
}
|
|
1109
938
|
catch (error) {
|
|
1110
|
-
this.logging.error(`ATX FES: Error mapping step ${index}: ${error
|
|
939
|
+
this.logging.error(`ATX FES: Error mapping step ${index}: ${String(error)}`);
|
|
1111
940
|
// Return a safe fallback step
|
|
1112
941
|
const stepNumber = index + 1;
|
|
1113
942
|
return {
|
|
@@ -1129,9 +958,6 @@ class ATXTransformHandler {
|
|
|
1129
958
|
this.logging.log(`ATX FES: Could not get worklog for workspaces: ${workspaceId}, job id: ${jobId}`);
|
|
1130
959
|
}
|
|
1131
960
|
this.logging.log(`ATX FES: Successfully mapped ${transformationPlan.transformationSteps?.length || 0} steps`);
|
|
1132
|
-
if (transformationPlan.transformationSteps?.[0]) {
|
|
1133
|
-
this.logging.log(`ATX FES: First step mapped - id: ${transformationPlan.transformationSteps[0].id}, name: ${transformationPlan.transformationSteps[0].name}`);
|
|
1134
|
-
}
|
|
1135
961
|
return transformationPlan;
|
|
1136
962
|
}
|
|
1137
963
|
else {
|
|
@@ -1142,7 +968,7 @@ class ATXTransformHandler {
|
|
|
1142
968
|
}
|
|
1143
969
|
}
|
|
1144
970
|
catch (error) {
|
|
1145
|
-
this.logging.error(`ATX FES getTransformationPlan error: ${error
|
|
971
|
+
this.logging.error(`ATX FES getTransformationPlan error: ${String(error)}`);
|
|
1146
972
|
// Return empty plan on error
|
|
1147
973
|
return {
|
|
1148
974
|
transformationSteps: [],
|
|
@@ -1156,7 +982,6 @@ class ATXTransformHandler {
|
|
|
1156
982
|
if (result) {
|
|
1157
983
|
const steps = result || [];
|
|
1158
984
|
this.logging.log(`ListJobPlanSteps: SUCCESS - Found ${steps.length} plan steps with substeps`);
|
|
1159
|
-
this.logging.log(`PlanSteps are ${JSON.stringify(result)}`);
|
|
1160
985
|
return steps;
|
|
1161
986
|
}
|
|
1162
987
|
return null;
|
|
@@ -1171,9 +996,9 @@ class ATXTransformHandler {
|
|
|
1171
996
|
*/
|
|
1172
997
|
async listJobPlanSteps(workspaceId, jobId) {
|
|
1173
998
|
try {
|
|
1174
|
-
this.logging.log(
|
|
999
|
+
this.logging.log(`ATX: Starting ListJobPlanSteps for job: ${jobId}`);
|
|
1175
1000
|
if (!this.atxClient && !(await this.initializeAtxClient())) {
|
|
1176
|
-
this.logging.error('
|
|
1001
|
+
this.logging.error('ATX: Failed to initialize client for ListJobPlanSteps');
|
|
1177
1002
|
return null;
|
|
1178
1003
|
}
|
|
1179
1004
|
// Get root steps first
|
|
@@ -1181,7 +1006,6 @@ class ATXTransformHandler {
|
|
|
1181
1006
|
if (rootSteps && rootSteps.length > 0) {
|
|
1182
1007
|
// For each root step, get its substeps
|
|
1183
1008
|
for (const step of rootSteps) {
|
|
1184
|
-
this.logging.log(`Getting substeps for step: ${step.stepName} (ID: ${step.stepId})`);
|
|
1185
1009
|
const substeps = await this.getStepsRecursive(workspaceId, jobId, step.stepId);
|
|
1186
1010
|
step.substeps = substeps || [];
|
|
1187
1011
|
// Sort substeps by score (primary) and startTime (tiebreaker) to match RTS ordering
|
|
@@ -1196,7 +1020,6 @@ class ATXTransformHandler {
|
|
|
1196
1020
|
return timeA - timeB;
|
|
1197
1021
|
});
|
|
1198
1022
|
for (const substep of step.substeps) {
|
|
1199
|
-
this.logging.log(`Getting superSubstep for step: ${substep.stepName} (ID: ${substep.stepId})`);
|
|
1200
1023
|
const superSubsteps = await this.getStepsRecursive(workspaceId, jobId, substep.stepId);
|
|
1201
1024
|
substep.substeps = superSubsteps || [];
|
|
1202
1025
|
// Sort substeps by score (primary) and startTime (tiebreaker) to match RTS ordering
|
|
@@ -1211,31 +1034,17 @@ class ATXTransformHandler {
|
|
|
1211
1034
|
return timeA - timeB;
|
|
1212
1035
|
});
|
|
1213
1036
|
}
|
|
1214
|
-
this.logging.log(`Step ${substep.stepName}: Found ${substep.substeps.length} substeps`);
|
|
1215
|
-
// Log substep details for debugging
|
|
1216
|
-
if (substep.substeps.length > 0) {
|
|
1217
|
-
substep.substeps.forEach((superSubstep, index) => {
|
|
1218
|
-
this.logging.log(` SuperSubstep ${index + 1}: ${superSubstep.stepName} (${superSubstep.status || 'No status'})`);
|
|
1219
|
-
});
|
|
1220
|
-
}
|
|
1221
1037
|
}
|
|
1222
1038
|
}
|
|
1223
|
-
this.logging.log(`Step ${step.stepName}: Found ${step.substeps.length} substeps`);
|
|
1224
|
-
// Log substep details for debugging
|
|
1225
|
-
if (step.substeps.length > 0) {
|
|
1226
|
-
step.substeps.forEach((substep, index) => {
|
|
1227
|
-
this.logging.log(` Substep ${index + 1}: ${substep.stepName} (${substep.status || 'No status'})`);
|
|
1228
|
-
});
|
|
1229
|
-
}
|
|
1230
1039
|
}
|
|
1231
|
-
this.logging.log(`
|
|
1040
|
+
this.logging.log(`ATX: ListJobPlanSteps completed - Found ${rootSteps.length} steps with substeps`);
|
|
1232
1041
|
return rootSteps;
|
|
1233
1042
|
}
|
|
1234
|
-
this.logging.log('
|
|
1043
|
+
this.logging.log('ATX: ListJobPlanSteps - No root steps found');
|
|
1235
1044
|
return null;
|
|
1236
1045
|
}
|
|
1237
1046
|
catch (error) {
|
|
1238
|
-
this.logging.error(`ListJobPlanSteps error: ${error
|
|
1047
|
+
this.logging.error(`ATX: ListJobPlanSteps error: ${String(error)}`);
|
|
1239
1048
|
return null;
|
|
1240
1049
|
}
|
|
1241
1050
|
}
|
|
@@ -1253,13 +1062,12 @@ class ATXTransformHandler {
|
|
|
1253
1062
|
await this.addAuthToCommand(command);
|
|
1254
1063
|
const result = await this.atxClient.send(command);
|
|
1255
1064
|
if (result && result.steps && result.steps.length > 0) {
|
|
1256
|
-
this.logging.log(`Found ${result.steps.length} steps for parent: ${parentStepId}`);
|
|
1257
1065
|
return result.steps;
|
|
1258
1066
|
}
|
|
1259
1067
|
return null;
|
|
1260
1068
|
}
|
|
1261
1069
|
catch (error) {
|
|
1262
|
-
this.logging.error(`Error getting steps for parent ${parentStepId}: ${error
|
|
1070
|
+
this.logging.error(`Error getting steps for parent ${parentStepId}: ${String(error)}`);
|
|
1263
1071
|
return null;
|
|
1264
1072
|
}
|
|
1265
1073
|
}
|
|
@@ -1268,10 +1076,9 @@ class ATXTransformHandler {
|
|
|
1268
1076
|
*/
|
|
1269
1077
|
async listArtifacts(workspaceId, jobId, filter = 'CUSTOMER_OUTPUT') {
|
|
1270
1078
|
try {
|
|
1271
|
-
this.logging.log(
|
|
1272
|
-
this.logging.log(`Listing artifacts for job: ${jobId} in workspace: ${workspaceId}`);
|
|
1079
|
+
this.logging.log(`ATX: Starting ListArtifacts for job: ${jobId}`);
|
|
1273
1080
|
if (!this.atxClient && !(await this.initializeAtxClient())) {
|
|
1274
|
-
this.logging.error('
|
|
1081
|
+
this.logging.error('ATX: Failed to initialize client for ListArtifacts');
|
|
1275
1082
|
return null;
|
|
1276
1083
|
}
|
|
1277
1084
|
const command = new elastic_gumby_frontend_client_1.ListArtifactsCommand({
|
|
@@ -1283,11 +1090,11 @@ class ATXTransformHandler {
|
|
|
1283
1090
|
});
|
|
1284
1091
|
await this.addAuthToCommand(command);
|
|
1285
1092
|
const result = await this.atxClient.send(command);
|
|
1286
|
-
this.logging.log(`
|
|
1093
|
+
this.logging.log(`ATX: ListArtifacts completed - Found ${result.artifacts?.length || 0} artifacts`);
|
|
1287
1094
|
return result.artifacts || [];
|
|
1288
1095
|
}
|
|
1289
1096
|
catch (error) {
|
|
1290
|
-
this.logging.error(`ListArtifacts error: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
1097
|
+
this.logging.error(`ATX: ListArtifacts error: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
1291
1098
|
return null;
|
|
1292
1099
|
}
|
|
1293
1100
|
}
|
|
@@ -1296,10 +1103,9 @@ class ATXTransformHandler {
|
|
|
1296
1103
|
*/
|
|
1297
1104
|
async listWorklogs(workspaceId, jobId, solutionRootPath, stepId) {
|
|
1298
1105
|
try {
|
|
1299
|
-
this.logging.log(
|
|
1300
|
-
this.logging.log(`Listing ListWorklog for job: ${jobId} in workspace: ${workspaceId}`);
|
|
1106
|
+
this.logging.log(`ATX: Starting ListWorklogs for job: ${jobId}`);
|
|
1301
1107
|
if (!this.atxClient && !(await this.initializeAtxClient())) {
|
|
1302
|
-
this.logging.error('
|
|
1108
|
+
this.logging.error('ATX: Failed to initialize client for ListWorklogs');
|
|
1303
1109
|
return null;
|
|
1304
1110
|
}
|
|
1305
1111
|
const command = new elastic_gumby_frontend_client_1.ListWorklogsCommand({
|
|
@@ -1315,122 +1121,18 @@ class ATXTransformHandler {
|
|
|
1315
1121
|
});
|
|
1316
1122
|
await this.addAuthToCommand(command);
|
|
1317
1123
|
const result = await this.atxClient.send(command);
|
|
1318
|
-
this.logging.log(`
|
|
1319
|
-
|
|
1320
|
-
result.worklogs?.forEach(async (value, index) => {
|
|
1124
|
+
this.logging.log(`ATX: ListWorklogs completed - Found ${result.worklogs?.length || 0} entries`);
|
|
1125
|
+
for (const value of result.worklogs || []) {
|
|
1321
1126
|
const currentStepId = value.attributeMap?.STEP_ID || stepId || 'Progress';
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
});
|
|
1127
|
+
await utils_1.Utils.saveWorklogsToJson(jobId, currentStepId, value.description || '', solutionRootPath);
|
|
1128
|
+
}
|
|
1325
1129
|
return result.worklogs || [];
|
|
1326
1130
|
}
|
|
1327
1131
|
catch (error) {
|
|
1328
|
-
this.logging.error(`
|
|
1132
|
+
this.logging.error(`ATX: ListWorklogs error: ${String(error)}`);
|
|
1329
1133
|
return null;
|
|
1330
1134
|
}
|
|
1331
1135
|
}
|
|
1332
|
-
/**
|
|
1333
|
-
* Saves worklogs to JSON file with stepId as key and description as value
|
|
1334
|
-
*/
|
|
1335
|
-
async saveWorklogsToJson(jobId, stepId, description, solutionRootPath) {
|
|
1336
|
-
try {
|
|
1337
|
-
const worklogDir = path.join(solutionRootPath, exports.ArtifactWorkspaceName, jobId);
|
|
1338
|
-
const worklogPath = path.join(worklogDir, 'worklogs.json');
|
|
1339
|
-
await this.directoryExists(worklogDir);
|
|
1340
|
-
let worklogData = {};
|
|
1341
|
-
// Read existing worklog if it exists
|
|
1342
|
-
if (fs.existsSync(worklogPath)) {
|
|
1343
|
-
const existingData = fs.readFileSync(worklogPath, 'utf8');
|
|
1344
|
-
worklogData = JSON.parse(existingData);
|
|
1345
|
-
}
|
|
1346
|
-
if (stepId == null) {
|
|
1347
|
-
stepId = 'Progress';
|
|
1348
|
-
}
|
|
1349
|
-
// Initialize array if stepId doesn't exist
|
|
1350
|
-
if (!worklogData[stepId]) {
|
|
1351
|
-
worklogData[stepId] = [];
|
|
1352
|
-
}
|
|
1353
|
-
// Add description if not already present
|
|
1354
|
-
if (!worklogData[stepId].includes(description)) {
|
|
1355
|
-
worklogData[stepId].push(description);
|
|
1356
|
-
}
|
|
1357
|
-
// Write back to file
|
|
1358
|
-
fs.writeFileSync(worklogPath, JSON.stringify(worklogData, null, 2));
|
|
1359
|
-
}
|
|
1360
|
-
catch (error) {
|
|
1361
|
-
this.logging.error(`Error saving worklog: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
1362
|
-
}
|
|
1363
|
-
}
|
|
1364
|
-
async downloadAndExtractArchive(downloadUrl, requestHeaders, saveToDir, exportName) {
|
|
1365
|
-
const response = await got_1.default.get(downloadUrl, {
|
|
1366
|
-
headers: requestHeaders || {},
|
|
1367
|
-
timeout: { request: 300000 }, // 5 minutes
|
|
1368
|
-
responseType: 'buffer',
|
|
1369
|
-
});
|
|
1370
|
-
// Save, extract, and return paths
|
|
1371
|
-
const buffer = [Buffer.from(response.body)];
|
|
1372
|
-
return await this.extractArchiveFromBuffer(exportName, buffer, saveToDir);
|
|
1373
|
-
}
|
|
1374
|
-
/**
|
|
1375
|
-
* Extracts ZIP archive from buffer using AdmZip
|
|
1376
|
-
*/
|
|
1377
|
-
async extractArchiveFromBuffer(exportName, buffer, saveToDir) {
|
|
1378
|
-
const pathToArchive = path.join(saveToDir, exportName);
|
|
1379
|
-
await this.directoryExists(saveToDir);
|
|
1380
|
-
await fs.writeFileSync(pathToArchive, Buffer.concat(buffer));
|
|
1381
|
-
const pathContainingArchive = path.dirname(pathToArchive);
|
|
1382
|
-
const zip = new AdmZip(pathToArchive);
|
|
1383
|
-
const zipEntries = zip.getEntries();
|
|
1384
|
-
await this.extractAllEntriesTo(pathContainingArchive, zipEntries);
|
|
1385
|
-
return pathContainingArchive;
|
|
1386
|
-
}
|
|
1387
|
-
async directoryExists(directoryPath) {
|
|
1388
|
-
try {
|
|
1389
|
-
await fs.promises.access(directoryPath);
|
|
1390
|
-
}
|
|
1391
|
-
catch (error) {
|
|
1392
|
-
this.logging.log(`Directory doesn't exist, creating it: ${directoryPath}`);
|
|
1393
|
-
await fs.promises.mkdir(directoryPath, { recursive: true });
|
|
1394
|
-
}
|
|
1395
|
-
}
|
|
1396
|
-
/**
|
|
1397
|
-
* Extracts all ZIP entries to target directory
|
|
1398
|
-
*/
|
|
1399
|
-
async extractAllEntriesTo(pathContainingArchive, zipEntries) {
|
|
1400
|
-
for (const entry of zipEntries) {
|
|
1401
|
-
try {
|
|
1402
|
-
const entryPath = path.join(pathContainingArchive, entry.entryName);
|
|
1403
|
-
if (entry.isDirectory) {
|
|
1404
|
-
await fs.promises.mkdir(entryPath, { recursive: true });
|
|
1405
|
-
}
|
|
1406
|
-
else {
|
|
1407
|
-
const parentDir = path.dirname(entryPath);
|
|
1408
|
-
await fs.promises.mkdir(parentDir, { recursive: true });
|
|
1409
|
-
await fs.promises.writeFile(entryPath, entry.getData());
|
|
1410
|
-
}
|
|
1411
|
-
}
|
|
1412
|
-
catch (extractError) {
|
|
1413
|
-
if (extractError instanceof Error && 'code' in extractError && extractError.code === 'ENOENT') {
|
|
1414
|
-
this.logging.log(`Attempted to extract a file that does not exist: ${entry.entryName}`);
|
|
1415
|
-
}
|
|
1416
|
-
else {
|
|
1417
|
-
throw extractError;
|
|
1418
|
-
}
|
|
1419
|
-
}
|
|
1420
|
-
}
|
|
1421
|
-
}
|
|
1422
|
-
async zipFile(sourceFilePath, outputZipPath) {
|
|
1423
|
-
const archive = archiver('zip', { zlib: { level: 9 } });
|
|
1424
|
-
const stream = fs.createWriteStream(outputZipPath);
|
|
1425
|
-
return new Promise((resolve, reject) => {
|
|
1426
|
-
archive
|
|
1427
|
-
.file(sourceFilePath, { name: path.basename(sourceFilePath) })
|
|
1428
|
-
.on('error', err => reject(err))
|
|
1429
|
-
.pipe(stream);
|
|
1430
|
-
stream.on('close', () => resolve());
|
|
1431
|
-
void archive.finalize();
|
|
1432
|
-
});
|
|
1433
|
-
}
|
|
1434
1136
|
}
|
|
1435
1137
|
exports.ATXTransformHandler = ATXTransformHandler;
|
|
1436
1138
|
//# sourceMappingURL=atxTransformHandler.js.map
|