From 4bc870531763421dc8f40122f2a754e9cfb573f2 Mon Sep 17 00:00:00 2001 From: kptdobe Date: Thu, 25 Sep 2025 16:41:30 +0200 Subject: [PATCH 1/3] feat: get rid of da-collab binding --- src/storage/utils/object.js | 8 +- test/routes/source.test.js | 35 ++++--- test/storage/object/copy.test.js | 163 +++++++++++++++++------------ test/storage/object/delete.test.js | 33 +++--- test/storage/utils/object.test.js | 43 +++++--- wrangler.toml | 12 --- 6 files changed, 161 insertions(+), 133 deletions(-) diff --git a/src/storage/utils/object.js b/src/storage/utils/object.js index a095e8a8..3f605e6f 100644 --- a/src/storage/utils/object.js +++ b/src/storage/utils/object.js @@ -15,9 +15,9 @@ export async function invalidateCollab(api, url, env) { return; } - const invPath = `/api/v1/${api}?doc=${url}`; + const { DA_COLLAB } = env; - // Use dacollab service binding, hostname is not relevant - const invURL = `https://localhost${invPath}`; - await env.dacollab.fetch(invURL); + const invURL = `${DA_COLLAB}/api/v1/${api}?doc=${url}`; + + await fetch(invURL); } diff --git a/test/routes/source.test.js b/test/routes/source.test.js index 52538b2e..2fd68a80 100644 --- a/test/routes/source.test.js +++ b/test/routes/source.test.js @@ -15,13 +15,9 @@ import esmock from 'esmock'; import { getAclCtx } from '../../src/utils/auth.js'; describe('Source Route', () => { - it('Test invalidate using service binding', async () => { - const sb_callbacks = []; - const dacollab = { - fetch: async (url) => sb_callbacks.push(url) - }; + it('Test invalidate using direct fetch', async () => { + const fetch_callbacks = []; const env = { - dacollab, DA_COLLAB: 'http://localhost:4444' }; @@ -39,17 +35,26 @@ describe('Source Route', () => { } }); - const headers = new Map(); - headers.set('x-da-initiator', 'blah'); + const savedFetch = globalThis.fetch; + try { + globalThis.fetch = async (url) => { + fetch_callbacks.push(url); + }; - const req = { - headers, - url: 'http://localhost:9876/source/somedoc.html' - }; + const headers = new Map(); + headers.set('x-da-initiator', 'blah'); - const resp = await postSource({ req, env, daCtx }); - assert.equal(200, resp.status); - assert.deepStrictEqual(['https://localhost/api/v1/syncadmin?doc=http://localhost:9876/source/somedoc.html'], sb_callbacks); + const req = { + headers, + url: 'http://localhost:9876/source/somedoc.html' + }; + + const resp = await postSource({ req, env, daCtx }); + assert.equal(200, resp.status); + assert.deepStrictEqual(['http://localhost:4444/api/v1/syncadmin?doc=http://localhost:9876/source/somedoc.html'], fetch_callbacks); + } finally { + globalThis.fetch = savedFetch; + } }); it('Test postSource from collab does not trigger invalidate callback', async () => { diff --git a/test/storage/object/copy.test.js b/test/storage/object/copy.test.js index 6a455b8b..e7630651 100644 --- a/test/storage/object/copy.test.js +++ b/test/storage/object/copy.test.js @@ -141,12 +141,7 @@ describe('Object copy', () => { })); const collabcalls = []; - const dacollab = { - fetch: (url) => { - collabcalls.push(url); - } - } - const env = { dacollab }; + const env = { DA_COLLAB: 'https://localhost' }; const ctx = { bucket: 'root-bucket', env, @@ -160,28 +155,38 @@ describe('Object copy', () => { source: 'mydir', destination: 'mydir/newdir', }; - await copyObject(env, ctx, details, false); - assert.strictEqual(s3Sent.length, 3); + const savedFetch = globalThis.fetch; + try { + globalThis.fetch = async (url) => { + collabcalls.push(url); + }; + + await copyObject(env, ctx, details, false); - // Make the order in s3Sent predictable - s3Sent.sort((a, b) => a.Key.localeCompare(b.Key)); + assert.strictEqual(s3Sent.length, 3); - const input = s3Sent[2]; - assert.strictEqual(input.Bucket, 'root-bucket'); - assert.strictEqual(input.CopySource, 'root-bucket/foo/mydir/xyz.html'); - assert.strictEqual(input.Key, 'foo/mydir/newdir/xyz.html'); + // Make the order in s3Sent predictable + s3Sent.sort((a, b) => a.Key.localeCompare(b.Key)); - const md = input.Metadata; - assert(md.ID, "ID should be set"); - assert(md.Version, "Version should be set"); - assert.strictEqual(typeof (md.Timestamp), 'string', 'Timestamp should be set as a string'); - assert.strictEqual(md.Users, '[{"email":"haha@foo.com"}]'); - assert.strictEqual(md.Path, 'mydir/newdir/xyz.html'); + const input = s3Sent[2]; + assert.strictEqual(input.Bucket, 'root-bucket'); + assert.strictEqual(input.CopySource, 'root-bucket/foo/mydir/xyz.html'); + assert.strictEqual(input.Key, 'foo/mydir/newdir/xyz.html'); - assert.strictEqual(1, collabcalls.length); - assert.deepStrictEqual(collabcalls, - ['https://localhost/api/v1/syncAdmin?doc=somehost.sometld/source/foo/mydir/newdir/xyz.html']); + const md = input.Metadata; + assert(md.ID, "ID should be set"); + assert(md.Version, "Version should be set"); + assert.strictEqual(typeof (md.Timestamp), 'string', 'Timestamp should be set as a string'); + assert.strictEqual(md.Users, '[{"email":"haha@foo.com"}]'); + assert.strictEqual(md.Path, 'mydir/newdir/xyz.html'); + + assert.strictEqual(1, collabcalls.length); + assert.deepStrictEqual(collabcalls, + ['https://localhost/api/v1/syncAdmin?doc=somehost.sometld/source/foo/mydir/newdir/xyz.html']); + } finally { + globalThis.fetch = savedFetch; + } }); it('Copies a file for rename', async () => { @@ -193,33 +198,38 @@ describe('Object copy', () => { })); const collabcalls = []; - const dacollab = { - fetch: (url) => { - collabcalls.push(url); - } - } - const env = { dacollab }; + const env = { DA_COLLAB: 'https://localhost' }; const ctx = { bucket: 'root-bucket', org: 'testorg', key: 'mydir/dir1', origin: 'http://localhost:3000' }; ctx.aclCtx = await getAclCtx(env, ctx.org, ctx.users, '/'); const details = { source: 'mydir/dir1', destination: 'mydir/dir2', }; - await copyObject(env, ctx, details, true); - assert.strictEqual(s3Sent.length, 3); + const savedFetch = globalThis.fetch; + try { + globalThis.fetch = async (url) => { + collabcalls.push(url); + }; + + await copyObject(env, ctx, details, true); - // Make the order in s3Sent predictable - s3Sent.sort((a, b) => a.Key.localeCompare(b.Key)); + assert.strictEqual(s3Sent.length, 3); - const input = s3Sent[2]; - assert.strictEqual(input.Bucket, 'root-bucket'); - assert.strictEqual(input.CopySource, 'root-bucket/testorg/mydir/dir1/myfile.html'); - assert.strictEqual(input.Key, 'testorg/mydir/dir2/myfile.html'); - assert.ifError(input.Metadata); + // Make the order in s3Sent predictable + s3Sent.sort((a, b) => a.Key.localeCompare(b.Key)); - assert.deepStrictEqual(collabcalls, - ['https://localhost/api/v1/syncAdmin?doc=http://localhost:3000/source/testorg/mydir/dir2/myfile.html']); + const input = s3Sent[2]; + assert.strictEqual(input.Bucket, 'root-bucket'); + assert.strictEqual(input.CopySource, 'root-bucket/testorg/mydir/dir1/myfile.html'); + assert.strictEqual(input.Key, 'testorg/mydir/dir2/myfile.html'); + assert.ifError(input.Metadata); + + assert.deepStrictEqual(collabcalls, + ['https://localhost/api/v1/syncAdmin?doc=http://localhost:3000/source/testorg/mydir/dir2/myfile.html']); + } finally { + globalThis.fetch = savedFetch; + } }); it('Adds copy condition', async () => { @@ -246,9 +256,7 @@ describe('Object copy', () => { const collabCalled = []; const env = { - dacollab: { - fetch: (x) => { collabCalled.push(x); }, - }, + DA_COLLAB: 'https://localhost', }; const daCtx = { bucket: 'root-bucket', @@ -261,7 +269,11 @@ describe('Object copy', () => { source: 'mysrc', destination: 'mydst', }; - const resp = await copyFile({}, env, daCtx, 'mysrc/abc/def.html', details, false); + + const savedFetch = globalThis.fetch; + try { + globalThis.fetch = async (x) => { collabCalled.push(x); }; + const resp = await copyFile({}, env, daCtx, 'mysrc/abc/def.html', details, false); assert.strictEqual(resp.constructor.name, 'CopyObjectCommand'); assert.strictEqual(resp.input.Bucket, 'root-bucket'); @@ -298,6 +310,9 @@ describe('Object copy', () => { assert.deepStrictEqual(collabCalled, ['https://localhost/api/v1/syncAdmin?doc=https://blahblah:7890/source/myorg/mydst/abc/def.html']); + } finally { + globalThis.fetch = savedFetch; + } }); it('Copy content when destination already exists', async () => { @@ -344,9 +359,7 @@ describe('Object copy', () => { const collabCalled = []; const env = { - dacollab: { - fetch: (x) => { collabCalled.push(x); }, - }, + DA_COLLAB: 'https://localhost', }; const daCtx = { bucket: 'mybucket', org: 'xorg' }; daCtx.aclCtx = await getAclCtx(env, daCtx.org, daCtx.users, '/'); @@ -354,17 +367,24 @@ describe('Object copy', () => { source: 'xsrc', destination: 'xdst', }; - const resp = await copyFile({}, env, daCtx, 'xsrc/abc/def.html', details, false); - assert.strictEqual(resp, 'beuaaark!'); - - assert.strictEqual(puwv.length, 1); - assert.strictEqual(puwv[0].c, daCtx); - assert.strictEqual(puwv[0].e, env); - assert.strictEqual(puwv[0].u.body, 'original body'); - assert.strictEqual(puwv[0].u.contentLength, 42); - assert.strictEqual(puwv[0].u.key, 'xdst/abc/def.html'); - assert.strictEqual(puwv[0].u.org, 'xorg'); - assert.strictEqual(puwv[0].u.type, 'text/html'); + + const savedFetch = globalThis.fetch; + try { + globalThis.fetch = async (x) => { collabCalled.push(x); }; + const resp = await copyFile({}, env, daCtx, 'xsrc/abc/def.html', details, false); + assert.strictEqual(resp, 'beuaaark!'); + + assert.strictEqual(puwv.length, 1); + assert.strictEqual(puwv[0].c, daCtx); + assert.strictEqual(puwv[0].e, env); + assert.strictEqual(puwv[0].u.body, 'original body'); + assert.strictEqual(puwv[0].u.contentLength, 42); + assert.strictEqual(puwv[0].u.key, 'xdst/abc/def.html'); + assert.strictEqual(puwv[0].u.org, 'xorg'); + assert.strictEqual(puwv[0].u.type, 'text/html'); + } finally { + globalThis.fetch = savedFetch; + } }); it('Copy content when origin does not exists', async () => { @@ -389,9 +409,7 @@ describe('Object copy', () => { const collabCalled = []; const env = { - dacollab: { - fetch: (x) => { collabCalled.push(x); }, - }, + DA_COLLAB: 'https://localhost', }; const daCtx = { org: 'qqqorg', origin: 'http://qqq' }; daCtx.aclCtx = await getAclCtx(env, daCtx.org, daCtx.users, '/'); @@ -399,10 +417,17 @@ describe('Object copy', () => { source: 'qqqsrc', destination: 'qqqdst', }; - const resp = await copyFile({}, env, daCtx, 'qqqsrc/abc/def.html', details, false); - assert.strictEqual(resp.$metadata, error.$metadata); - assert.deepStrictEqual(collabCalled, - ['https://localhost/api/v1/syncAdmin?doc=http://qqq/source/qqqorg/qqqdst/abc/def.html']); + + const savedFetch = globalThis.fetch; + try { + globalThis.fetch = async (x) => { collabCalled.push(x); }; + const resp = await copyFile({}, env, daCtx, 'qqqsrc/abc/def.html', details, false); + assert.strictEqual(resp.$metadata, error.$metadata); + assert.deepStrictEqual(collabCalled, + ['https://localhost/api/v1/syncAdmin?doc=http://qqq/source/qqqorg/qqqdst/abc/def.html']); + } finally { + globalThis.fetch = savedFetch; + } }); }); @@ -417,7 +442,7 @@ describe('Object copy', () => { s3Sent.push(input); })); - const env = { dacollab: { fetch: () => {} } }; + const env = { DA_COLLAB: 'https://localhost' }; const ctx = { org: 'foo', key: 'mydir', @@ -442,7 +467,7 @@ describe('Object copy', () => { DA_JOBS[key] = value; } }, - dacollab: { fetch: () => {} } + DA_COLLAB: 'https://localhost' } s3Mock.on(ListObjectsV2Command) .resolves({ @@ -498,7 +523,7 @@ describe('Object copy', () => { return DA_JOBS[key]; } }, - dacollab: { fetch: () => {} } + DA_COLLAB: 'https://localhost' } const ctx = { @@ -540,7 +565,7 @@ describe('Object copy', () => { delete DA_JOBS[key]; } }, - dacollab: { fetch: () => {} } + DA_COLLAB: 'https://localhost' } const ctx = { diff --git a/test/storage/object/delete.test.js b/test/storage/object/delete.test.js index 1c5572cf..d67b07ac 100644 --- a/test/storage/object/delete.test.js +++ b/test/storage/object/delete.test.js @@ -25,10 +25,8 @@ describe('Object delete', () => { describe('single context', () => { it('Delete a file', async () => { const collabCalled = [] - const dacollab = { fetch: (u) => collabCalled.push(u) }; - const client = {}; - const env = { dacollab }; + const env = { DA_COLLAB: 'https://localhost' }; const daCtx = { origin: 'https://admin.da.live', org: 'testorg', @@ -64,18 +62,23 @@ describe('Object delete', () => { const savedFetch = globalThis.fetch; try { globalThis.fetch = async (url, opts) => { - assert.equal(deleteURL, url); - assert.equal('DELETE', opts.method); - return { status: 204 }; + if (url === deleteURL) { + assert.equal('DELETE', opts.method); + return { status: 204 }; + } else { + // This is the collab invalidation call + collabCalled.push(url); + return { status: 200 }; + } }; const resp = await deleteObject(client, daCtx, 'foo/bar.html', env); assert.equal(204, resp.status); // assert.deepStrictEqual(['postObjectVersionWithLabel'], postObjVerCalled); - // assert.deepStrictEqual( - // ['https://localhost/api/v1/deleteadmin?doc=https://admin.da.live/source/testorg/foo/bar.html'], - // collabCalled - // ); + assert.deepStrictEqual( + ['https://localhost/api/v1/deleteadmin?doc=https://admin.da.live/source/testorg/foo/bar.html'], + collabCalled + ); } finally { globalThis.fetch = savedFetch; } @@ -234,10 +237,7 @@ describe('Object delete', () => { aclCtx: { pathLookup: new Map() }, }; const env = { - dacollab: { - fetch: () => { - } - }, + DA_COLLAB: 'https://localhost', }; const mockPostObjectVersion = async () => ({ status: 201 }); const mockSignedUrl = async () => 'http://localhost:8080/test/'; @@ -264,10 +264,7 @@ describe('Object delete', () => { aclCtx: { pathLookup: new Map() }, }; const env = { - dacollab: { - fetch: () => { - } - }, + DA_COLLAB: 'https://localhost', }; const mockPostObjectVersion = async () => ({ status: 201 }); const mockSignedUrl = async () => 'http://localhost:8080/test/'; diff --git a/test/storage/utils/object.test.js b/test/storage/utils/object.test.js index 52a1e9cc..078fa670 100644 --- a/test/storage/utils/object.test.js +++ b/test/storage/utils/object.test.js @@ -17,31 +17,44 @@ import { invalidateCollab } from '../../../src/storage/utils/object.js'; describe('Storage Object Utils tests', () => { function setupEnv() { const called = []; - const dacollab = { - fetch: async (url) => { - console.log(`invalidate called with ${url}`); - called.push(url); - }, - }; - const env = { dacollab }; + const env = { DA_COLLAB: 'https://localhost' }; return { called, env }; } it('Should invalidate', async () => { const { called, env } = setupEnv(); - assert.strictEqual(called.length, 0, 'precondition'); - await invalidateCollab('syncAdmin', 'https://admin.da.live/source/a/b/c.html', env); - assert.strictEqual(called.length, 1); - assert.strictEqual(called[0], 'https://localhost/api/v1/syncAdmin?doc=https://admin.da.live/source/a/b/c.html'); + const savedFetch = globalThis.fetch; + try { + globalThis.fetch = async (url) => { + console.log(`invalidate called with ${url}`); + called.push(url); + }; + + assert.strictEqual(called.length, 0, 'precondition'); + await invalidateCollab('syncAdmin', 'https://admin.da.live/source/a/b/c.html', env); + assert.strictEqual(called.length, 1); + assert.strictEqual(called[0], 'https://localhost/api/v1/syncAdmin?doc=https://admin.da.live/source/a/b/c.html'); + } finally { + globalThis.fetch = savedFetch; + } }); it('Should not invalidate non-html documents', async () => { const { called, env } = setupEnv(); - assert.strictEqual(called.length, 0, 'precondition'); - await invalidateCollab('syncAdmin', 'https://admin.da.live/source/a/b/c.jpg', env); - await invalidateCollab('syncAdmin', 'https://admin.da.live/source/a/b/c/d', env); - assert.strictEqual(called.length, 0, 'should not have invalidated anything'); + const savedFetch = globalThis.fetch; + try { + globalThis.fetch = async (url) => { + called.push(url); + }; + + assert.strictEqual(called.length, 0, 'precondition'); + await invalidateCollab('syncAdmin', 'https://admin.da.live/source/a/b/c.jpg', env); + await invalidateCollab('syncAdmin', 'https://admin.da.live/source/a/b/c/d', env); + assert.strictEqual(called.length, 0, 'should not have invalidated anything'); + } finally { + globalThis.fetch = savedFetch; + } }); }); diff --git a/wrangler.toml b/wrangler.toml index 88b30f7e..bd00bba1 100644 --- a/wrangler.toml +++ b/wrangler.toml @@ -5,10 +5,6 @@ keep_vars = true vars = { DA_COLLAB = "https://collab.da.page", AEM_BUCKET_NAME = "aem-content" } -services = [ - { binding = "dacollab", service = "da-collab" } -] - kv_namespaces = [ { binding = "DA_AUTH", id = "f8978fd2270f4c4fbcc8c9f04248a034" }, { binding = "DA_CONFIG", id = "a20824737cd8499bae0f0d887ac6db21" }, @@ -22,10 +18,6 @@ r2_buckets = [ [env.stage] vars = { ENVIRONMENT = "stage", DA_COLLAB = "https://collab.da.page", AEM_BUCKET_NAME = "aem-content-stage" } -services = [ - { binding = "dacollab", service = "da-collab-stage" } -] - kv_namespaces = [ { binding = "DA_AUTH", id = "f5cc4d0150ac48d5b56948b5d147c77e" }, { binding = "DA_CONFIG", id = "3f6f6db5c27348fabee7c2a8ed39be17" }, @@ -39,10 +31,6 @@ r2_buckets = [ [env.dev] vars = { ENVIRONMENT = "dev", DA_COLLAB = "http://localhost:4711", AEM_BUCKET_NAME = "aem-content-dev" } -services = [ - { binding = "dacollab", service = "da-collab-local" } -] - kv_namespaces = [ { binding = "DA_AUTH", id = "f5cc4d0150ac48d5b56948b5d147c77e" }, { binding = "DA_CONFIG", id = "3f6f6db5c27348fabee7c2a8ed39be17" }, From 2a602bfb34087db00e3d873ad970b910e8ea5bf7 Mon Sep 17 00:00:00 2001 From: kptdobe Date: Tue, 30 Sep 2025 10:53:17 +0200 Subject: [PATCH 2/3] chore: tune config --- wrangler.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrangler.toml b/wrangler.toml index bd00bba1..16fe59bf 100644 --- a/wrangler.toml +++ b/wrangler.toml @@ -16,7 +16,7 @@ r2_buckets = [ ] [env.stage] -vars = { ENVIRONMENT = "stage", DA_COLLAB = "https://collab.da.page", AEM_BUCKET_NAME = "aem-content-stage" } +vars = { ENVIRONMENT = "stage", DA_COLLAB = "https://stage-collab.da.page/", AEM_BUCKET_NAME = "aem-content-stage" } kv_namespaces = [ { binding = "DA_AUTH", id = "f5cc4d0150ac48d5b56948b5d147c77e" }, From 73733e45d2c5645b4a4f9b039c8a327c3cfc7ee5 Mon Sep 17 00:00:00 2001 From: kptdobe Date: Thu, 9 Oct 2025 14:18:03 +0200 Subject: [PATCH 3/3] chore: worker cannot fetch on same zone --- wrangler.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wrangler.toml b/wrangler.toml index 16fe59bf..018934c3 100644 --- a/wrangler.toml +++ b/wrangler.toml @@ -3,7 +3,7 @@ main = "src/index.js" compatibility_date = "2024-11-11" keep_vars = true -vars = { DA_COLLAB = "https://collab.da.page", AEM_BUCKET_NAME = "aem-content" } +vars = { DA_COLLAB = "https://da-collab.adobeaem.workers.dev", AEM_BUCKET_NAME = "aem-content" } kv_namespaces = [ { binding = "DA_AUTH", id = "f8978fd2270f4c4fbcc8c9f04248a034" }, @@ -16,7 +16,7 @@ r2_buckets = [ ] [env.stage] -vars = { ENVIRONMENT = "stage", DA_COLLAB = "https://stage-collab.da.page/", AEM_BUCKET_NAME = "aem-content-stage" } +vars = { ENVIRONMENT = "stage", DA_COLLAB = "https://da-collab-stage.adobeaem.workers.dev", AEM_BUCKET_NAME = "aem-content-stage" } kv_namespaces = [ { binding = "DA_AUTH", id = "f5cc4d0150ac48d5b56948b5d147c77e" },