Skip to content

Commit

Permalink
prefix workspace name to paths
Browse files Browse the repository at this point in the history
  • Loading branch information
Tigran Vardanyan committed Jul 18, 2024
1 parent 576518a commit 765683f
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 15 deletions.
84 changes: 84 additions & 0 deletions src/datasources/tag/TagDataSource.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,90 @@ describe('queries', () => {
expect(result.data).toMatchSnapshot();
});

test('history of tags from different workspaces', async () => {
const queryRequest = buildQuery({ type: TagQueryType.History, path: 'my.tag.*' });

backendSrv.fetch
.calledWith(requestMatching({ url: '/nitag/v2/query-tags-with-values', data: { filter: 'path = "my.tag.*"' } }))
.mockReturnValue(createQueryTagsResponse([
{ tag: { path: 'my.tag.1', workspace: '1' } },
{ tag: { path: 'my.tag.2', workspace: '1' } },
{ tag: { path: 'my.tag.3', workspace: '2' } },
{ tag: { path: 'my.tag.4', workspace: '2' } }
]));

backendSrv.fetch
.calledWith(
requestMatching({
url: '/nitaghistorian/v2/tags/query-decimated-history',
data: {
paths: ['my.tag.1', 'my.tag.2'],
workspace: '1',
startTime: queryRequest.range.from.toISOString(),
endTime: queryRequest.range.to.toISOString(),
decimation: 300,
},
})
)
.mockReturnValue(
createTagHistoryResponse([
{
path: 'my.tag.1',
type: TagDataType.DOUBLE,
values: [
{ timestamp: '2023-01-01T00:00:00Z', value: '1' },
{ timestamp: '2023-01-01T00:01:00Z', value: '2' },
],
},
{
path: 'my.tag.2',
type: TagDataType.DOUBLE,
values: [
{ timestamp: '2023-01-01T00:00:00Z', value: '2' },
{ timestamp: '2023-01-01T00:01:00Z', value: '3' },
]
}
])
)

backendSrv.fetch.calledWith(
requestMatching({
url: '/nitaghistorian/v2/tags/query-decimated-history',
data: {
paths: ['my.tag.3', 'my.tag.4'],
workspace: '2',
startTime: queryRequest.range.from.toISOString(),
endTime: queryRequest.range.to.toISOString(),
decimation: 300,
},
})
)
.mockReturnValue(
createTagHistoryResponse([
{
path: 'my.tag.3',
type: TagDataType.DOUBLE,
values: [
{ timestamp: '2023-01-01T00:00:00Z', value: '3' },
{ timestamp: '2023-01-01T00:01:00Z', value: '4' },
],
},
{
path: 'my.tag.4',
type: TagDataType.DOUBLE,
values: [
{ timestamp: '2023-01-01T00:00:00Z', value: '4' },
{ timestamp: '2023-01-01T00:01:00Z', value: '5' },
]
}
])
)

const result = await ds.query(queryRequest);

expect(result.data).toMatchSnapshot();
});

