Full SDK workspace: core, contracts, sdk, cli, browser-host, browser-kit, federation, omega-core, oracle, self-healing, strategies, tools, emacs. Clean extraction from the development monorepo. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
211 lines
6.2 KiB
TypeScript
211 lines
6.2 KiB
TypeScript
/**
|
|
* EdgeGateway Routing Integration Tests
|
|
*
|
|
* Tests the EdgeGateway's ability to route messages between
|
|
* backbone and local bus using in-memory transports.
|
|
*/
|
|
|
|
import { describe, it } from 'node:test';
|
|
import { strict as assert } from 'node:assert';
|
|
import {
|
|
FederationPeer, ExactInstanceResolver,
|
|
WIRE_PROFILES,
|
|
InMemoryFilterBroker,
|
|
getLegacyIngressTopic,
|
|
} from '@open-matrix/federation';
|
|
|
|
describe('EdgeGateway Routing', () => {
|
|
|
|
it('routes inbound request from backbone to local bus', async () => {
|
|
const REALM = 'test-realm';
|
|
|
|
// Create in-memory brokers
|
|
const backbone = new InMemoryFilterBroker();
|
|
const localBus = new InMemoryFilterBroker();
|
|
|
|
// Create EdgeGateway
|
|
const gateway = new FederationPeer({
|
|
localRealm: REALM,
|
|
profile: WIRE_PROFILES.matrix3,
|
|
backbone,
|
|
localBus,
|
|
});
|
|
|
|
gateway.start();
|
|
|
|
// Subscribe to internal topic on local bus (simulating a handler)
|
|
// Internal topic format: <toPath> (realm is a transport concern)
|
|
let receivedRequest: unknown = null;
|
|
localBus.subscribe(`test.component.accepts.ping`, (topic, payload) => {
|
|
receivedRequest = JSON.parse(payload);
|
|
});
|
|
|
|
// Allow subscriptions to propagate
|
|
await new Promise(r => setTimeout(r, 50));
|
|
|
|
// Send request to backbone mailbox using LEGACY format (flat fields)
|
|
const request = {
|
|
toRealm: REALM,
|
|
toPath: 'test.component.accepts.ping',
|
|
fromRealm: 'client-realm',
|
|
replyTo: '_reply', // just the path, not an object
|
|
correlationId: 'test-123',
|
|
body: { message: 'hello' },
|
|
};
|
|
|
|
backbone.publish(getLegacyIngressTopic(REALM), JSON.stringify(request));
|
|
|
|
// Wait for message to be routed
|
|
await new Promise(r => setTimeout(r, 100));
|
|
|
|
assert.ok(receivedRequest, 'Should receive request on local bus');
|
|
assert.strictEqual((receivedRequest as { correlationId: string }).correlationId, 'test-123');
|
|
|
|
gateway.stop();
|
|
});
|
|
|
|
it('routes reply from local bus back to backbone', async () => {
|
|
const REALM = 'test-realm';
|
|
const CLIENT_REALM = 'client-realm';
|
|
|
|
const backbone = new InMemoryFilterBroker();
|
|
const localBus = new InMemoryFilterBroker();
|
|
|
|
const gateway = new FederationPeer({
|
|
localRealm: REALM,
|
|
profile: WIRE_PROFILES.matrix3,
|
|
backbone,
|
|
localBus,
|
|
internalTimeoutMs: 5000,
|
|
});
|
|
|
|
gateway.start();
|
|
|
|
// Subscribe to client's mailbox on backbone (where reply should go)
|
|
let receivedReply: unknown = null;
|
|
backbone.subscribe(getLegacyIngressTopic(CLIENT_REALM), (topic, payload) => {
|
|
receivedReply = JSON.parse(payload);
|
|
});
|
|
|
|
// Set up handler on local bus that will reply
|
|
// Internal topic format: <toPath> (realm is a transport concern)
|
|
localBus.subscribe(`test.component.accepts.echo`, (topic, payload) => {
|
|
const req = JSON.parse(payload) as { replyTo: string; correlationId: string; params: unknown };
|
|
// Send reply to the replyTo topic
|
|
localBus.publish(req.replyTo, JSON.stringify({
|
|
ok: true,
|
|
correlationId: req.correlationId,
|
|
result: { echo: 'hello back' },
|
|
}));
|
|
});
|
|
|
|
await new Promise(r => setTimeout(r, 50));
|
|
|
|
// Send request from client using LEGACY format (flat fields)
|
|
const request = {
|
|
toRealm: REALM,
|
|
toPath: 'test.component.accepts.echo',
|
|
fromRealm: CLIENT_REALM,
|
|
replyTo: '_reply', // just the path
|
|
correlationId: 'echo-456',
|
|
body: { message: 'hello' },
|
|
};
|
|
|
|
backbone.publish(getLegacyIngressTopic(REALM), JSON.stringify(request));
|
|
|
|
// Wait for round-trip
|
|
await new Promise(r => setTimeout(r, 200));
|
|
|
|
assert.ok(receivedReply, 'Should receive reply on backbone');
|
|
|
|
gateway.stop();
|
|
});
|
|
|
|
it('uses exact mailbox topic (no wildcards)', async () => {
|
|
const REALM = 'my-realm';
|
|
|
|
const backbone = new InMemoryFilterBroker();
|
|
const localBus = new InMemoryFilterBroker();
|
|
|
|
// Track what topics are subscribed
|
|
const subscribedTopics: string[] = [];
|
|
const originalSubscribe = backbone.subscribe.bind(backbone);
|
|
backbone.subscribe = (topic: string, handler: (t: string, p: string) => void) => {
|
|
subscribedTopics.push(topic);
|
|
return originalSubscribe(topic, handler);
|
|
};
|
|
|
|
const gateway = new FederationPeer({
|
|
localRealm: REALM,
|
|
profile: WIRE_PROFILES.matrix3,
|
|
backbone,
|
|
localBus,
|
|
});
|
|
|
|
gateway.start();
|
|
|
|
// Verify subscribed topic is exact mailbox, not wildcard
|
|
const mailboxTopic = getLegacyIngressTopic(REALM);
|
|
assert.ok(
|
|
subscribedTopics.includes(mailboxTopic),
|
|
`Should subscribe to exact mailbox: ${mailboxTopic}`
|
|
);
|
|
assert.ok(
|
|
!subscribedTopics.some(t => t.includes('#') || t.includes('+')),
|
|
'Should NOT use wildcards on backbone subscription'
|
|
);
|
|
|
|
gateway.stop();
|
|
});
|
|
|
|
it('metrics track inbound requests', async () => {
|
|
const REALM = 'metrics-realm';
|
|
|
|
const backbone = new InMemoryFilterBroker();
|
|
const localBus = new InMemoryFilterBroker();
|
|
|
|
const gateway = new FederationPeer({
|
|
localRealm: REALM,
|
|
profile: WIRE_PROFILES.matrix3,
|
|
backbone,
|
|
localBus,
|
|
});
|
|
|
|
gateway.start();
|
|
|
|
// Set up a handler so request completes
|
|
// Internal topic format: <toPath> (realm is a transport concern)
|
|
localBus.subscribe(`test.accepts.cmd`, (topic, payload) => {
|
|
const req = JSON.parse(payload) as { replyTo: string; correlationId: string };
|
|
localBus.publish(req.replyTo, JSON.stringify({ ok: true, correlationId: req.correlationId }));
|
|
});
|
|
|
|
await new Promise(r => setTimeout(r, 50));
|
|
|
|
const initialMetrics = gateway.getMetrics();
|
|
|
|
// Send a request using LEGACY format (flat fields)
|
|
const request = {
|
|
toRealm: REALM,
|
|
toPath: 'test.accepts.cmd',
|
|
fromRealm: 'other',
|
|
replyTo: '_reply', // just the path
|
|
correlationId: 'metrics-1',
|
|
body: {},
|
|
};
|
|
|
|
backbone.publish(getLegacyIngressTopic(REALM), JSON.stringify(request));
|
|
|
|
await new Promise(r => setTimeout(r, 200));
|
|
|
|
const finalMetrics = gateway.getMetrics();
|
|
|
|
assert.ok(
|
|
finalMetrics.inboundRequests > initialMetrics.inboundRequests,
|
|
'Inbound requests should increase'
|
|
);
|
|
|
|
gateway.stop();
|
|
});
|
|
});
|