Skip to content

Commit 7fdc65b

Browse files
committed
Add APIs to support configurable output (data provider)
- Add ConfigurationQuery and OutputConfigurationQuery - Add utility methods in query-helper.ts to create such query instances - Add configuration service per output (data provider) This addition enables clients to create derived data providers from an existing data provider. - Add unit tests Signed-off-by: Bernd Hufmann <[email protected]>
1 parent 98fbdcc commit 7fdc65b

File tree

7 files changed

+329
-13
lines changed

7 files changed

+329
-13
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"parentId": "org.eclipse.tracecompass.incubator.inandout.core.analysis.inAndOutDataProviderFactory",
3+
"id": "org.eclipse.tracecompass.incubator.inandout.analysis85eec6d6-bea0-3680-84b6-f1a200e852d1",
4+
"name": "InAndOut Analysis (My new InAndOut)",
5+
"description": "Custom InAndOut analysis configured by \"My new InAndOut\"",
6+
"type": "NONE",
7+
"configuration": {
8+
"id": "85eec6d6-bea0-3680-84b6-f1a200e852d1",
9+
"name": "My new InAndOut",
10+
"description": "My special configuration",
11+
"sourceTypeId": "org.eclipse.tracecompass.incubator.internal.inandout.core.config",
12+
"parameters": {
13+
"specifiers": [
14+
{
15+
"label": "latency",
16+
"inRegex": "(\\S*)_entry",
17+
"outRegex": "(\\S*)_exit",
18+
"contextInRegex": "(\\S*)_entry",
19+
"contextOutRegex": "(\\S*)_exit",
20+
"classifier": "CPU"
21+
}
22+
]
23+
}
24+
}
25+
}

tsp-typescript-client/src/models/query/query-helper.test.ts

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { QueryHelper } from './query-helper';
2-
import { Query } from './query';
2+
import { ConfigurationQuery, OutputConfigurationQuery, Query } from './query';
33

