SDA-4657: Patch for OpenFin

This commit is contained in:
Antoine Rollin 2025-01-23 15:19:37 +01:00
parent 72be5a43cb
commit 794e0aa9af
7 changed files with 117 additions and 61 deletions

View File

@ -21,6 +21,7 @@ jest.mock('../src/app/openfin-handler', () => {
connect: jest.fn(), connect: jest.fn(),
fireIntent: jest.fn(), fireIntent: jest.fn(),
joinContextGroup: jest.fn(), joinContextGroup: jest.fn(),
joinSessionContextGroup: jest.fn(),
getContextGroups: jest.fn(), getContextGroups: jest.fn(),
getConnectionStatus: jest.fn(), getConnectionStatus: jest.fn(),
getInfo: jest.fn(), getInfo: jest.fn(),
@ -28,7 +29,7 @@ jest.mock('../src/app/openfin-handler', () => {
registerIntentHandler: jest.fn(), registerIntentHandler: jest.fn(),
unregisterIntentHandler: jest.fn(), unregisterIntentHandler: jest.fn(),
fireIntentForContext: jest.fn(), fireIntentForContext: jest.fn(),
removeClientFromContextGroup: jest.fn(), removeFromContextGroup: jest.fn(),
}, },
}; };
}); });
@ -726,10 +727,22 @@ describe('main api handler', () => {
expect(spy).toHaveBeenCalledTimes(1); expect(spy).toHaveBeenCalledTimes(1);
}); });
it('should call `removeClientFromContextGroup`', () => { it('should call `removeFromContextGroup`', () => {
const spy = jest.spyOn(openfinHandler, 'removeClientFromContextGroup'); const spy = jest.spyOn(openfinHandler, 'removeFromContextGroup');
const value = { const value = {
cmd: apiCmds.openfinRemoveClientFromContextGroup, cmd: apiCmds.openfinRemoveFromContextGroup,
};
ipcMain.send(apiName.symphonyApi, value);
expect(spy).toHaveBeenCalledTimes(1);
});
it('should call `joinSessionContextGroup`', () => {
const spy = jest.spyOn(openfinHandler, 'joinSessionContextGroup');
const value = {
cmd: apiCmds.openfinJoinSessionContextGroup,
contextGroupId: 'group-id',
}; };
ipcMain.send(apiName.symphonyApi, value); ipcMain.send(apiName.symphonyApi, value);

View File

@ -13,9 +13,10 @@ jest.mock('@openfin/node-adapter', () => ({
registerIntentHandler: jest.fn(), registerIntentHandler: jest.fn(),
getAllClientsInContextGroup: jest.fn(), getAllClientsInContextGroup: jest.fn(),
joinContextGroup: jest.fn(), joinContextGroup: jest.fn(),
joinSessionContextGroup: jest.fn(),
getContextGroups: jest.fn(), getContextGroups: jest.fn(),
fireIntentForContext: jest.fn(), fireIntentForContext: jest.fn(),
removeClientFromContextGroup: jest.fn(), removeFromContextGroup: jest.fn(),
}), }),
}, },
}); });
@ -185,6 +186,19 @@ describe('Openfin', () => {
expect(joinContextGroupSpy).toHaveBeenCalledTimes(1); expect(joinContextGroupSpy).toHaveBeenCalledTimes(1);
}); });
it('should join a session context group', async () => {
const connectSyncMock = await connectMock.Interop.connectSync();
const joinSessionContextGroupSpy = jest.spyOn(
connectSyncMock,
'joinSessionContextGroup',
);
await openfinHandler.connect();
await openfinHandler.joinSessionContextGroup('contextGroupId');
expect(joinSessionContextGroupSpy).toHaveBeenCalledTimes(1);
});
it('should return all context groups', async () => { it('should return all context groups', async () => {
const connectSyncMock = await connectMock.Interop.connectSync(); const connectSyncMock = await connectMock.Interop.connectSync();
const getContextGroupsSpy = jest.spyOn(connectSyncMock, 'getContextGroups'); const getContextGroupsSpy = jest.spyOn(connectSyncMock, 'getContextGroups');
@ -210,7 +224,10 @@ describe('Openfin', () => {
it('should fire an intent for a given context', async () => { it('should fire an intent for a given context', async () => {
const connectSyncMock = await connectMock.Interop.connectSync(); const connectSyncMock = await connectMock.Interop.connectSync();
const fireIntentSpy = jest.spyOn(connectSyncMock, 'fireIntentForContext'); const fireIntentForContextSpy = jest.spyOn(
connectSyncMock,
'fireIntentForContext',
);
await openfinHandler.connect(); await openfinHandler.connect();
const context = { const context = {
@ -222,18 +239,18 @@ describe('Openfin', () => {
}; };
await openfinHandler.fireIntentForContext(context); await openfinHandler.fireIntentForContext(context);
expect(fireIntentSpy).toHaveBeenCalledTimes(1); expect(fireIntentForContextSpy).toHaveBeenCalledTimes(1);
}); });
it('should remove client from context group', async () => { it('should remove from context group', async () => {
const connectSyncMock = await connectMock.Interop.connectSync(); const connectSyncMock = await connectMock.Interop.connectSync();
const fireIntentSpy = jest.spyOn( const removeFromContextGroupSpy = jest.spyOn(
connectSyncMock, connectSyncMock,
'removeClientFromContextGroup', 'removeFromContextGroup',
); );
await openfinHandler.removeClientFromContextGroup(); await openfinHandler.removeFromContextGroup();
expect(fireIntentSpy).toHaveBeenCalledTimes(1); expect(removeFromContextGroupSpy).toHaveBeenCalledTimes(1);
}); });
}); });

View File

@ -560,21 +560,6 @@ ipcMain.on(
helpMenu.setValue(helpCenter); helpMenu.setValue(helpCenter);
break; break;
case apiCmds.openfinFireIntent:
openfinHandler.fireIntent(arg.intent);
break;
case apiCmds.openfinJoinContextGroup:
openfinHandler.joinContextGroup(arg.contextGroupId, arg.target);
break;
case apiCmds.openfinUnregisterIntentHandler:
openfinHandler.unregisterIntentHandler(arg.intentName);
break;
case apiCmds.openfinFireIntentForContext:
openfinHandler.fireIntentForContext(arg.context);
break;
case apiCmds.openfinRemoveClientFromContextGroup:
openfinHandler.removeClientFromContextGroup();
break;
default: default:
break; break;
} }
@ -657,6 +642,18 @@ ipcMain.handle(
return openfinHandler.getAllClientsInContextGroup(arg.contextGroupId); return openfinHandler.getAllClientsInContextGroup(arg.contextGroupId);
case apiCmds.openfinGetClientInfo: case apiCmds.openfinGetClientInfo:
return openfinHandler.getClientInfo(); return openfinHandler.getClientInfo();
case apiCmds.openfinFireIntent:
return openfinHandler.fireIntent(arg.intent);
case apiCmds.openfinJoinContextGroup:
return openfinHandler.joinContextGroup(arg.contextGroupId, arg.target);
case apiCmds.openfinJoinSessionContextGroup:
return openfinHandler.joinSessionContextGroup(arg.contextGroupId);
case apiCmds.openfinUnregisterIntentHandler:
return openfinHandler.unregisterIntentHandler(arg.intentName);
case apiCmds.openfinFireIntentForContext:
return openfinHandler.fireIntentForContext(arg.context);
case apiCmds.openfinRemoveFromContextGroup:
return openfinHandler.removeFromContextGroup();
default: default:
break; break;
} }

View File

@ -1,20 +1,22 @@
/// <reference types="@openfin/core/fin" />
import { connect } from '@openfin/node-adapter'; import { connect } from '@openfin/node-adapter';
import { randomUUID, UUID } from 'crypto'; import { randomUUID, UUID } from 'crypto';
import { logger } from '../common/openfin-logger'; import { logger } from '../common/openfin-logger';
import { config, IConfig } from './config-handler'; import { config, IConfig } from './config-handler';
import { windowHandler } from './window-handler'; import { windowHandler } from './window-handler';
const OPENFIN_PROVIDER = 'Openfin'; const OPENFIN_PROVIDER = 'OpenFin';
const TIMEOUT_THRESHOLD = 10000; const TIMEOUT_THRESHOLD = 10000;
export class OpenfinHandler { export class OpenfinHandler {
private interopClient; private interopClient: OpenFin.InteropClient | undefined;
private intentHandlerSubscriptions: Map<UUID, any> = new Map(); private intentHandlerSubscriptions: Map<UUID, any> = new Map();
private isConnected: boolean = false; private isConnected: boolean = false;
private fin: any; private fin: any;
/** /**
* Connection to interop brocker * Connection to interop broker
*/ */
public async connect() { public async connect() {
const { openfin }: IConfig = config.getConfigFields(['openfin']); const { openfin }: IConfig = config.getConfigFields(['openfin']);
@ -30,7 +32,8 @@ export class OpenfinHandler {
const connectionTimeoutPromise = new Promise((_, reject) => const connectionTimeoutPromise = new Promise((_, reject) =>
setTimeout(() => { setTimeout(() => {
logger.error( logger.error(
`openfin-handler: Connection timeout after ${timeoutValue / 1000 `openfin-handler: Connection timeout after ${
timeoutValue / 1000
} seconds`, } seconds`,
); );
return reject( return reject(
@ -61,7 +64,7 @@ export class OpenfinHandler {
this.interopClient = this.fin.Interop.connectSync(openfin.channelName); this.interopClient = this.fin.Interop.connectSync(openfin.channelName);
this.isConnected = true; this.isConnected = true;
this.interopClient.onDisconnection((event) => { this.interopClient?.onDisconnection((event) => {
const { brokerName } = event; const { brokerName } = event;
logger.warn( logger.warn(
`openfin-handler: Disconnected from Interop Broker ${brokerName}`, `openfin-handler: Disconnected from Interop Broker ${brokerName}`,
@ -95,7 +98,7 @@ export class OpenfinHandler {
* Sends an intent to the Interop Broker * Sends an intent to the Interop Broker
*/ */
public fireIntent(intent) { public fireIntent(intent) {
this.interopClient.fireIntent(intent); return this.interopClient?.fireIntent(intent);
} }
/** /**
@ -103,7 +106,7 @@ export class OpenfinHandler {
*/ */
public async registerIntentHandler(intentName: string): Promise<UUID> { public async registerIntentHandler(intentName: string): Promise<UUID> {
const unsubscriptionCallback = const unsubscriptionCallback =
await this.interopClient.registerIntentHandler( await this.interopClient?.registerIntentHandler(
this.intentHandler, this.intentHandler,
intentName, intentName,
); );
@ -125,21 +128,28 @@ export class OpenfinHandler {
* Join all Interop Clients at the given identity to context group contextGroupId. If no target is specified, it adds the sender to the context group. * Join all Interop Clients at the given identity to context group contextGroupId. If no target is specified, it adds the sender to the context group.
*/ */
public async joinContextGroup(contextGroupId: string, target?: any) { public async joinContextGroup(contextGroupId: string, target?: any) {
await this.interopClient.joinContextGroup(contextGroupId, target); return this.interopClient?.joinContextGroup(contextGroupId, target);
}
/**
* Joins or create a context group that does not persist between runs and aren't present on snapshots.
*/
public async joinSessionContextGroup(contextGroupId: string) {
return this.interopClient?.joinSessionContextGroup(contextGroupId);
} }
/** /**
* Returns the Interop-Broker-defined context groups available for an entity to join. * Returns the Interop-Broker-defined context groups available for an entity to join.
*/ */
public async getContextGroups() { public async getContextGroups() {
return this.interopClient.getContextGroups(); return this.interopClient?.getContextGroups();
} }
/** /**
* Gets all clients for a context group. * Gets all clients for a context group.
*/ */
public getAllClientsInContextGroup(contextGroupId: string) { public async getAllClientsInContextGroup(contextGroupId: string) {
return this.interopClient.getAllClientsInContextGroup(contextGroupId); return this.interopClient?.getAllClientsInContextGroup(contextGroupId);
} }
/** /**
@ -178,7 +188,7 @@ export class OpenfinHandler {
public getInfo() { public getInfo() {
return { return {
provider: OPENFIN_PROVIDER, provider: OPENFIN_PROVIDER,
fdc3Version: '', fdc3Version: '2.0',
optionalFeatures: { optionalFeatures: {
OriginatingAppMetadata: false, OriginatingAppMetadata: false,
UserChannelMembershipAPIs: false, UserChannelMembershipAPIs: false,
@ -193,14 +203,14 @@ export class OpenfinHandler {
* @param context * @param context
*/ */
public fireIntentForContext(context: any) { public fireIntentForContext(context: any) {
this.interopClient.fireIntentForContext(context); return this.interopClient?.fireIntentForContext(context);
} }
/** /**
* Removes a client from current context group * Leaves current context group
*/ */
public removeClientFromContextGroup() { public removeFromContextGroup() {
this.interopClient.removeClientFromContextGroup(); return this.interopClient?.removeFromContextGroup();
} }
/** /**

View File

@ -91,10 +91,11 @@ export enum apiCmds {
openfinGetConnectionStatus = 'openfin-get-connection-status', openfinGetConnectionStatus = 'openfin-get-connection-status',
openfinGetInfo = 'openfin-get-info', openfinGetInfo = 'openfin-get-info',
openfinJoinContextGroup = 'openfin-join-context-group', openfinJoinContextGroup = 'openfin-join-context-group',
openfinJoinSessionContextGroup = 'openfin-join-session-context-group',
openfinGetContextGroups = 'openfin-get-context-groups', openfinGetContextGroups = 'openfin-get-context-groups',
openfinGetAllClientsInContextGroup = 'openfin-get-all-clients-in-context-group', openfinGetAllClientsInContextGroup = 'openfin-get-all-clients-in-context-group',
openfinFireIntentForContext = 'openfin-fire-intent-for-context', openfinFireIntentForContext = 'openfin-fire-intent-for-context',
openfinRemoveClientFromContextGroup = 'openfin-remove-client-from-context-group', openfinRemoveFromContextGroup = 'openfin-remove-from-context-group',
openfinGetClientInfo = 'openfin-get-client-info', openfinGetClientInfo = 'openfin-get-client-info',
} }

View File

@ -115,11 +115,11 @@ if (ssfWindow.ssf) {
unregisterIntentHandler: ssfWindow.ssf.openfinUnregisterIntentHandler, unregisterIntentHandler: ssfWindow.ssf.openfinUnregisterIntentHandler,
getContextGroups: ssfWindow.ssf.openfinGetContextGroups, getContextGroups: ssfWindow.ssf.openfinGetContextGroups,
joinContextGroup: ssfWindow.ssf.openfinJoinContextGroup, joinContextGroup: ssfWindow.ssf.openfinJoinContextGroup,
joinSessionContextGroup: ssfWindow.ssf.openfinJoinSessionContextGroup,
getAllClientsInContextGroup: getAllClientsInContextGroup:
ssfWindow.ssf.openfinGetAllClientsInContextGroup, ssfWindow.ssf.openfinGetAllClientsInContextGroup,
fireIntentForContext: ssfWindow.ssf.openfinFireIntentForContext, fireIntentForContext: ssfWindow.ssf.openfinFireIntentForContext,
removeClientFromContextGroup: removeFromContextGroup: ssfWindow.ssf.openfinRemoveFromContextGroup,
ssfWindow.ssf.openfinRemoveClientFromContextGroup,
getClientInfo: ssfWindow.ssf.openfinGetClientInfo, getClientInfo: ssfWindow.ssf.openfinGetClientInfo,
}); });
} }

View File

@ -958,7 +958,7 @@ export class SSFApi {
/** /**
* Openfin Interop client initialization * Openfin Interop client initialization
*/ */
public async openfinInit(): Promise<boolean> { public async openfinInit() {
const connectionStatus = await local.ipcRenderer.invoke( const connectionStatus = await local.ipcRenderer.invoke(
apiName.symphonyApi, apiName.symphonyApi,
{ {
@ -981,31 +981,34 @@ export class SSFApi {
/** /**
* Fires an intent * Fires an intent
*/ */
public openfinFireIntent(intent: any): void { public async openfinFireIntent(intent: any): Promise<void> {
local.ipcRenderer.send(apiName.symphonyApi, { const response = await local.ipcRenderer.invoke(apiName.symphonyApi, {
cmd: apiCmds.openfinFireIntent, cmd: apiCmds.openfinFireIntent,
intent, intent,
}); });
return response;
} }
/** /**
* Fires an intent for a given context * Fires an intent for a given context
* @param context * @param context
*/ */
public openfinFireIntentForContext(context: any): void { public async openfinFireIntentForContext(context: any): Promise<void> {
local.ipcRenderer.send(apiName.symphonyApi, { const response = await local.ipcRenderer.invoke(apiName.symphonyApi, {
cmd: apiCmds.openfinFireIntentForContext, cmd: apiCmds.openfinFireIntentForContext,
context, context,
}); });
return response;
} }
/** /**
* Removes client from current context group * Leaves current context group
*/ */
public openfinRemoveClientFromContextGroup() { public async openfinRemoveFromContextGroup() {
local.ipcRenderer.send(apiName.symphonyApi, { const response = await local.ipcRenderer.invoke(apiName.symphonyApi, {
cmd: apiCmds.openfinRemoveClientFromContextGroup, cmd: apiCmds.openfinRemoveFromContextGroup,
}); });
return response;
} }
/** /**
@ -1057,7 +1060,7 @@ export class SSFApi {
* Unregisters a handler based on a given intent handler callback id * Unregisters a handler based on a given intent handler callback id
* @param UUID * @param UUID
*/ */
public openfinUnregisterIntentHandler(callbackId: UUID): void { public async openfinUnregisterIntentHandler(callbackId: UUID): Promise<void> {
for (const innerMap of local.intentsCallbacks.values()) { for (const innerMap of local.intentsCallbacks.values()) {
if (innerMap.has(callbackId)) { if (innerMap.has(callbackId)) {
innerMap.delete(callbackId); innerMap.delete(callbackId);
@ -1065,10 +1068,11 @@ export class SSFApi {
} }
} }
local.ipcRenderer.send(apiName.symphonyApi, { const response = await local.ipcRenderer.invoke(apiName.symphonyApi, {
cmd: apiCmds.openfinUnregisterIntentHandler, cmd: apiCmds.openfinUnregisterIntentHandler,
callbackId, callbackId,
}); });
return response;
} }
/** /**
@ -1086,22 +1090,36 @@ export class SSFApi {
* @param contextGroupId * @param contextGroupId
* @param target * @param target
*/ */
public openfinJoinContextGroup(contextGroupId: string, target?: any) { public async openfinJoinContextGroup(contextGroupId: string, target?: any) {
local.ipcRenderer.send(apiName.symphonyApi, { const response = await local.ipcRenderer.invoke(apiName.symphonyApi, {
cmd: apiCmds.openfinJoinContextGroup, cmd: apiCmds.openfinJoinContextGroup,
contextGroupId, contextGroupId,
target, target,
}); });
return response;
}
/**
* Allows to join or create an Openfin session context group
* @param contextGroupId
*/
public async openfinJoinSessionContextGroup(contextGroupId: string) {
const response = await local.ipcRenderer.invoke(apiName.symphonyApi, {
cmd: apiCmds.openfinJoinSessionContextGroup,
contextGroupId,
});
return response;
} }
/** /**
* Returns registered clients in a given context group * Returns registered clients in a given context group
*/ */
public openfinGetAllClientsInContextGroup(contextGroupId: string) { public async openfinGetAllClientsInContextGroup(contextGroupId: string) {
return local.ipcRenderer.invoke(apiName.symphonyApi, { const clients = await local.ipcRenderer.invoke(apiName.symphonyApi, {
cmd: apiCmds.openfinGetAllClientsInContextGroup, cmd: apiCmds.openfinGetAllClientsInContextGroup,
contextGroupId, contextGroupId,
}); });
return clients;
} }
/** /**