Skip to content

Commit 0cdc441

Browse files
committed
fix: automating edge config creation on s3
2 parents 5cc5fd7 + 83aac56 commit 0cdc441

File tree

16 files changed

+242
-28
lines changed

16 files changed

+242
-28
lines changed

package-lock.json

Lines changed: 24 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/spacecat-shared-data-access/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
# [@adobe/spacecat-shared-data-access-v2.93.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v2.92.1...@adobe/spacecat-shared-data-access-v2.93.0) (2026-01-08)
2+
3+
4+
### Features
5+
6+
* propagate traceId across workers for cross-worker tracing ([#1247](https://github.com/adobe/spacecat-shared/issues/1247)) ([f7d194d](https://github.com/adobe/spacecat-shared/commit/f7d194d2a8d23426c9dd66aae33f1118d226e827))
7+
18
# [@adobe/spacecat-shared-data-access-v2.92.1](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v2.92.0...@adobe/spacecat-shared-data-access-v2.92.1) (2026-01-07)
29

310

packages/spacecat-shared-data-access/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@adobe/spacecat-shared-data-access",
3-
"version": "2.92.1",
3+
"version": "2.93.0",
44
"description": "Shared modules of the Spacecat Services - Data Access",
55
"type": "module",
66
"engines": {

packages/spacecat-shared-data-access/src/models/audit/audit.model.js

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -194,17 +194,27 @@ class Audit extends BaseModel {
194194
* @param context - The context object.
195195
* @returns {object} - The formatted payload for the scrape client.
196196
*/
197-
formatPayload: (stepResult, auditContext, context) => ({
198-
urls: stepResult.urls.map((urlObj) => urlObj.url),
199-
processingType: stepResult.processingType || 'default',
200-
options: stepResult.options || {},
201-
maxScrapeAge: isNumber(stepResult.maxScrapeAge) ? stepResult.maxScrapeAge : 24,
202-
auditData: {
203-
siteId: stepResult.siteId,
204-
completionQueueUrl: stepResult.completionQueueUrl || context.env?.AUDIT_JOBS_QUEUE_URL,
205-
auditContext,
206-
},
207-
}),
197+
formatPayload: (stepResult, auditContext, context) => {
198+
const payload = {
199+
urls: stepResult.urls.map((urlObj) => urlObj.url),
200+
processingType: stepResult.processingType || 'default',
201+
options: stepResult.options || {},
202+
maxScrapeAge: isNumber(stepResult.maxScrapeAge) ? stepResult.maxScrapeAge : 24,
203+
auditData: {
204+
siteId: stepResult.siteId,
205+
completionQueueUrl: stepResult.completionQueueUrl || context.env?.AUDIT_JOBS_QUEUE_URL,
206+
auditContext,
207+
},
208+
};
209+
210+
// Propagate traceId for cross-worker tracing continuity
211+
// This allows the scrape client to maintain the same trace across multiple workers
212+
if (context.traceId) {
213+
payload.traceId = context.traceId;
214+
}
215+
216+
return payload;
217+
},
208218
},
209219
};
210220

packages/spacecat-shared-data-access/test/unit/models/audit/audit.model.test.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,5 +348,36 @@ describe('AuditModel', () => {
348348
},
349349
});
350350
});
351+
352+
it('formats scrape client payload with traceId when present in context', () => {
353+
const stepResult = {
354+
urls: [{ url: 'someUrl' }],
355+
siteId: 'someSiteId',
356+
options: { someOption: 'someValue' },
357+
processingType: 'someProcessingType',
358+
};
359+
const context = {
360+
env: {
361+
AUDIT_JOBS_QUEUE_URL: 'audit-jobs-queue-url',
362+
},
363+
traceId: '1-5e8e8e8e-5e8e8e8e5e8e8e8e5e8e8e8e',
364+
};
365+
const auditContext = { some: 'context' };
366+
const formattedPayload = auditStepDestinationConfigs[auditStepDestinations.SCRAPE_CLIENT]
367+
.formatPayload(stepResult, auditContext, context);
368+
369+
expect(formattedPayload).to.deep.equal({
370+
urls: ['someUrl'],
371+
options: { someOption: 'someValue' },
372+
processingType: 'someProcessingType',
373+
maxScrapeAge: 24,
374+
traceId: '1-5e8e8e8e-5e8e8e8e5e8e8e8e5e8e8e8e',
375+
auditData: {
376+
siteId: 'someSiteId',
377+
completionQueueUrl: 'audit-jobs-queue-url',
378+
auditContext: { some: 'context' },
379+
},
380+
});
381+
});
351382
});
352383
});