44
describe('Query helper tests', () => {
55
it('Should build a simple query', () => {
@@ -105,4 +105,50 @@ describe('Query helper tests', () => {
105105

106106
expect(test).toEqual(array);
107107
});
108+
109+
it('Should create a configuration query', () => {
110+
const param = {
111+
cpu: 0,
112+
thread: "myThread"
113+
};
114+
115+
const test = QueryHelper.configurationQuery(
116+
'My Config',
117+
'My special configuration',
118+
param);
119+
120+
const query = new ConfigurationQuery('My Config',
121+
'My special configuration',
122+
param);
123+
124+
expect(test).toEqual(query);
125+
});
126+
127+
it('Should create a output configuration query', () => {
128+
const param = {
129+
specifiers: [
130+
{
131+
label: 'latency',
132+
inRegex: '(\\S*)_entry',
133+
outRegex: '(\\S*)_exit',
134+
contextInRegex: '(\\S*)_entry',
135+
contextOutRegex: '(\\S*)_exit',
136+
classifier: 'CPU'
137+
}
138+
]
139+
};
140+
141+
const test = QueryHelper.outputConfigurationQuery(
142+
'My new InAndOut',
143+
'org.eclipse.tracecompass.incubator.internal.inandout.core.config',
144+
'My special configuration',
145+
param);
146+
147+
const query = new OutputConfigurationQuery('My new InAndOut',
148+
'org.eclipse.tracecompass.incubator.internal.inandout.core.config',
149+
'My special configuration',
150+
param);
151+
152+
expect(test).toEqual(query);
153+
});
108154
});

tsp-typescript-client/src/models/query/query-helper.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Query } from './query';
1+
import { ConfigurationQuery, OutputConfigurationQuery, Query } from './query';
22

33
/**
44
* Helper class to create query object
@@ -163,6 +163,27 @@ export class QueryHelper {
163163
return new Query({ ...tableObj, ...additionalProperties });
164164
}
165165

166+
/**
167+
* Build a configuration query
168+
* @param name the name of the configuration
169+
* @param description the optional description of the configuration
170+
* @param parameters the custom parameters
171+
*/
172+
public static configurationQuery(name: string, description: string | undefined, parameters: { [key: string]: any }) {
173+
return new ConfigurationQuery(name, description, parameters);
174+
}
175+
176+
/**
177+
* Build a output configuration query
178+
* @param name the name of the configuration
179+
* @param description the optional description of the configuration
180+
* @param typeId the configuration type ID
181+
* @param parameters the custom parameters
182+
*/
183+
public static outputConfigurationQuery(name: string, description: string | undefined, typeId: string, parameters: { [key: string]: any }) {
184+
return new OutputConfigurationQuery(name, description, typeId, parameters);
185+
}
186+
166187
/**
167188
* Split the range into equal parts
168189
* @param start Start time

tsp-typescript-client/src/models/query/query.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,47 @@ export class Query {
1919
this.parameters = parameters;
2020
}
2121
}
22+
export class ConfigurationQuery extends Query {
23+
/**
24+
* Name of the configuration
25+
*/
26+
// @ts-expect-error TS doesn't like unused private fields.
27+
private name: string;
28+
29+
/**
30+
* The optional description of configuration
31+
*/
32+
// @ts-expect-error TS doesn't like unused private fields.
33+
private description?: string;
34+
35+
/**
36+
* Constructor
37+
* @param name Name of the configuration
38+
* @param parameters Object used to send parameters to the server
39+
* @param description Optional description of the configuraiton
40+
*/
41+
constructor(name: string, descripion: string | undefined, parameters: Object) {
42+
super(parameters);
43+
this.name = name;
44+
this.description = descripion;
45+
}
46+
}
47+
export class OutputConfigurationQuery extends ConfigurationQuery {
48+
/**
49+
* The configuration source type ID
50+
*/
51+
// @ts-expect-error TS doesn't like unused private fields.
52+
private typeId: string;
53+
54+
/**
55+
* Constructor
56+
* @param name Name of the configuration
57+
* @param description Optional description of the configuraiton
58+
* @param typeId The ID of the configuration source type
59+
* @param parameters Object used to send parameters to the server
60+
*/
61+
constructor(name: string, description: string | undefined, typeId: string, parameters: Object) {
62+
super(name, description, parameters);
63+
this.typeId = typeId;
64+
}
65+
}

tsp-typescript-client/src/protocol/http-tsp-client.ts

Lines changed: 91 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { HealthStatus } from "../models/health";
1111
import { Identifier } from "../models/identifier";
1212
import { MarkerSet } from "../models/markerset";
1313
import { OutputDescriptor } from "../models/output-descriptor";
14-
import { Query } from "../models/query/query";
14+
import { ConfigurationQuery, OutputConfigurationQuery, Query } from "../models/query/query";
1515
import { GenericResponse } from "../models/response/responses";
1616
import { OutputStyleModel } from "../models/styles";
1717
import { ColumnHeaderEntry, TableModel } from "../models/table";
@@ -511,6 +511,92 @@ export class HttpTspClient implements ITspClient {
511511
return RestClient.post(url, parameters);
512512
}
513513