test('decimation parameter does not go above 1000', async () => {
const queryRequest = buildQuery({ type: TagQueryType.History, path: 'my.tag' });
queryRequest.maxDataPoints = 1500;
Expand Down
48 changes: 33 additions & 15 deletions src/datasources/tag/TagDataSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
TimeAndTagTypeValues,
TypeAndValues,
} from './types';
import { Throw } from 'core/utils';
import { Throw, getWorkspaceName } from 'core/utils';

export class TagDataSource extends DataSourceBase<TagQuery> {
constructor(
Expand All @@ -44,7 +44,7 @@ export class TagDataSource extends DataSourceBase<TagQuery> {
this.templateSrv.replace(query.path, scopedVars),
this.templateSrv.replace(query.workspace, scopedVars)
);

const workspaces = await this.getWorkspaces();
const result: DataFrameDTO = { refId: query.refId, fields: [] };

if (query.type === TagQueryType.Current) {
Expand Down Expand Up @@ -78,18 +78,36 @@ export class TagDataSource extends DataSourceBase<TagQuery> {

return result
} else {
const workspaceTagMap: Record<string, TagWithValue[]> = {};
const tagPropertiesMap: Record<string, Record<string, string> | null> = {};
tagsWithValues.forEach((tag: TagWithValue) => {
tagPropertiesMap[tag.tag.path] = tag.tag.properties

tagsWithValues.forEach(tagWithValue => {
let workspace = tagWithValue.tag.workspace ?? tagWithValue.tag.workspace_id
if (!workspaceTagMap[workspace]) {
workspaceTagMap[workspace] = [];
}
workspaceTagMap[workspace].push(tagWithValue);
tagPropertiesMap[`${getWorkspaceName(workspaces, workspace)}.${tagWithValue.tag.path}`] = tagWithValue.tag.properties
});
const workspaceFromFirstTag = tagsWithValues[0].tag.workspace ?? tagsWithValues[0].tag.workspace_id;
const tagHistoryResponse = await this.getTagHistoryWithChunks(
Object.keys(tagPropertiesMap),
workspaceFromFirstTag,
range,
maxDataPoints
)
const mergedTagValuesWithType = this.mergeTagsHistoryValues(tagHistoryResponse.results);
let tagsDecimatedHistory: { [key: string]: TypeAndValues } = {}
for (const workspace in workspaceTagMap) {
const tagHistoryResponse = await this.getTagHistoryWithChunks(
workspaceTagMap[workspace],
workspace,
range,
maxDataPoints
)
for (const path in tagHistoryResponse.results) {
// If tags are mixed from different workspaces, add the workspace name as a prefix
if (Object.keys(workspaceTagMap).length === 1) {
tagsDecimatedHistory[path] = tagHistoryResponse.results[path]
} else {
tagsDecimatedHistory[`${getWorkspaceName(await this.getWorkspaces(), workspace)}.${path}`] = tagHistoryResponse.results[path]
}
}
}

const mergedTagValuesWithType = this.mergeTagsHistoryValues(tagsDecimatedHistory);
result.fields.push({
name: 'time', 'values': mergedTagValuesWithType.timestamps, type: FieldType.time
});
Expand Down Expand Up @@ -133,15 +151,15 @@ export class TagDataSource extends DataSourceBase<TagQuery> {
return response.tagsWithValues.length ? response.tagsWithValues : Throw(`No tags matched the path '${path}'`)
}

private async getTagHistoryWithChunks(paths: string[], workspace: string, range: TimeRange, intervals?: number): Promise<TagHistoryResponse> {
const pathChunks: string[][] = [];
private async getTagHistoryWithChunks(paths: TagWithValue[], workspace: string, range: TimeRange, intervals?: number): Promise<TagHistoryResponse> {
const pathChunks: TagWithValue[][] = [];
for (let i = 0; i < paths.length; i += 10) {
pathChunks.push(paths.slice(i, i + 10));
}
// Fetch and aggregate the data from each chunk
const aggregatedResults: TagHistoryResponse = { results: {} };
for (const chunk of pathChunks) {
const chunkResult = await this.getTagHistoryValues(chunk, workspace, range, intervals);
const chunkResult = await this.getTagHistoryValues(chunk.map(tag => tag.tag.path), workspace, range, intervals);
// Merge the results from the current chunk with the aggregated results
for (const [path, data] of Object.entries(chunkResult.results)) {
if (!aggregatedResults.results[path]) {
Expand Down
50 changes: 50 additions & 0 deletions src/datasources/tag/__snapshots__/TagDataSource.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -649,3 +649,53 @@ exports[`queries uses displayName property 1`] = `
},
]
`;

exports[`queries history of tags from different workspaces 1`] = `
[
{
"fields": [
{
"name": "time",
"type": "time",
"values": [
"2023-01-01T00:00:00Z",
"2023-01-01T00:01:00Z",
],
},
{
"config": {},
"name": "Default workspace.my.tag.1",
"values": [
1,
2,
],
},
{
"config": {},
"name": "Default workspace.my.tag.2",
"values": [
2,
3,
],
},
{
"config": {},
"name": "Other workspace.my.tag.3",
"values": [
3,
4,
],
},
{
"config": {},
"name": "Other workspace.my.tag.4",
"values": [
4,
5,
],
},
],
"refId": "A",
},
]
`;

0 comments on commit 765683f

Please sign in to comment.