Skip to content

Commit

Permalink
Refactor server communication to JSON-RPC
Browse files Browse the repository at this point in the history
TspClient Proxy:
Provide an implementation of the ITspClient called `TheiaRpcTspProxy`.
The implementation forwards all calls to a JSON RPC proxy called `TheiaClientProxy`.
Responses are then mapped to a `TspClientResponse`.
On the backend the `TheiaClientProxy` returns a lazyTspClient.
The lazyTspClient returns a `HttpTspClient` (default implementation).

Trace Server url provider:
The implementation of the provider was moved to the backend.
This way the env variable can be read out directly.
For the port preference a proxy mechanism was added.
Changes to the preference are sent via JSON RPC and handled by the url provider.

Trace Server connection status:
The implementation was moved to the backend.
Frontends can register themselves on the backend.
Each registered frontend will be pinged when the status has changed.

Misc:
Use `ITspClient` instead of `TspClient` for types, as `TspClient` is deprecated.

Fixes eclipse-cdt-cloud#976

Contributed on behalf of STMicroelectronics
  • Loading branch information
sgraband committed Sep 13, 2023
1 parent 10971b4 commit 37e20b2
Show file tree
Hide file tree
Showing 14 changed files with 624 additions and 95 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { FrontendApplicationContribution } from '@theia/core/lib/browser';
import { inject, injectable } from 'inversify';
import { PortPreferenceProxy } from '../common/trace-server-url-provider';
import { TracePreferences, TRACE_PORT } from './trace-server-preference';

@injectable()
export class PreferencesFrontendContribution implements FrontendApplicationContribution {
constructor(
@inject(TracePreferences) protected tracePreferences: TracePreferences,
@inject(PortPreferenceProxy) protected portPreferenceProxy: PortPreferenceProxy
) {}

async initialize(): Promise<void> {
this.tracePreferences.ready.then(() => {
this.portPreferenceProxy.onPortPreferenceChanged(this.tracePreferences[TRACE_PORT]);
this.tracePreferences.onPreferenceChanged(async event => {
const newValue = typeof event.newValue === 'string' ? parseInt(event.newValue) : event.newValue;
const oldValue = typeof event.oldValue === 'string' ? parseInt(event.oldValue) : event.oldValue;
this.portPreferenceProxy.onPortPreferenceChanged(newValue, oldValue, true);
});
});
}
}
371 changes: 371 additions & 0 deletions theia-extensions/viewer-prototype/src/browser/theia-rpc-tsp-proxy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,371 @@
import { inject, injectable, interfaces } from '@theia/core/shared/inversify';
import { ITspClient } from 'tsp-typescript-client/lib/protocol/tsp-client';
import { TspClientResponse } from 'tsp-typescript-client/lib/protocol/tsp-client-response';
import { Trace } from 'tsp-typescript-client/lib/models/trace';
import { Query } from 'tsp-typescript-client/lib/models/query/query';
import { Experiment } from 'tsp-typescript-client/lib/models/experiment';
import { GenericResponse } from 'tsp-typescript-client/lib/models/response/responses';
import { HealthStatus } from 'tsp-typescript-client/lib/models/health';
import { XyEntry, XYModel } from 'tsp-typescript-client/lib/models/xy';
import { TimeGraphEntry, TimeGraphArrow, TimeGraphModel } from 'tsp-typescript-client/lib/models/timegraph';
import { AnnotationCategoriesModel, AnnotationModel } from 'tsp-typescript-client/lib/models/annotation';
import { TableModel, ColumnHeaderEntry } from 'tsp-typescript-client/lib/models/table';
import { OutputDescriptor } from 'tsp-typescript-client/lib/models/output-descriptor';
import { EntryModel } from 'tsp-typescript-client/lib/models/entry';
import { OutputStyleModel } from 'tsp-typescript-client/lib/models/styles';
import { MarkerSet } from 'tsp-typescript-client/lib/models/markerset';
import { DataTreeEntry } from 'tsp-typescript-client/lib/models/data-tree';

