Skip to content

Commit 89a3efd

Browse files
committed
datasource-http-backend: Example migration with experimental APIs
1 parent 5fc2764 commit 89a3efd

File tree

11 files changed

+85
-21
lines changed

11 files changed

+85
-21
lines changed

examples/datasource-http-backend/pkg/kinds/query.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ import (
1010
type DataQuery struct {
1111
v0alpha1.CommonQueryProperties
1212

13-
// Multiplier is the number to multiply the input by
13+
// Multiply is the number to multiply the input by
14+
Multiply int `json:"multiply,omitempty"`
15+
16+
// Deprecated: Use Multiply instead
1417
Multiplier int `json:"multiplier,omitempty"`
1518
}
1619

examples/datasource-http-backend/pkg/kinds/query.panel.schema.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,11 @@
4141
"type": "integer"
4242
},
4343
"multiplier": {
44-
"description": "Multiplier is the number to multiply the input by",
44+
"description": "Deprecated: Use Multiply instead",
45+
"type": "integer"
46+
},
47+
"multiply": {
48+
"description": "Multiply is the number to multiply the input by",
4549
"type": "integer"
4650
},
4751
"queryType": {

examples/datasource-http-backend/pkg/kinds/query.request.schema.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,11 @@
5151
"type": "integer"
5252
},
5353
"multiplier": {
54-
"description": "Multiplier is the number to multiply the input by",
54+
"description": "Deprecated: Use Multiply instead",
55+
"type": "integer"
56+
},
57+
"multiply": {
58+
"description": "Multiply is the number to multiply the input by",
5559
"type": "integer"
5660
},
5761
"queryType": {

examples/datasource-http-backend/pkg/kinds/query.types.json

+6-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
{
99
"metadata": {
1010
"name": "default",
11-
"resourceVersion": "1728987397884",
11+
"resourceVersion": "1729779295393",
1212
"creationTimestamp": "2024-10-15T10:11:05Z"
1313
},
1414
"spec": {
@@ -47,7 +47,11 @@
4747
"type": "integer"
4848
},
4949
"multiplier": {
50-
"description": "Multiplier is the number to multiply the input by",
50+
"description": "Deprecated: Use Multiply instead",
51+
"type": "integer"
52+
},
53+
"multiply": {
54+
"description": "Multiply is the number to multiply the input by",
5155
"type": "integer"
5256
},
5357
"queryType": {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package plugin
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"fmt"
7+
8+
"github.com/grafana/datasource-http-backend/pkg/kinds"
9+
"github.com/grafana/grafana-plugin-sdk-go/backend"
10+
)
11+
12+
// convertQuery parses a given DataQuery and migrates it if necessary.
13+
func convertQuery(orig backend.DataQuery) (*kinds.DataQuery, error) {
14+
input := &kinds.DataQuery{}
15+
err := json.Unmarshal(orig.JSON, input)
16+
if err != nil {
17+
return nil, fmt.Errorf("unmarshal: %w", err)
18+
}
19+
if input.Multiplier != 0 && input.Multiply == 0 {
20+
input.Multiply = input.Multiplier
21+
input.Multiplier = 0
22+
}
23+
return input, nil
24+
}
25+
26+
// convertQueryRequest migrates a given QueryDataRequest which can contain multiple queries.
27+
func convertQueryRequest(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryConversionResponse, error) {
28+
queries := make([]any, 0, len(req.Queries))
29+
for _, q := range req.Queries {
30+
input, err := convertQuery(q)
31+
if err != nil {
32+
return nil, err
33+
}
34+
q.JSON, err = json.Marshal(input)
35+
if err != nil {
36+
return nil, fmt.Errorf("marshal: %w", err)
37+
}
38+
queries = append(queries, q)
39+
}
40+
return &backend.QueryConversionResponse{
41+
Queries: queries,
42+
}, nil
43+
}

examples/datasource-http-backend/pkg/plugin/datasource.go

+4-5
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"strconv"
1010
"time"
1111

12-
"github.com/grafana/datasource-http-backend/pkg/kinds"
1312
"github.com/grafana/grafana-plugin-sdk-go/backend"
1413
"github.com/grafana/grafana-plugin-sdk-go/backend/datasource"
1514
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
@@ -75,6 +74,7 @@ var DatasourceOpts = datasource.ManageOpts{
7574
attribute.String("my_plugin.my_attribute", "custom value"),
7675
},
7776
},
77+
QueryConversionHandler: backend.ConvertQueryFunc(convertQueryRequest),
7878
}
7979