packages/spacecat-shared-ims-client/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
# [@adobe/spacecat-shared-ims-client-v1.11.8](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-ims-client-v1.11.7...@adobe/spacecat-shared-ims-client-v1.11.8) (2026-01-08)
2+
3+
4+
### Bug Fixes
5+
6+
* API to get all orgs for a user profile ([#1254](https://github.com/adobe/spacecat-shared/issues/1254)) ([4a0401c](https://github.com/adobe/spacecat-shared/commit/4a0401c73e372272b7055463a412be6ad691b615))
7+
18
# [@adobe/spacecat-shared-ims-client-v1.11.7](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-ims-client-v1.11.6...@adobe/spacecat-shared-ims-client-v1.11.7) (2025-11-30)
29

310

packages/spacecat-shared-ims-client/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@adobe/spacecat-shared-ims-client",
3-
"version": "1.11.7",
3+
"version": "1.11.8",
44
"description": "Shared modules of the Spacecat Services - IMS Client",
55
"type": "module",
66
"engines": {

packages/spacecat-shared-ims-client/src/clients/ims-client.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
IMS_VALIDATE_TOKEN_ENDPOINT,
2828
IMS_ADMIN_PROFILE_ENDPOINT,
2929
IMS_ACCOUNT_CLUSTER_ENDPOINT,
30+
IMS_ADMIN_ORGANIZATIONS_ENDPOINT,
3031
} from '../utils.js';
3132

3233
export default class ImsClient extends ImsBaseClient {
@@ -410,4 +411,39 @@ export default class ImsClient extends ImsBaseClient {
410411

411412
return accountClusterResponse.json();
412413
}
414+
415+
/**
416+
* Fetches list of organizations for a given IMS ID
417+
* @param {string} imsId - The IMS ID of the user
418+
* @returns {Promise<Object>} The user's profile data
419+
* @throws {Error} If the request fails
420+
*/
421+
async getImsAdminOrganizations(imsId) {
422+
if (!hasText(imsId)) {
423+
throw new Error('imsId param is required.');
424+
}
425+
426+
const { guid, authSource } = extractGuidAndAuthSource(imsId);
427+
const serviceToken = await this.getServiceAccessToken();
428+
429+
const formBody = `guid=${guid}&auth_src=${authSource}`;
430+
431+
const response = await fetch(
432+
`https://${this.config.imsHost}${IMS_ADMIN_ORGANIZATIONS_ENDPOINT}`,
433+
{
434+
method: 'POST',
435+
headers: {
436+
'Content-Type': 'application/x-www-form-urlencoded',
437+
Authorization: `Bearer ${serviceToken.access_token}`,
438+
},
439+
body: formBody,
440+
},
441+
);
442+
443+
if (!response.ok) {
444+
throw new Error(`IMS getImsAdminOrganizations request failed with status: ${response.status}`);
445+
}
446+
447+
return response.json();
448+
}
413449
}

packages/spacecat-shared-ims-client/src/utils.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export const IMS_PROFILE_ENDPOINT = '/ims/profile/v1';
2424
export const IMS_INVALIDATE_TOKEN_ENDPOINT = '/ims/invalidate_token/v2';
2525
export const IMS_ADMIN_PROFILE_ENDPOINT = '/ims/admin_profile/v3';
2626
export const IMS_ACCOUNT_CLUSTER_ENDPOINT = '/ims/account_cluster/v2';
27+
export const IMS_ADMIN_ORGANIZATIONS_ENDPOINT = '/ims/admin_organizations/v4';
2728
/**
2829
* Creates and populates a FormData object from key-value pairs.
2930
* @param {Object} fields - Object containing key-value pairs to append to FormData.

packages/spacecat-shared-ims-client/test/clients/ims-client.test.js

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,80 @@ describe('ImsClient', () => {
525525
});
526526
});
527527

528+
describe('getImsAdminOrganizations', () => {
529+
let client;
530+
const testImsId = '6E14161F62BEB2990A49401A@0b2414d95e6abf580a49403d';
531+
532+
beforeEach(() => {
533+
client = ImsClient.createFrom(mockContext);
534+
});
535+
536+
it('throws error when imsId is not provided', async () => {
537+
await expect(client.getImsAdminOrganizations())
538+
.to.be.rejectedWith('imsId param is required.');
539+
});
540+
541+
it('successfully fetches admin organizations', async () => {
542+
const mockAdminOrgs = [
543+
{
544+
orgRef: { ident: '1234567890ABCDEF12345678', authSrc: 'AdobeOrg' },
545+
orgName: 'Example Org',
546+
orgType: 'Enterprise',
547+
countryCode: 'US',
548+
},
549+
];
550+
551+
// Mock service token endpoint
552+
mockImsTokenResponse();
553+
554+
// Mock admin organizations endpoint
555+
nock(`https://${DUMMY_HOST}`)
556+
.post('/ims/admin_organizations/v4')
557+
.reply(200, mockAdminOrgs);
558+
559+
const result = await client.getImsAdminOrganizations(testImsId);
560+
expect(result).to.deep.equal(mockAdminOrgs);
561+
});
562+
563+
it('throws error when admin organizations request fails', async () => {
564+
// Mock service token endpoint
565+
mockImsTokenResponse();
566+
567+
// Mock failed admin organizations response
568+
nock(`https://${DUMMY_HOST}`)
569+
.post('/ims/admin_organizations/v4')
570+
.reply(404);
571+
572+
await expect(client.getImsAdminOrganizations(testImsId))
573+
.to.be.rejectedWith('IMS getImsAdminOrganizations request failed with status: 404');
574+
});
575+
576+
it('reuses existing service token if available', async () => {
577+
const mockAdminOrgs = [
578+
{
579+
orgRef: { ident: '1234567890ABCDEF12345678', authSrc: 'AdobeOrg' },
580+
orgName: 'Example Org',
581+
},
582+
];
583+
584+
// Set existing service token
585+
client.serviceAccessToken = {
586+
access_token: 'ZHVtbXktYWNjZXNzLXRva2Vu',
587+
expires_in: 86400,
588+
token_type: 'bearer',
589+
};
590+
591+
// Mock only admin organizations endpoint (token endpoint should not be called)
592+
nock(`https://${DUMMY_HOST}`)
593+
.post('/ims/admin_organizations/v4')
594+
.reply(200, mockAdminOrgs);
595+
596+
const result = await client.getImsAdminOrganizations(testImsId);
597+
expect(result).to.deep.equal(mockAdminOrgs);
598+
expect(nock.isDone()).to.be.true;
599+
});
600+
});
601+
528602
describe('getAccountCluster', () => {
529603
let client;
530604
const testAccessToken = 'eyJhbGciOiJIUzI1NiJ9.eyJpZCI6IjEyMzQ1IiwidHlwZSI6ImFjY2Vzc190b2tlbiIsImNsaWVudF9pZCI6ImV4YW1wbGVfYXBwIiwidXNlcl9pZCI6Ijk4NzY1NDc4OTBBQkNERUYxMjM0NTY3OEBhYmNkZWYxMjM0NTY3ODkuZSIsImFzIjoiaW1zLW5hMSIsImFhX2lkIjoiMTIzNDU2Nzg5MEFCQ0RFRjEyMzQ1Njc4QGFkb2JlLmNvbSIsImNyZWF0ZWRfYXQiOiIxNzEwMjQ3MDAwMDAwIn0.MRDpxgxSHDj4DmA182hPnjMAnKkly-VUJ_bXpQ-J8EQ';

0 commit comments

Comments
 (0)