export const TspClientProxy = Symbol('TspClientProxy') as symbol & interfaces.Abstract<TspClientProxy>;
export type TspClientProxy = ITspClient;

@injectable()
export class TheiaRpcTspProxy implements ITspClient {
public constructor(@inject(TspClientProxy) protected tspClient: ITspClient) {}

// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
protected toTspClientResponse<T>(result: any): TspClientResponse<T> {
const tspClientResponse: TspClientResponse<T> = new TspClientResponse(
result.text,
result.statusCode,
result.statusMessage,
result.responseModel
);
return tspClientResponse;
}

/**
* Fetch all available traces on the server
* @returns List of Trace
*/
public async fetchTraces(): Promise<TspClientResponse<Trace[]>> {
return this.toTspClientResponse<Trace[]>(await this.tspClient.fetchTraces());
}

/**
* Fetch a specific trace information
* @param traceUUID Trace UUID to fetch
*/
public async fetchTrace(traceUUID: string): Promise<TspClientResponse<Trace>> {
return this.toTspClientResponse<Trace>(await this.tspClient.fetchTrace(traceUUID));
}

/**
* Open a trace on the server
* @param parameters Query object
* @returns The opened trace
*/
public async openTrace(parameters: Query): Promise<TspClientResponse<Trace>> {
return this.toTspClientResponse<Trace>(await this.tspClient.openTrace(parameters));
}

/**
* Delete a trace on the server
* @param traceUUID Trace UUID to delete
* @param deleteTrace Also delete the trace from disk
* @param removeCache Remove all cache for this trace
* @returns The deleted trace
*/
public async deleteTrace(
traceUUID: string,
deleteTrace?: boolean,
removeCache?: boolean
): Promise<TspClientResponse<Trace>> {
return this.toTspClientResponse<Trace>(await this.tspClient.deleteTrace(traceUUID, deleteTrace, removeCache));
}

/**
* Fetch all available experiments on the server
* @returns List of Experiment
*/
public async fetchExperiments(): Promise<TspClientResponse<Experiment[]>> {
return this.toTspClientResponse<Experiment[]>(await this.tspClient.fetchExperiments());
}

/**
* Fetch a specific experiment information
* @param expUUID Experiment UUID to fetch
* @returns The experiment
*/
public async fetchExperiment(expUUID: string): Promise<TspClientResponse<Experiment>> {
return this.toTspClientResponse<Experiment>(await this.tspClient.fetchExperiment(expUUID));
}

/**
* Create an experiment on the server
* @param parameters Query object
* @returns The created experiment
*/
public async createExperiment(parameters: Query): Promise<TspClientResponse<Experiment>> {
return this.toTspClientResponse<Experiment>(await this.tspClient.createExperiment(parameters));
}

/**
* Update an experiment
* @param expUUID Experiment UUID to update
* @param parameters Query object
* @returns The updated experiment
*/
public async updateExperiment(expUUID: string, parameters: Query): Promise<TspClientResponse<Experiment>> {
return this.toTspClientResponse<Experiment>(await this.tspClient.updateExperiment(expUUID, parameters));
}

/**
* Delete an experiment on the server
* @param expUUID Experiment UUID to delete
* @returns The deleted experiment
*/
public async deleteExperiment(expUUID: string): Promise<TspClientResponse<Experiment>> {
return this.toTspClientResponse<Experiment>(await this.tspClient.deleteExperiment(expUUID));
}

/**
* List all the outputs associated to this experiment
* @param expUUID Experiment UUID
* @returns List of OutputDescriptor
*/
public async experimentOutputs(expUUID: string): Promise<TspClientResponse<OutputDescriptor[]>> {
return this.toTspClientResponse<OutputDescriptor[]>(await this.tspClient.experimentOutputs(expUUID));
}

/**
* Fetch Data tree
* @param expUUID Experiment UUID
* @param outputID Output ID
* @param parameters Query object
* @returns Generic entry response with entries
*/
public async fetchDataTree(
expUUID: string,
outputID: string,
parameters: Query
): Promise<TspClientResponse<GenericResponse<EntryModel<DataTreeEntry>>>> {
return this.toTspClientResponse<GenericResponse<EntryModel<DataTreeEntry>>>(
await this.tspClient.fetchDataTree(expUUID, outputID, parameters)
);
}

/**
* Fetch XY tree
* @param expUUID Experiment UUID
* @param outputID Output ID
* @param parameters Query object
* @returns Generic entry response with entries
*/
public async fetchXYTree(
expUUID: string,
outputID: string,
parameters: Query
): Promise<TspClientResponse<GenericResponse<EntryModel<XyEntry>>>> {
return this.toTspClientResponse<GenericResponse<EntryModel<XyEntry>>>(
await this.tspClient.fetchXYTree(expUUID, outputID, parameters)
);
}

/**
* Fetch XY. model extends XYModel
* @param expUUID Experiment UUID
* @param outputID Output ID
* @param parameters Query object
* @returns XY model response with the model
*/
public async fetchXY(
expUUID: string,
outputID: string,
parameters: Query
): Promise<TspClientResponse<GenericResponse<XYModel>>> {
return this.toTspClientResponse<GenericResponse<XYModel>>(
await this.tspClient.fetchXY(expUUID, outputID, parameters)
);
}

/**
* Fetch XY tooltip
* @param expUUID Experiment UUID
* @param outputID Output ID
* @param xValue X value
* @param yValue Optional Y value
* @param seriesID Optional series ID
* @returns Map of key=name of the property and value=string value associated
*/
public async fetchXYToolTip(
expUUID: string,
outputID: string,
xValue: number,
yValue?: number,
seriesID?: string
): Promise<TspClientResponse<GenericResponse<{ [key: string]: string }>>> {
return this.toTspClientResponse<GenericResponse<{ [key: string]: string }>>(
await this.tspClient.fetchXYToolTip(expUUID, outputID, xValue, yValue, seriesID)
);
}

/**
* Fetch Time Graph tree, Model extends TimeGraphEntry
* @param expUUID Experiment UUID
* @param outputID Output ID
* @param parameters Query object
* @returns Time graph entry response with entries of type TimeGraphEntry
*/
public async fetchTimeGraphTree(
expUUID: string,
outputID: string,
parameters: Query
): Promise<TspClientResponse<GenericResponse<EntryModel<TimeGraphEntry>>>> {
return this.toTspClientResponse<GenericResponse<EntryModel<TimeGraphEntry>>>(
await this.tspClient.fetchTimeGraphTree(expUUID, outputID, parameters)
);
}

/**
* Fetch Time Graph states. Model extends TimeGraphModel
* @param expUUID Experiment UUID
* @param outputID Output ID
* @param parameters Query object
* @returns Generic response with the model
*/
public async fetchTimeGraphStates(
expUUID: string,
outputID: string,
parameters: Query
): Promise<TspClientResponse<GenericResponse<TimeGraphModel>>> {
return this.toTspClientResponse<GenericResponse<TimeGraphModel>>(
await this.tspClient.fetchTimeGraphStates(expUUID, outputID, parameters)
);
}

/**
* Fetch Time Graph arrows. Model extends TimeGraphArrow
* @param expUUID Experiment UUID
* @param outputID Output ID
* @param parameters Query object
* @returns Generic response with the model
*/
public async fetchTimeGraphArrows(
expUUID: string,
outputID: string,
parameters: Query
): Promise<TspClientResponse<GenericResponse<TimeGraphArrow[]>>> {
return this.toTspClientResponse<GenericResponse<TimeGraphArrow[]>>(
await this.tspClient.fetchTimeGraphArrows(expUUID, outputID, parameters)
);
}

/**
* Fetch marker sets.
* @returns Generic response with the model
*/
public async fetchMarkerSets(expUUID: string): Promise<TspClientResponse<GenericResponse<MarkerSet[]>>> {
return this.toTspClientResponse<GenericResponse<MarkerSet[]>>(await this.tspClient.fetchMarkerSets(expUUID));
}

/**
* Fetch annotations categories.
* @param expUUID Experiment UUID
* @param outputID Output ID
* @param markerSetId Marker Set ID
* @returns Generic response with the model
*/
public async fetchAnnotationsCategories(
expUUID: string,
outputID: string,
markerSetId?: string
): Promise<TspClientResponse<GenericResponse<AnnotationCategoriesModel>>> {
return this.toTspClientResponse<GenericResponse<AnnotationCategoriesModel>>(
await this.tspClient.fetchAnnotationsCategories(expUUID, outputID, markerSetId)
);
}

/**
* Fetch annotations.
* @param expUUID Experiment UUID
* @param outputID Output ID
* @param parameters Query object
* @returns Generic response with the model
*/
public async fetchAnnotations(
expUUID: string,
outputID: string,
parameters: Query
): Promise<TspClientResponse<GenericResponse<AnnotationModel>>> {
return this.toTspClientResponse<GenericResponse<AnnotationModel>>(
await this.tspClient.fetchAnnotations(expUUID, outputID, parameters)
);
}

/**
* Fetch tooltip for a Time Graph element.
* @param expUUID Experiment UUID
* @param outputID Output ID
* @param parameters Query object
* @returns Map of key=name of the property and value=string value associated
*/
public async fetchTimeGraphTooltip(
expUUID: string,
outputID: string,
parameters: Query
): Promise<TspClientResponse<GenericResponse<{ [key: string]: string }>>> {
return this.toTspClientResponse<GenericResponse<{ [key: string]: string }>>(
await this.tspClient.fetchTimeGraphTooltip(expUUID, outputID, parameters)
);
}

/**
* Fetch Table columns
* @param expUUID Experiment UUID
* @param outputID Output ID
* @param parameters Query object
* @returns Generic entry response with columns headers as model
*/
public async fetchTableColumns(
expUUID: string,
outputID: string,
parameters: Query
): Promise<TspClientResponse<GenericResponse<ColumnHeaderEntry[]>>> {
return this.toTspClientResponse<GenericResponse<ColumnHeaderEntry[]>>(
await this.tspClient.fetchTableColumns(expUUID, outputID, parameters)
);
}

/**
* Fetch Table lines
* @param expUUID Experiment UUID
* @param outputID Output ID
* @param parameters Query object
* @returns Generic response with the model
*/
public async fetchTableLines(
expUUID: string,
outputID: string,
parameters: Query
): Promise<TspClientResponse<GenericResponse<TableModel>>> {
return this.toTspClientResponse<GenericResponse<TableModel>>(
await this.tspClient.fetchTableLines(expUUID, outputID, parameters)
);
}

/**
* Fetch output styles
* @param expUUID Experiment UUID
* @param outputID Output ID
* @param parameters Query object
* @returns Generic response with the model
*/
public async fetchStyles(
expUUID: string,
outputID: string,
parameters: Query
): Promise<TspClientResponse<GenericResponse<OutputStyleModel>>> {
return this.toTspClientResponse<GenericResponse<OutputStyleModel>>(
await this.tspClient.fetchStyles(expUUID, outputID, parameters)
);
}

/**
* Check the health status of the server
* @returns The Health Status
*/
public async checkHealth(): Promise<TspClientResponse<HealthStatus>> {
return this.toTspClientResponse<HealthStatus>(await this.tspClient.checkHealth());
}
}
Loading

0 comments on commit 37e20b2

Please sign in to comment.