8080
// Datasource is an example datasource which can respond to data queries, reports
@@ -174,13 +174,12 @@ func (d *Datasource) query(ctx context.Context, pCtx backend.PluginContext, quer
174174
return backend.DataResponse{}, fmt.Errorf("new request with context: %w", err)
175175
}
176176
if len(query.JSON) > 0 {
177-
input := &kinds.DataQuery{}
178-
err = json.Unmarshal(query.JSON, input)
177+
input, err := convertQuery(query)
179178
if err != nil {
180-
return backend.DataResponse{}, fmt.Errorf("unmarshal: %w", err)
179+
return backend.DataResponse{}, err
181180
}
182181
q := req.URL.Query()
183-
q.Add("multiplier", strconv.Itoa(input.Multiplier))
182+
q.Add("multiplier", strconv.Itoa(input.Multiply))
184183
req.URL.RawQuery = q.Encode()
185184
}
186185
httpResp, err := d.httpClient.Do(req)

examples/datasource-http-backend/src/components/QueryEditor.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ export class QueryEditor extends PureComponent<Props> {
1515
type="number"
1616
id="multiplier"
1717
name="multiplier"
18-
value={this.props.query.multiplier}
19-
onChange={(e) => this.props.onChange({ ...this.props.query, multiplier: e.currentTarget.valueAsNumber })}
18+
value={this.props.query.multiply}
19+
onChange={(e) => this.props.onChange({ ...this.props.query, multiply: e.currentTarget.valueAsNumber })}
2020
/>
2121
</HorizontalGroup>
2222
);
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
import { CoreApp, DataSourceInstanceSettings } from '@grafana/data';
22

33
import { MyQuery, MyDataSourceOptions } from './types';
4-
import { DataSourceWithBackend } from '@grafana/runtime';
4+
import { DataSourceWithBackend, MigrationHandler } from '@grafana/runtime';
5+
import { DataQuery } from '@grafana/schema';
6+
7+
export class DataSource extends DataSourceWithBackend<MyQuery, MyDataSourceOptions> implements MigrationHandler {
8+
hasBackendMigration: boolean;
59

6-
export class DataSource extends DataSourceWithBackend<MyQuery, MyDataSourceOptions> {
710
constructor(instanceSettings: DataSourceInstanceSettings<MyDataSourceOptions>) {
811
super(instanceSettings);
12+
this.hasBackendMigration = true;
913
}
1014

1115
getDefaultQuery(_: CoreApp): Partial<MyQuery> {
12-
return { multiplier: 1 };
16+
return { multiply: 1 };
17+
}
18+
19+
shouldMigrate(query: DataQuery): boolean {
20+
return !query.hasOwnProperty('multiply');
1321
}
1422
}

examples/datasource-http-backend/src/module.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import { DataSource } from './datasource';
33
import { ConfigEditor } from './components/ConfigEditor';
44
import { QueryEditor } from './components/QueryEditor';
55
import { MyQuery, MyDataSourceOptions } from './types';
6+
import { QueryEditorWithMigration } from '@grafana/runtime';
67

78
export const plugin = new DataSourcePlugin<DataSource, MyQuery, MyDataSourceOptions>(DataSource)
89
.setConfigEditor(ConfigEditor)
9-
.setQueryEditor(QueryEditor);
10+
.setQueryEditor(QueryEditorWithMigration(QueryEditor));

examples/datasource-http-backend/src/plugin.json

+2-4
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@
1212
"author": {
1313
"name": "Grafana Labs"
1414
},
15-
"keywords": [
16-
"datasource"
17-
],
15+
"keywords": ["datasource"],
1816
"logos": {
1917
"small": "img/logo.svg",
2018
"large": "img/logo.svg"
@@ -34,7 +32,7 @@
3432
"updated": "%TODAY%"
3533
},
3634
"dependencies": {
37-
"grafanaDependency": ">=10.4.0",
35+
"grafanaDependency": ">=11.4.0",
3836
"plugins": []
3937
}
4038
}

examples/datasource-http-backend/src/types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { DataSourceJsonData } from '@grafana/data';
22
import type { DataQuery } from '@grafana/schema';
33

44
export interface MyQuery extends DataQuery {
5-
multiplier: number;
5+
multiply: number;
66
}
77

88
/**

0 commit comments

Comments
 (0)