Skip to content

Commit

Permalink
Use application/x-ndjson content type for multisearch requests (#403)
Browse files Browse the repository at this point in the history
  • Loading branch information
iwysiu authored Jun 4, 2024
1 parent dc38823 commit 63aa0ce
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 18 deletions.
1 change: 1 addition & 0 deletions cspell.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,5 +114,6 @@
"Throughputs",
"mainstat",
"secondarystat",
"x-ndjson"
]
}
2 changes: 1 addition & 1 deletion pkg/opensearch/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ func (c *baseClientImpl) executeRequest(ctx context.Context, method, uriPath, ur
}

req.Header.Set("User-Agent", "Grafana")
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Content-Type", "application/x-ndjson")

dsHttpOpts, err := c.ds.HTTPClientOptions(ctx)
if err != nil {
Expand Down
2 changes: 2 additions & 0 deletions pkg/opensearch/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ func TestClient(t *testing.T) {
assert.NotNil(t, sc.request)
assert.Equal(t, http.MethodPost, sc.request.Method)
assert.Equal(t, "/_msearch", sc.request.URL.Path)
assert.Equal(t, "application/x-ndjson", sc.request.Header.Get("Content-Type"))
assert.Equal(t, "max_concurrent_shard_requests=6", sc.request.URL.RawQuery)

assert.NotNil(t, sc.requestBody)
Expand Down Expand Up @@ -178,6 +179,7 @@ func TestClient(t *testing.T) {
assert.NotNil(t, sc.request)
assert.Equal(t, http.MethodPost, sc.request.Method)
assert.Equal(t, "/_opendistro/_ppl", sc.request.URL.Path)
assert.Equal(t, "application/json", sc.request.Header.Get("Content-Type"))

assert.NotNil(t, sc.requestBody)

Expand Down
44 changes: 27 additions & 17 deletions src/datasource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,14 @@ import { OpenSearchResponse } from './OpenSearchResponse';
import { IndexPattern } from './index_pattern';
import { QueryBuilder } from './QueryBuilder';
import { defaultBucketAgg, hasMetricOfType } from './query_def';
import { DataSourceWithBackend, FetchError, getBackendSrv, getDataSourceSrv, getTemplateSrv } from '@grafana/runtime';
import {
BackendSrvRequest,
DataSourceWithBackend,
FetchError,
getBackendSrv,
getDataSourceSrv,
getTemplateSrv,
} from '@grafana/runtime';
import { DataLinkConfig, Flavor, LuceneQueryType, OpenSearchOptions, OpenSearchQuery, QueryType } from './types';
import { metricAggregationConfig } from './components/QueryEditor/MetricAggregationsEditor/utils';
import {
Expand Down Expand Up @@ -103,27 +110,26 @@ export class OpenSearchDatasource extends DataSourceWithBackend<OpenSearchQuery,
this.sigV4Auth = settingsData.sigV4Auth ?? false;
}

private async request(method: string, url: string, data?: undefined) {
const options: any = {
private async request(method: string, url: string, data?: undefined, headers?: BackendSrvRequest['headers']) {
const options: BackendSrvRequest = {
url: this.url + '/' + url,
method: method,
data: data,
method,
data,
};
options.headers = headers ?? {};

if (this.basicAuth || this.withCredentials) {
options.withCredentials = true;

Check warning on line 122 in src/datasource.ts

View workflow job for this annotation

GitHub Actions / compatibilitycheck

'withCredentials' is deprecated. withCredentials is deprecated in favor of credentials
}
const tempHeaders: { Authorization?: string; 'x-amz-content-sha256'?: string } = {};

if (this.basicAuth) {
tempHeaders.Authorization = this.basicAuth;
options.headers.Authorization = this.basicAuth;
}

if (this.sigV4Auth && data) {
tempHeaders['x-amz-content-sha256'] = await sha256(data);
options.headers['x-amz-content-sha256'] = await sha256(data);
}

options.headers = tempHeaders;

return getBackendSrv()
.datasourceRequest(options)

Check warning on line 134 in src/datasource.ts

View workflow job for this annotation

GitHub Actions / compatibilitycheck

'datasourceRequest' is deprecated. Use the fetch function instead
.catch((err: any) => {
Expand Down Expand Up @@ -175,8 +181,12 @@ export class OpenSearchDatasource extends DataSourceWithBackend<OpenSearchQuery,
}
}

private post(url: string, data: any) {
return this.request('POST', url, data).then((results: any) => {
private postMultiSearch(url: string, data: any) {
return this.post(url, data, { 'Content-Type': 'application/x-ndjson' });
}

private post(url: string, data: any, headers?: BackendSrvRequest['headers']) {
return this.request('POST', url, data, headers).then((results: any) => {
results.data.$$config = results.config;
return results.data;
});
Expand Down Expand Up @@ -252,7 +262,7 @@ export class OpenSearchDatasource extends DataSourceWithBackend<OpenSearchQuery,

const payload = JSON.stringify(header) + '\n' + JSON.stringify(data) + '\n';

return this.post('_msearch', payload).then((res: any) => {
return this.postMultiSearch('_msearch', payload).then((res: any) => {
const list = [];
const hits = res.responses[0].hits.hits;

Expand Down Expand Up @@ -651,7 +661,7 @@ export class OpenSearchDatasource extends DataSourceWithBackend<OpenSearchQuery,

const traceList$ =
traceListTargets.length > 0
? from(this.post(this.getMultiSearchUrl(), createQuery(traceListTargets))).pipe(
? from(this.postMultiSearch(this.getMultiSearchUrl(), createQuery(traceListTargets))).pipe(
map((res: any) => {
return createListTracesDataFrame(traceListTargets, res, this.uid, this.name, this.type);
})
Expand All @@ -660,15 +670,15 @@ export class OpenSearchDatasource extends DataSourceWithBackend<OpenSearchQuery,

const traceDetails$ =
traceTargets.length > 0
? from(this.post(this.getMultiSearchUrl(), createQuery(traceTargets))).pipe(
? from(this.postMultiSearch(this.getMultiSearchUrl(), createQuery(traceTargets))).pipe(
map((res: any) => {
return createTraceDataFrame(traceTargets, res);
})
)
: null;
const otherQueries$ =
otherTargets.length > 0
? from(this.post(this.getMultiSearchUrl(), createQuery(otherTargets))).pipe(
? from(this.postMultiSearch(this.getMultiSearchUrl(), createQuery(otherTargets))).pipe(
map((res: any) => {
const er = new OpenSearchResponse(otherTargets, res);
// this condition that checks if some targets are logs, and if some are, enhance ALL data frames, even the ones that aren't
Expand Down Expand Up @@ -907,7 +917,7 @@ export class OpenSearchDatasource extends DataSourceWithBackend<OpenSearchQuery,

const url = this.getMultiSearchUrl();

return this.post(url, esQuery).then((res: any) => {
return this.postMultiSearch(url, esQuery).then((res: any) => {
if (!res.responses[0].aggregations) {
return [];
}
Expand Down

0 comments on commit 63aa0ce

Please sign in to comment.