From 2a85238443eec07ff4ee19ac594ec9cbe427a617 Mon Sep 17 00:00:00 2001
From: Antoine Rollin <66251236+antoinerollindev@users.noreply.github.com>
Date: Thu, 23 Jan 2025 20:00:19 +0100
Subject: [PATCH] SDA-4657: Patch for OpenFin (#2271)
---
spec/mainApiHandler.spec.ts | 21 +++++++++++++---
spec/openfinHandler.spec.ts | 33 +++++++++++++++++++------
src/app/main-api-handler.ts | 27 +++++++++-----------
src/app/openfin-handler.ts | 42 +++++++++++++++++++------------
src/common/api-interface.ts | 3 ++-
src/renderer/preload-main.ts | 4 +--
src/renderer/ssf-api.ts | 48 +++++++++++++++++++++++++-----------
7 files changed, 117 insertions(+), 61 deletions(-)
diff --git a/spec/mainApiHandler.spec.ts b/spec/mainApiHandler.spec.ts
index 2423be67b..f141eba00 100644
--- a/spec/mainApiHandler.spec.ts
+++ b/spec/mainApiHandler.spec.ts
@@ -21,6 +21,7 @@ jest.mock('../src/app/openfin-handler', () => {
connect: jest.fn(),
fireIntent: jest.fn(),
joinContextGroup: jest.fn(),
+ joinSessionContextGroup: jest.fn(),
getContextGroups: jest.fn(),
getConnectionStatus: jest.fn(),
getInfo: jest.fn(),
@@ -28,7 +29,7 @@ jest.mock('../src/app/openfin-handler', () => {
registerIntentHandler: jest.fn(),
unregisterIntentHandler: jest.fn(),
fireIntentForContext: jest.fn(),
- removeClientFromContextGroup: jest.fn(),
+ removeFromContextGroup: jest.fn(),
},
};
});
@@ -726,10 +727,22 @@ describe('main api handler', () => {
expect(spy).toHaveBeenCalledTimes(1);
});
- it('should call `removeClientFromContextGroup`', () => {
- const spy = jest.spyOn(openfinHandler, 'removeClientFromContextGroup');
+ it('should call `removeFromContextGroup`', () => {
+ const spy = jest.spyOn(openfinHandler, 'removeFromContextGroup');
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);
diff --git a/spec/openfinHandler.spec.ts b/spec/openfinHandler.spec.ts
index d7322657a..3e80cfee9 100644
--- a/spec/openfinHandler.spec.ts
+++ b/spec/openfinHandler.spec.ts
@@ -13,9 +13,10 @@ jest.mock('@openfin/node-adapter', () => ({
registerIntentHandler: jest.fn(),
getAllClientsInContextGroup: jest.fn(),
joinContextGroup: jest.fn(),
+ joinSessionContextGroup: jest.fn(),
getContextGroups: jest.fn(),
fireIntentForContext: jest.fn(),
- removeClientFromContextGroup: jest.fn(),
+ removeFromContextGroup: jest.fn(),
}),
},
});
@@ -185,6 +186,19 @@ describe('Openfin', () => {
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 () => {
const connectSyncMock = await connectMock.Interop.connectSync();
const getContextGroupsSpy = jest.spyOn(connectSyncMock, 'getContextGroups');
@@ -210,7 +224,10 @@ describe('Openfin', () => {
it('should fire an intent for a given context', async () => {
const connectSyncMock = await connectMock.Interop.connectSync();
- const fireIntentSpy = jest.spyOn(connectSyncMock, 'fireIntentForContext');
+ const fireIntentForContextSpy = jest.spyOn(
+ connectSyncMock,
+ 'fireIntentForContext',
+ );
await openfinHandler.connect();
const context = {
@@ -222,18 +239,18 @@ describe('Openfin', () => {
};
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 fireIntentSpy = jest.spyOn(
+ const removeFromContextGroupSpy = jest.spyOn(
connectSyncMock,
- 'removeClientFromContextGroup',
+ 'removeFromContextGroup',
);
- await openfinHandler.removeClientFromContextGroup();
+ await openfinHandler.removeFromContextGroup();
- expect(fireIntentSpy).toHaveBeenCalledTimes(1);
+ expect(removeFromContextGroupSpy).toHaveBeenCalledTimes(1);
});
});
diff --git a/src/app/main-api-handler.ts b/src/app/main-api-handler.ts
index 55d433722..5630bc79e 100644
--- a/src/app/main-api-handler.ts
+++ b/src/app/main-api-handler.ts
@@ -560,21 +560,6 @@ ipcMain.on(
helpMenu.setValue(helpCenter);
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:
break;
}
@@ -657,6 +642,18 @@ ipcMain.handle(
return openfinHandler.getAllClientsInContextGroup(arg.contextGroupId);
case apiCmds.openfinGetClientInfo:
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:
break;
}
diff --git a/src/app/openfin-handler.ts b/src/app/openfin-handler.ts
index 60a8c0311..36c6348a0 100644
--- a/src/app/openfin-handler.ts
+++ b/src/app/openfin-handler.ts
@@ -1,20 +1,22 @@
+///
+
import { connect } from '@openfin/node-adapter';
import { randomUUID, UUID } from 'crypto';
import { logger } from '../common/openfin-logger';
import { config, IConfig } from './config-handler';
import { windowHandler } from './window-handler';
-const OPENFIN_PROVIDER = 'Openfin';
+const OPENFIN_PROVIDER = 'OpenFin';
const TIMEOUT_THRESHOLD = 10000;
export class OpenfinHandler {
- private interopClient;
+ private interopClient: OpenFin.InteropClient | undefined;
private intentHandlerSubscriptions: Map = new Map();
private isConnected: boolean = false;
private fin: any;
/**
- * Connection to interop brocker
+ * Connection to interop broker
*/
public async connect() {
const { openfin }: IConfig = config.getConfigFields(['openfin']);
@@ -30,7 +32,8 @@ export class OpenfinHandler {
const connectionTimeoutPromise = new Promise((_, reject) =>
setTimeout(() => {
logger.error(
- `openfin-handler: Connection timeout after ${timeoutValue / 1000
+ `openfin-handler: Connection timeout after ${
+ timeoutValue / 1000
} seconds`,
);
return reject(
@@ -61,7 +64,7 @@ export class OpenfinHandler {
this.interopClient = this.fin.Interop.connectSync(openfin.channelName);
this.isConnected = true;
- this.interopClient.onDisconnection((event) => {
+ this.interopClient?.onDisconnection((event) => {
const { brokerName } = event;
logger.warn(
`openfin-handler: Disconnected from Interop Broker ${brokerName}`,
@@ -95,7 +98,7 @@ export class OpenfinHandler {
* Sends an intent to the Interop Broker
*/
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 {
const unsubscriptionCallback =
- await this.interopClient.registerIntentHandler(
+ await this.interopClient?.registerIntentHandler(
this.intentHandler,
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.
*/
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.
*/
public async getContextGroups() {
- return this.interopClient.getContextGroups();
+ return this.interopClient?.getContextGroups();
}
/**
* Gets all clients for a context group.
*/
- public getAllClientsInContextGroup(contextGroupId: string) {
- return this.interopClient.getAllClientsInContextGroup(contextGroupId);
+ public async getAllClientsInContextGroup(contextGroupId: string) {
+ return this.interopClient?.getAllClientsInContextGroup(contextGroupId);
}
/**
@@ -178,7 +188,7 @@ export class OpenfinHandler {
public getInfo() {
return {
provider: OPENFIN_PROVIDER,
- fdc3Version: '',
+ fdc3Version: '2.0',
optionalFeatures: {
OriginatingAppMetadata: false,
UserChannelMembershipAPIs: false,
@@ -193,14 +203,14 @@ export class OpenfinHandler {
* @param context
*/
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() {
- this.interopClient.removeClientFromContextGroup();
+ public removeFromContextGroup() {
+ return this.interopClient?.removeFromContextGroup();
}
/**
diff --git a/src/common/api-interface.ts b/src/common/api-interface.ts
index 67e41f8a4..c36ee1377 100644
--- a/src/common/api-interface.ts
+++ b/src/common/api-interface.ts
@@ -91,10 +91,11 @@ export enum apiCmds {
openfinGetConnectionStatus = 'openfin-get-connection-status',
openfinGetInfo = 'openfin-get-info',
openfinJoinContextGroup = 'openfin-join-context-group',
+ openfinJoinSessionContextGroup = 'openfin-join-session-context-group',
openfinGetContextGroups = 'openfin-get-context-groups',
openfinGetAllClientsInContextGroup = 'openfin-get-all-clients-in-context-group',
openfinFireIntentForContext = 'openfin-fire-intent-for-context',
- openfinRemoveClientFromContextGroup = 'openfin-remove-client-from-context-group',
+ openfinRemoveFromContextGroup = 'openfin-remove-from-context-group',
openfinGetClientInfo = 'openfin-get-client-info',
}
diff --git a/src/renderer/preload-main.ts b/src/renderer/preload-main.ts
index e1304c6e0..5cd3e1ce5 100644
--- a/src/renderer/preload-main.ts
+++ b/src/renderer/preload-main.ts
@@ -115,11 +115,11 @@ if (ssfWindow.ssf) {
unregisterIntentHandler: ssfWindow.ssf.openfinUnregisterIntentHandler,
getContextGroups: ssfWindow.ssf.openfinGetContextGroups,
joinContextGroup: ssfWindow.ssf.openfinJoinContextGroup,
+ joinSessionContextGroup: ssfWindow.ssf.openfinJoinSessionContextGroup,
getAllClientsInContextGroup:
ssfWindow.ssf.openfinGetAllClientsInContextGroup,
fireIntentForContext: ssfWindow.ssf.openfinFireIntentForContext,
- removeClientFromContextGroup:
- ssfWindow.ssf.openfinRemoveClientFromContextGroup,
+ removeFromContextGroup: ssfWindow.ssf.openfinRemoveFromContextGroup,
getClientInfo: ssfWindow.ssf.openfinGetClientInfo,
});
}
diff --git a/src/renderer/ssf-api.ts b/src/renderer/ssf-api.ts
index b85350be6..d7f5230d4 100644
--- a/src/renderer/ssf-api.ts
+++ b/src/renderer/ssf-api.ts
@@ -958,7 +958,7 @@ export class SSFApi {
/**
* Openfin Interop client initialization
*/
- public async openfinInit(): Promise {
+ public async openfinInit() {
const connectionStatus = await local.ipcRenderer.invoke(
apiName.symphonyApi,
{
@@ -981,31 +981,34 @@ export class SSFApi {
/**
* Fires an intent
*/
- public openfinFireIntent(intent: any): void {
- local.ipcRenderer.send(apiName.symphonyApi, {
+ public async openfinFireIntent(intent: any): Promise {
+ const response = await local.ipcRenderer.invoke(apiName.symphonyApi, {
cmd: apiCmds.openfinFireIntent,
intent,
});
+ return response;
}
/**
* Fires an intent for a given context
* @param context
*/
- public openfinFireIntentForContext(context: any): void {
- local.ipcRenderer.send(apiName.symphonyApi, {
+ public async openfinFireIntentForContext(context: any): Promise {
+ const response = await local.ipcRenderer.invoke(apiName.symphonyApi, {
cmd: apiCmds.openfinFireIntentForContext,
context,
});
+ return response;
}
/**
- * Removes client from current context group
+ * Leaves current context group
*/
- public openfinRemoveClientFromContextGroup() {
- local.ipcRenderer.send(apiName.symphonyApi, {
- cmd: apiCmds.openfinRemoveClientFromContextGroup,
+ public async openfinRemoveFromContextGroup() {
+ const response = await local.ipcRenderer.invoke(apiName.symphonyApi, {
+ cmd: apiCmds.openfinRemoveFromContextGroup,
});
+ return response;
}
/**
@@ -1057,7 +1060,7 @@ export class SSFApi {
* Unregisters a handler based on a given intent handler callback id
* @param UUID
*/
- public openfinUnregisterIntentHandler(callbackId: UUID): void {
+ public async openfinUnregisterIntentHandler(callbackId: UUID): Promise {
for (const innerMap of local.intentsCallbacks.values()) {
if (innerMap.has(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,
callbackId,
});
+ return response;
}
/**
@@ -1086,22 +1090,36 @@ export class SSFApi {
* @param contextGroupId
* @param target
*/
- public openfinJoinContextGroup(contextGroupId: string, target?: any) {
- local.ipcRenderer.send(apiName.symphonyApi, {
+ public async openfinJoinContextGroup(contextGroupId: string, target?: any) {
+ const response = await local.ipcRenderer.invoke(apiName.symphonyApi, {
cmd: apiCmds.openfinJoinContextGroup,
contextGroupId,
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
*/
- public openfinGetAllClientsInContextGroup(contextGroupId: string) {
- return local.ipcRenderer.invoke(apiName.symphonyApi, {
+ public async openfinGetAllClientsInContextGroup(contextGroupId: string) {
+ const clients = await local.ipcRenderer.invoke(apiName.symphonyApi, {
cmd: apiCmds.openfinGetAllClientsInContextGroup,
contextGroupId,
});
+ return clients;
}
/**