514+
/**
515+
* Fetch all configuration source types for a given experiment and output
516+
* @param expUUID Experiment UUID
517+
* @param outputID Output ID
518+
* @returns Generic response with the model
519+
*/
520+
public async fetchOutputConfigurationTypes(
521+
expUUID: string,
522+
outputID: string
523+
): Promise<TspClientResponse<ConfigurationSourceType[]>> {
524+
const url =
525+
this.baseUrl +
526+
"/experiments/" +
527+
expUUID +
528+
"/outputs/" +
529+
outputID +
530+
"/configTypes";
531+
return RestClient.get(url);
532+
}
533+
534+
/**
535+
* Fetch a single configuration source type for a given experiment, output and type
536+
* @param expUUID Experiment UUID
537+
* @param outputID Output ID
538+
* @param typeID the ID of the configuration source type
539+
* @returns Generic response with the model
540+
*/
541+
public async fetchOutputConfigurationType(
542+
expUUID: string,
543+
outputID: string,
544+
typeID: string
545+
): Promise<TspClientResponse<ConfigurationSourceType>> {
546+
const url =
547+
this.baseUrl +
548+
"/experiments/" +
549+
expUUID +
550+
"/outputs/" +
551+
outputID +
552+
"/configTypes/" +
553+
typeID;
554+
return RestClient.get(url);
555+
}
556+
557+
/**
558+
* Create a derived output for a given experiment, output and parameters
559+
* @param expUUID Experiment UUID
560+
* @param outputID Output ID
561+
* @param parameters OutputConfigurationQuery object
562+
* @returns Generic response with the model
563+
*/
564+
public async createDerivedOutput(
565+
expUUID: string,
566+
outputID: string,
567+
parameters: OutputConfigurationQuery): Promise<TspClientResponse<OutputDescriptor>> {
568+
const url =
569+
this.baseUrl +
570+
"/experiments/" +
571+
expUUID +
572+
"/outputs/" +
573+
outputID;
574+
return RestClient.post(url, parameters, OutputDescriptor);
575+
}
576+
577+
/**
578+
* Delete a derived output (and its configuration) for a given experiment,
579+
* output and derived output
580+
* @param expUUID Experiment UUID
581+
* @param outputID Output ID
582+
* @param derivedOutputID the ID of the derived output
583+
* @returns Generic response with the model
584+
*/
585+
public async deleteDerivedOutput(
586+
expUUID: string,
587+
outputID: string,
588+
derivedOutputID: string): Promise<TspClientResponse<OutputDescriptor>> {
589+
const url =
590+
this.baseUrl +
591+
"/experiments/" +
592+
expUUID +
593+
"/outputs/" +
594+
outputID +
595+
"/" +
596+
derivedOutputID;
597+
return RestClient.delete(url, undefined, OutputDescriptor);
598+
}
599+
514600
/**
515601
* Check the health status of the server
516602
* @returns The Health Status
@@ -572,10 +658,10 @@ export class HttpTspClient implements ITspClient {
572658
/**
573659
* Create a configuration for a given type ID and parameters
574660
* @param typeId the ID of the configuration source type
575-
* @param parameters Query object
661+
* @param parameters ConfigurationQuery object
576662
* @returns Generic response with the model
577663
*/
578-
createConfiguration(typeId: string, parameters: Query): Promise<TspClientResponse<Configuration>> {
664+
createConfiguration(typeId: string, parameters: ConfigurationQuery): Promise<TspClientResponse<Configuration>> {
579665
const url = this.baseUrl + "/config/types/" + typeId;
580666
return RestClient.post(url, parameters);
581667
}
@@ -584,10 +670,10 @@ export class HttpTspClient implements ITspClient {
584670
* Update a configuration for a given type ID, config ID and parameters
585671
* @param typeId the ID of the configuration source type
586672
* @param configId the ID of the configuration
587-
* @param parameters Query object
673+
* @param parameters ConfigurationQuery object
588674
* @returns Generic response with the model
589675
*/
590-
updateConfiguration(typeId: string, configId: string, parameters: Query): Promise<TspClientResponse<Configuration>> {
676+
updateConfiguration(typeId: string, configId: string, parameters: ConfigurationQuery): Promise<TspClientResponse<Configuration>> {
591677
const url = this.baseUrl + "/config/types/" + typeId + "/configs/" + configId;
592678
return RestClient.put(url, parameters);
593679
}

tsp-typescript-client/src/protocol/tsp-client.test.ts

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { Headers } from 'node-fetch';
2-
import { Query } from '../models/query/query';
2+
import { ConfigurationQuery, OutputConfigurationQuery, Query } from '../models/query/query';
33
import { HttpRequest, HttpResponse, RestClient } from './rest-client';
44
import { FixtureSet } from './test-utils';
55
import { HttpTspClient } from './http-tsp-client';
66
import { DataType } from '../models/data-type';
77
import { ConfigurationParameterDescriptor } from '../models/configuration-source';
8+
import { QueryHelper } from '../models/query/query-helper';
89

910
describe('HttpTspClient Deserialization', () => {
1011

@@ -474,7 +475,7 @@ describe('HttpTspClient Deserialization', () => {
474475

475476
it('createConfiguration', async () => {
476477
httpRequestMock.mockReturnValueOnce(fixtures.asResponse('configuration-0.json'));
477-
const response = await client.createConfiguration("my-source-type-1-id", new Query({}));
478+
const response = await client.createConfiguration("my-source-type-1-id", new ConfigurationQuery('', undefined, {}));
478479
const config = response.getModel()!;
479480

480481
expect(config.name).toEqual('My configuration 1');
@@ -487,7 +488,7 @@ describe('HttpTspClient Deserialization', () => {
487488

488489
it('updateConfiguration', async () => {
489490
httpRequestMock.mockReturnValueOnce(fixtures.asResponse('configuration-0.json'));
490-
const response = await client.updateConfiguration("my-source-type-1-id", "my-config-1-id", new Query({}));
491+
const response = await client.updateConfiguration("my-source-type-1-id", "my-config-1-id", new ConfigurationQuery('', undefined, {}));
491492
const config = response.getModel()!;
492493

493494
expect(config.name).toEqual('My configuration 1');
@@ -511,4 +512,48 @@ describe('HttpTspClient Deserialization', () => {
511512
expect(config.parameters?.path).toEqual('/home/user/tmp');
512513
});
513514

515+
it('createOutputConfiguration', async () => {
516+
httpRequestMock.mockReturnValueOnce(fixtures.asResponse('output-configuration-0.json'));
517+
const config: OutputConfigurationQuery = QueryHelper.outputConfigurationQuery(
518+
'My new InAndOut',
519+
'org.eclipse.tracecompass.incubator.internal.inandout.core.config',
520+
'My special configuration',
521+
{
522+
specifiers: [
523+
{
524+
label: 'latency',
525+
inRegex: '(\\S*)_entry',
526+
outRegex: '(\\S*)_exit',
527+
contextInRegex: '(\\S*)_entry',
528+
contextOutRegex: '(\\S*)_exit',
529+
classifier: 'CPU'
530+
}
531+
]
532+
}
533+
);
534+
535+
const response = await client.createDerivedOutput(
536+
'd280b5ab-b0ff-38cf-b3e1-d33a0d56d1a3',
537+
'org.eclipse.tracecompass.incubator.inandout.core.analysis.inAndOutDataProviderFactory',
538+
config);
539+
540+
const output = response.getModel()!;
541+
expect(output.name).toEqual('InAndOut Analysis (My new InAndOut)');
542+
expect(output.description).toEqual('Custom InAndOut analysis configured by "My new InAndOut"');
543+
expect(output.id).toEqual('org.eclipse.tracecompass.incubator.inandout.analysis85eec6d6-bea0-3680-84b6-f1a200e852d1');
544+
expect(output.parentId).toBeDefined();
545+
expect(output.parentId).toEqual('org.eclipse.tracecompass.incubator.inandout.core.analysis.inAndOutDataProviderFactory');
546+
expect(output.configuration).toBeDefined();
547+
});
548+
549+
it('deleteOutputConfiguration', async () => {
550+
httpRequestMock.mockReturnValueOnce(fixtures.asResponse('output-configuration-0.json'));
551+
const response = await client.deleteDerivedOutput(
552+
'd280b5ab-b0ff-38cf-b3e1-d33a0d56d1a3',
553+
'org.eclipse.tracecompass.incubator.inandout.core.analysis.inAndOutdataProviderFactory',
554+
'org.eclipse.tracecompass.incubator.inandout.analysis85eec6d6-bea0-3680-84b6-f1a200e852d1');
555+
556+
const output = response.getModel()!;
557+
expect(output).toBeDefined();
558+
});
514559
});

0 commit comments

Comments
 (0)