Skip to content

Commit

Permalink
Revert websocket
Browse files Browse the repository at this point in the history
  • Loading branch information
VitoAlbano committed Nov 27, 2024
1 parent c50ed8b commit 6798c92
Show file tree
Hide file tree
Showing 13 changed files with 148 additions and 438 deletions.
2 changes: 1 addition & 1 deletion lib/process-services-cloud/.storybook/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
},

"exclude": ["../**/*.spec.ts" ],
"include": ["../src/**/*", "*.js", "../../core/feature-flags"]
"include": ["../src/**/*", "*.js"]
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import {
import { ProcessFilterCloudModel } from '../models/process-filter-cloud.model';
import { IdentityUserService } from '../../../people/services/identity-user.service';
import { NotificationCloudService } from '../../../services/notification-cloud.service';
import { provideMockFeatureFlags } from '@alfresco/adf-core/feature-flags';

describe('ProcessFilterCloudService', () => {
let service: ProcessFilterCloudService;
Expand All @@ -53,10 +52,7 @@ describe('ProcessFilterCloudService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ProcessServiceCloudTestingModule],
providers: [
{ provide: PROCESS_FILTERS_SERVICE_TOKEN, useClass: LocalPreferenceCloudService },
provideMockFeatureFlags({ ['studio-ws-graphql-subprotocol']: false })
]
providers: [{ provide: PROCESS_FILTERS_SERVICE_TOKEN, useClass: LocalPreferenceCloudService }]
});
service = TestBed.inject(ProcessFilterCloudService);

Expand All @@ -72,7 +68,7 @@ describe('ProcessFilterCloudService', () => {
});

it('should create processfilter key by using appName and the username', (done) => {
service.getProcessFilters('mock-appName').subscribe((res: ProcessFilterCloudModel[]) => {
service.getProcessFilters('mock-appName').subscribe((res: any) => {
expect(res).toBeDefined();
expect(getCurrentUserInfoSpy).toHaveBeenCalled();
done();
Expand Down Expand Up @@ -141,7 +137,7 @@ describe('ProcessFilterCloudService', () => {
it('should create the process filters in case the filters are not exist in the user preferences', (done) => {
getPreferencesSpy.and.returnValue(of(fakeProcessCloudFilterWithDifferentEntries));

service.getProcessFilters('mock-appName').subscribe((res: ProcessFilterCloudModel[]) => {
service.getProcessFilters('mock-appName').subscribe((res: any) => {
expect(res).toBeDefined();
expect(res).not.toBeNull();
expect(res.length).toBe(3);
Expand Down Expand Up @@ -247,7 +243,6 @@ describe('ProcessFilterCloudService', () => {
it('should reset filters to default values', async () => {
const changedFilter = new ProcessFilterCloudModel(fakeProcessCloudFilters[0]);
changedFilter.processDefinitionKey = 'modifiedProcessDefinitionKey';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
spyOn<any>(service, 'defaultProcessFilters').and.returnValue(fakeProcessCloudFilters);

await service.resetProcessFilterToDefaults('mock-appName', changedFilter).toPromise();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@
import { TestBed } from '@angular/core/testing';
import { ProcessServiceCloudTestingModule } from '../testing/process-service-cloud.testing.module';
import { NotificationCloudService } from './notification-cloud.service';
import { WebSocketService } from './web-socket.service';
import { provideMockFeatureFlags } from '@alfresco/adf-core/feature-flags';
import { Apollo } from 'apollo-angular';

describe('NotificationCloudService', () => {
let service: NotificationCloudService;
let wsService: WebSocketService;
let apollo: Apollo;
let apolloCreateSpy: jasmine.Spy;
let apolloSubscribeSpy: jasmine.Spy;

const useMock: any = {
subscribe: () => {}
};

const queryMock = `
subscription {
Expand All @@ -38,25 +43,39 @@ describe('NotificationCloudService', () => {

beforeEach(() => {
TestBed.configureTestingModule({
imports: [ProcessServiceCloudTestingModule],
providers: [WebSocketService, provideMockFeatureFlags({ ['studio-ws-graphql-subprotocol']: false })]
imports: [ProcessServiceCloudTestingModule]
});
service = TestBed.inject(NotificationCloudService);
wsService = TestBed.inject(WebSocketService);
apollo = TestBed.inject(Apollo);

service.appsListening = [];
apolloCreateSpy = spyOn(apollo, 'createNamed');
apolloSubscribeSpy = spyOn(apollo, 'use').and.returnValue(useMock);
});

it('should call getSubscription with the correct parameters', () => {
const getSubscriptionSpy = spyOn(wsService, 'getSubscription').and.callThrough();
it('should not create more than one websocket per app if it was already created', () => {
service.makeGQLQuery('myAppName', queryMock);
expect(service.appsListening.length).toBe(1);
expect(service.appsListening[0]).toBe('myAppName');

service.makeGQLQuery('myAppName', queryMock);
expect(service.appsListening.length).toBe(1);
expect(service.appsListening[0]).toBe('myAppName');

expect(getSubscriptionSpy).toHaveBeenCalledWith({
apolloClientName: 'myAppName',
wsUrl: 'myAppName/notifications',
httpUrl: 'myAppName/notifications/graphql',
subscriptionOptions: {
query: jasmine.any(Object)
}
});
expect(apolloCreateSpy).toHaveBeenCalledTimes(1);
expect(apolloSubscribeSpy).toHaveBeenCalledTimes(2);
});

it('should create new websocket if it is subscribing to new app', () => {
service.makeGQLQuery('myAppName', queryMock);
expect(service.appsListening.length).toBe(1);
expect(service.appsListening[0]).toBe('myAppName');

service.makeGQLQuery('myOtherAppName', queryMock);
expect(service.appsListening.length).toBe(2);
expect(service.appsListening[1]).toBe('myOtherAppName');

expect(apolloCreateSpy).toHaveBeenCalledTimes(2);
expect(apolloSubscribeSpy).toHaveBeenCalledTimes(2);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,101 @@
* limitations under the License.
*/

import { gql } from '@apollo/client/core';
import { Apollo } from 'apollo-angular';
import { HttpLink } from 'apollo-angular/http';
import { split, gql, InMemoryCache, ApolloLink, InMemoryCacheConfig } from '@apollo/client/core';
import { WebSocketLink } from '@apollo/client/link/ws';
import { onError } from '@apollo/client/link/error';
import { getMainDefinition } from '@apollo/client/utilities';
import { Injectable } from '@angular/core';
import { WebSocketService } from './web-socket.service';
import { AuthenticationService } from '@alfresco/adf-core';
import { BaseCloudService } from './base-cloud.service';
import { AdfHttpClient } from '@alfresco/adf-core/api';

@Injectable({
providedIn: 'root'
})
export class NotificationCloudService {
constructor(private readonly webSocketService: WebSocketService) {}
export class NotificationCloudService extends BaseCloudService {
appsListening = [];

constructor(public apollo: Apollo, private http: HttpLink, private authService: AuthenticationService, protected adfHttpClient: AdfHttpClient) {
super(adfHttpClient);
}

private get webSocketHost() {
return this.contextRoot.split('://')[1];
}

private get protocol() {
return this.contextRoot.split('://')[0] === 'https' ? 'wss' : 'ws';
}

initNotificationsForApp(appName: string) {
if (!this.appsListening.includes(appName)) {
this.appsListening.push(appName);
const httpLink = this.http.create({
uri: `${this.getBasePath(appName)}/notifications/graphql`
});

const webSocketLink = new WebSocketLink({
uri: `${this.protocol}://${this.webSocketHost}/${appName}/notifications/ws/graphql`,
options: {
reconnect: true,
lazy: true,
connectionParams: {
kaInterval: 2000,
// eslint-disable-next-line @typescript-eslint/naming-convention
'X-Authorization': 'Bearer ' + this.authService.getToken()
}
}
});

const link = split(
({ query }) => {
const definition = getMainDefinition(query);
return definition.kind === 'OperationDefinition' && definition.operation === 'subscription';
},
webSocketLink,
httpLink
);

const errorLink = onError(({ graphQLErrors, operation, forward }) => {
if (graphQLErrors) {
for (const err of graphQLErrors) {
switch (err.extensions.code) {
case 'UNAUTHENTICATED': {
const oldHeaders = operation.getContext().headers;
operation.setContext({
headers: {
...oldHeaders,
// eslint-disable-next-line @typescript-eslint/naming-convention
'X-Authorization': 'Bearer ' + this.authService.getToken()
}
});
forward(operation);
break;
}
default:
break;
}
}
}
});

this.apollo.createNamed(appName, {
link: ApolloLink.from([errorLink, link]),
cache: new InMemoryCache({ merge: true } as InMemoryCacheConfig),
defaultOptions: {
watchQuery: {
errorPolicy: 'all'
}
}
});
}
}

makeGQLQuery(appName: string, gqlQuery: string) {
return this.webSocketService.getSubscription({
apolloClientName: appName,
wsUrl: `${appName}/notifications`,
httpUrl: `${appName}/notifications/graphql`,
subscriptionOptions: {
query: gql(gqlQuery)
}
});
this.initNotificationsForApp(appName);
return this.apollo.use(appName).subscribe({ query: gql(gqlQuery) });
}
}
1 change: 0 additions & 1 deletion lib/process-services-cloud/src/lib/services/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,3 @@ export * from './form-fields.interfaces';
export * from './base-cloud.service';
export * from './task-list-cloud.service.interface';
export * from './variable-mapper.sevice';
export * from './web-socket.service';
135 changes: 0 additions & 135 deletions lib/process-services-cloud/src/lib/services/web-socket.service.spec.ts

This file was deleted.

Loading

0 comments on commit 6798c92

Please sign in to comment.