diff --git a/CHANGELOG.md b/CHANGELOG.md
index 154b9d74fc9a..9a94b7279bb9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -106,6 +106,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- [Multiple Datasource] Modify selectable picker to remove group label and close popover after selection ([#6515](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6515))
- [Multiple Datasource] Extract the button component for datasource picker to avoid duplicate code ([#6559](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6559))
- [Workspace] Add workspaces filter to saved objects page. ([#6458](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6458))
+- [Multiple Datasource] Support multi data source in Region map ([#6654](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6654))
### 🐛 Bug Fixes
diff --git a/src/plugins/region_map/opensearch_dashboards.json b/src/plugins/region_map/opensearch_dashboards.json
index b2859541377d..005714fe2b97 100644
--- a/src/plugins/region_map/opensearch_dashboards.json
+++ b/src/plugins/region_map/opensearch_dashboards.json
@@ -16,7 +16,8 @@
],
"requiredBundles": [
"opensearchDashboardsUtils",
- "charts",
+ "charts",
"visDefaultEditor"
- ]
+ ],
+ "optionalPlugins": ["dataSource"]
}
diff --git a/src/plugins/region_map/public/choropleth_layer.js b/src/plugins/region_map/public/choropleth_layer.js
index 84329953c9f0..b7f68c3986bb 100644
--- a/src/plugins/region_map/public/choropleth_layer.js
+++ b/src/plugins/region_map/public/choropleth_layer.js
@@ -100,7 +100,8 @@ export class ChoroplethLayer extends OpenSearchDashboardsMapLayer {
leaflet,
layerChosenByUser,
http,
- uiSettings
+ uiSettings,
+ dataSourceRefId
) {
super();
this._serviceSettings = serviceSettings;
@@ -119,6 +120,7 @@ export class ChoroplethLayer extends OpenSearchDashboardsMapLayer {
this._http = http;
this._visParams = null;
this._uiSettings = uiSettings;
+ this._dataSourceRefId = dataSourceRefId;
// eslint-disable-next-line no-undef
this._leafletLayer = this._leaflet.geoJson(null, {
@@ -249,7 +251,7 @@ CORS configuration of the server permits requests from the OpenSearch Dashboards
try {
const services = getServices(this._http);
const indexSize = this._uiSettings.get(CUSTOM_VECTOR_MAP_MAX_SIZE_SETTING);
- const result = await services.getIndexData(this._layerName, indexSize);
+ const result = await services.getIndexData(this._layerName, indexSize, this._dataSourceRefId);
const finalResult = {
type: 'FeatureCollection',
@@ -346,7 +348,8 @@ CORS configuration of the server permits requests from the OpenSearch Dashboards
leaflet,
layerChosenByUser,
http,
- uiSettings
+ uiSettings,
+ dataSourceRefId
) {
const clonedLayer = new ChoroplethLayer(
name,
@@ -359,7 +362,8 @@ CORS configuration of the server permits requests from the OpenSearch Dashboards
leaflet,
layerChosenByUser,
http,
- uiSettings
+ uiSettings,
+ dataSourceRefId
);
clonedLayer.setJoinField(this._joinField);
clonedLayer.setColorRamp(this._colorRamp);
diff --git a/src/plugins/region_map/public/region_map_type.js b/src/plugins/region_map/public/region_map_type.js
index 581bc1a178bd..903b84a6ec64 100644
--- a/src/plugins/region_map/public/region_map_type.js
+++ b/src/plugins/region_map/public/region_map_type.js
@@ -55,18 +55,18 @@ export function createRegionMapTypeDefinition(dependencies) {
return arr1.concat(arr2).filter((item) => !arr1.includes(item) || !arr2.includes(item));
};
- const getCustomIndices = async () => {
+ const getCustomIndices = async (dataSourceRefId) => {
try {
- const result = await services.getCustomIndices();
+ const result = await services.getCustomIndices(dataSourceRefId);
return result.resp;
} catch (e) {
return false;
}
};
- const getJoinFields = async (indexName) => {
+ const getJoinFields = async (indexName, dataSourceRefId) => {
try {
- const result = await services.getIndexMapping(indexName);
+ const result = await services.getIndexMapping(indexName, dataSourceRefId);
const properties = diffArray(Object.keys(result.resp[indexName].mappings.properties), [
'location',
]);
@@ -82,17 +82,17 @@ export function createRegionMapTypeDefinition(dependencies) {
}
};
- const addSchemaToCustomLayer = async (customlayer) => {
- const joinFields = await getJoinFields(customlayer.index);
+ const addSchemaToCustomLayer = async (customlayer, dataSourceRefId) => {
+ const joinFields = await getJoinFields(customlayer, dataSourceRefId);
const customLayerWithSchema = {
attribution:
'Made with NaturalEarth',
created_at: '2017-04-26T17:12:15.978370',
format: 'geojson',
fields: joinFields,
- id: customlayer.index,
+ id: customlayer,
meta: undefined,
- name: customlayer.index,
+ name: customlayer,
origin: 'user-upload',
};
@@ -147,6 +147,7 @@ provided base maps, or add your own. Darker colors represent higher values.',
vectorLayers: [],
customVectorLayers: [],
tmsLayers: [],
+ dataSourceRefId: '',
},
schemas: new Schemas([
{
@@ -199,7 +200,12 @@ provided base maps, or add your own. Darker colors represent higher values.',
const customVectorLayers = regionmapsConfig.layers.map(
mapToLayerWithId.bind(null, ORIGIN.OPENSEARCH_DASHBOARDS_YML)
);
- const customIndices = await getCustomIndices();
+
+ // Read the data source reference id from index pattern if available, empty string means for local clusters
+ const dataSourceRefId = vis.data.indexPattern?.dataSourceRef?.id || '';
+ vis.type.editorConfig.collections.dataSourceRefId = dataSourceRefId;
+
+ const customIndices = await getCustomIndices(dataSourceRefId);
let selectedLayer = vectorLayers[0];
let selectedJoinField = selectedLayer ? selectedLayer.fields[0] : null;
@@ -214,7 +220,7 @@ provided base maps, or add your own. Darker colors represent higher values.',
.filter(
(layer) => !vectorLayers.some((vectorLayer) => vectorLayer.layerId === layer.layerId)
);
- const promises = customIndices.map(addSchemaToCustomLayer);
+ const promises = customIndices.map((idx) => addSchemaToCustomLayer(idx, dataSourceRefId));
const newCustomLayers = await Promise.all(promises);
// backfill v1 manifest for now
diff --git a/src/plugins/region_map/public/region_map_visualization.js b/src/plugins/region_map/public/region_map_visualization.js
index 69dca0525b89..e9fa55b47840 100644
--- a/src/plugins/region_map/public/region_map_visualization.js
+++ b/src/plugins/region_map/public/region_map_visualization.js
@@ -183,7 +183,6 @@ export function createRegionMapVisualization({
const metricFieldFormatter = getFormatService().deserialize(this._params.metric.format);
this._choroplethLayer.setLayerChosenByUser(this._params.layerChosenByUser);
-
this._choroplethLayer.setJoinField(this._params.selectedJoinField.name);
this._choroplethLayer.setColorRamp(truncatedColorMaps[this._params.colorSchema].value);
this._choroplethLayer.setLineWeight(this._params.outlineWeight);
@@ -231,7 +230,8 @@ export function createRegionMapVisualization({
(await lazyLoadMapsLegacyModules()).L,
this._params.layerChosenByUser,
http,
- uiSettings
+ uiSettings,
+ this.vis.type.editorConfig.collections.dataSourceRefId
);
} else {
const { ChoroplethLayer } = await import('./choropleth_layer');
@@ -246,7 +246,8 @@ export function createRegionMapVisualization({
(await lazyLoadMapsLegacyModules()).L,
this._params.layerChosenByUser,
http,
- uiSettings
+ uiSettings,
+ this.vis.type.editorConfig.collections.dataSourceRefId
);
}
this._choroplethLayer.setLayerChosenByUser(this._params.layerChosenByUser);
diff --git a/src/plugins/region_map/public/services.ts b/src/plugins/region_map/public/services.ts
index ba182c7aa0fa..549666981d4d 100644
--- a/src/plugins/region_map/public/services.ts
+++ b/src/plugins/region_map/public/services.ts
@@ -6,46 +6,53 @@
import { CoreStart, HttpFetchError } from 'opensearch-dashboards/public';
export interface Services {
- getCustomIndices: () => Promise;
- getIndexData: (indexName: string, size: number) => Promise;
- getIndexMapping: (indexName: string) => Promise;
+ getCustomIndices: (dataSourceRefId: string) => Promise;
+ getIndexData: (
+ indexName: string,
+ size: number,
+ dataSourceRefId: string
+ ) => Promise;
+ getIndexMapping: (
+ indexName: string,
+ dataSourceRefId: string
+ ) => Promise;
}
export function getServices(http: CoreStart['http']): Services {
return {
- getCustomIndices: async () => {
+ getCustomIndices: async (dataSourceRefId: string) => {
try {
- const response = await http.post('../api/geospatial/_indices', {
+ return await http.post('../api/geospatial/_indices', {
body: JSON.stringify({
index: '*-map',
}),
+ query: { dataSourceId: dataSourceRefId },
});
- return response;
} catch (e) {
return e;
}
},
- getIndexData: async (indexName: string, size: number) => {
+ getIndexData: async (indexName: string, size: number, dataSourceRefId: string) => {
try {
- const response = await http.post('../api/geospatial/_search', {
+ return await http.post('../api/geospatial/_search', {
body: JSON.stringify({
index: indexName,
size,
}),
+ query: { dataSourceId: dataSourceRefId },
});
- return response;
} catch (e) {
return e;
}
},
- getIndexMapping: async (indexName: string) => {
+ getIndexMapping: async (indexName: string, dataSourceRefId: string) => {
try {
- const response = await http.post('../api/geospatial/_mappings', {
+ return await http.post('../api/geospatial/_mappings', {
body: JSON.stringify({
index: indexName,
}),
+ query: { dataSourceId: dataSourceRefId },
});
- return response;
} catch (e) {
return e;
}
diff --git a/src/plugins/region_map/server/routes/opensearch.ts b/src/plugins/region_map/server/routes/opensearch.ts
index dfdcb4a1900d..4ea868710999 100644
--- a/src/plugins/region_map/server/routes/opensearch.ts
+++ b/src/plugins/region_map/server/routes/opensearch.ts
@@ -14,20 +14,28 @@ export function registerGeospatialRoutes(router: IRouter) {
body: schema.object({
index: schema.string(),
}),
+ query: schema.maybe(schema.object({}, { unknowns: 'allow' })),
},
},
async (context, req, res) => {
- const client = context.core.opensearch.client.asCurrentUser;
try {
- const { index } = req.body;
- const indices = await client.cat.indices({
- index,
+ let client;
+ // @ts-ignore
+ if (!req.query.dataSourceId) {
+ client = context.core.opensearch.client.asCurrentUser;
+ } else {
+ // @ts-ignore
+ client = await context.dataSource.opensearch.getClient(req.query.dataSourceId);
+ }
+ const response = await client.cat.indices({
+ index: req.body.index,
format: 'json',
});
+ const indexNames = response.body.map((index: any) => index.index);
return res.ok({
body: {
ok: true,
- resp: indices.body,
+ resp: indexNames,
},
});
} catch (err: any) {
@@ -59,10 +67,18 @@ export function registerGeospatialRoutes(router: IRouter) {
index: schema.string(),
size: schema.number(),
}),
+ query: schema.maybe(schema.object({}, { unknowns: 'allow' })),
},
},
async (context, req, res) => {
- const client = context.core.opensearch.client.asCurrentUser;
+ let client;
+ // @ts-ignore
+ if (!req.query.dataSourceId) {
+ client = context.core.opensearch.client.asCurrentUser;
+ } else {
+ // @ts-ignore
+ client = await context.dataSource.opensearch.getClient(req.query.dataSourceId);
+ }
try {
const { index, size } = req.body;
const params = { index, body: {}, size };
@@ -91,10 +107,18 @@ export function registerGeospatialRoutes(router: IRouter) {
body: schema.object({
index: schema.string(),
}),
+ query: schema.maybe(schema.object({}, { unknowns: 'allow' })),
},
},
async (context, req, res) => {
- const client = context.core.opensearch.client.asCurrentUser;
+ let client;
+ // @ts-ignore
+ if (!req.query.dataSourceId) {
+ client = context.core.opensearch.client.asCurrentUser;
+ } else {
+ // @ts-ignore
+ client = await context.dataSource.opensearch.getClient(req.query.dataSourceId);
+ }
try {
const { index } = req.body;
const mappings = await client.indices.getMapping({ index });