Skip to content

Commit

Permalink
Add maps stats api
Browse files Browse the repository at this point in the history
Signed-off-by: Junqiu Lei <junqiu@amazon.com>
  • Loading branch information
junqiu-lei committed Mar 31, 2023
1 parent b7aa847 commit 7c74a3d
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

### Infrastructure
* Add CHANGELOG ([#342](https://github.com/opensearch-project/dashboards-maps/pull/342))
* Add maps metrics api from saved object ([#362](https://github.com/opensearch-project/dashboards-maps/pull/362))

### Documentation

Expand Down
5 changes: 4 additions & 1 deletion common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,11 @@ export const APP_PATH = {
LANDING_PAGE_PATH: '/',
CREATE_MAP: '/create',
EDIT_MAP: '/:id',
STATS: '/stats',
};

export const APP_API = '/api/maps-dashboards';

export enum DASHBOARDS_MAPS_LAYER_NAME {
OPENSEARCH_MAP = 'OpenSearch map',
DOCUMENTS = 'Documents',
Expand Down Expand Up @@ -147,7 +150,7 @@ export const LAYER_ICON_TYPE_MAP: { [key: string]: string } = {
[DASHBOARDS_MAPS_LAYER_TYPE.CUSTOM_MAP]: 'globe',
};

//refer https://github.com/opensearch-project/i18n-plugin/blob/main/DEVELOPER_GUIDE.md#new-locale for OSD supported languages
// refer https://github.com/opensearch-project/i18n-plugin/blob/main/DEVELOPER_GUIDE.md#new-locale for OSD supported languages
export const OSD_LANGUAGES = ['en', 'es', 'fr', 'de', 'ja', 'ko', 'zh']; // all these codes are also supported in vector tiles map
export const FALLBACK_LANGUAGE = 'en';

Expand Down
84 changes: 84 additions & 0 deletions server/common/stats/stats_helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { SavedObjectsFindResponse } from '../../../../../src/core/server';
import { MapLayerSpecification } from '../../../public/model/mapLayerType';
import { MapSavedObjectAttributes } from '../../../common/map_saved_object_attributes';
import { MAP_STATS, MAPS_STATS } from './type';
import { DASHBOARDS_MAPS_LAYER_TYPE } from '../../../common';

export const getStats = (mapsSavedObjects: SavedObjectsFindResponse<MapSavedObjectAttributes>) => {
let totalLayersCount = 0;
let totalDocumentsLayersCount = 0;
let totalOpensearchBaseLayersCount = 0;
let totalCustomTmsLayersCount = 0;
let totalCustomWmsLayersCount = 0;
let totalLayersFiltersCount = 0;
const mapsInfo: MAP_STATS[] = [];
mapsSavedObjects.saved_objects.forEach((mapRes) => {
let documentsLayersCount = 0;
let opensearchBaseLayersCount = 0;
let customTmsLayersCount = 0;
let customWmsLayersCount = 0;
let layersFiltersCount = 0;
const layerListJsonString = mapRes.attributes.layerList as string;
const layerList: MapLayerSpecification[] = layerListJsonString
? JSON.parse(layerListJsonString)
: [];
const layersCount = layerList.length;
totalLayersCount += layerList.length;

layerList.forEach((layer) => {
switch (layer.type) {
case DASHBOARDS_MAPS_LAYER_TYPE.DOCUMENTS:
totalDocumentsLayersCount++;
documentsLayersCount++;
const layerFiltersCount = layer.source.filters.length;
layersFiltersCount += layerFiltersCount;
totalLayersFiltersCount += layerFiltersCount;
break;
case DASHBOARDS_MAPS_LAYER_TYPE.OPENSEARCH_MAP:
totalOpensearchBaseLayersCount++;
opensearchBaseLayersCount++;
break;
case DASHBOARDS_MAPS_LAYER_TYPE.CUSTOM_MAP:
if (layer.source.customType === 'wms') {
totalCustomWmsLayersCount++;
customWmsLayersCount++;
} else {
totalCustomTmsLayersCount++;
customTmsLayersCount++;
}
break;
}
});

mapsInfo.push({
id: mapRes.id,
layers_filters_total: layersFiltersCount,
layers_count: {
total: layersCount,
documents: documentsLayersCount,
opensearch_base_map: opensearchBaseLayersCount,
custom_tms: customTmsLayersCount,
custom_wms: customWmsLayersCount,
},
});
});

const metrics: MAPS_STATS = {
maps_total: mapsSavedObjects.total,
layers_filters_total: totalLayersFiltersCount,
layers_count: {
total: totalLayersCount,
documents: totalDocumentsLayersCount,
opensearch_base_map: totalOpensearchBaseLayersCount,
custom_tms: totalCustomTmsLayersCount,
custom_wms: totalCustomWmsLayersCount,
},
maps: mapsInfo,
};
return metrics;
};
25 changes: 25 additions & 0 deletions server/common/stats/type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

export interface MAPS_STATS {
maps_total: number;
layers_filters_total: number;
layers_count: LAYER_STATS;
maps: MAP_STATS[];
}

export interface MAP_STATS {
id: string;
layers_filters_total: number;
layers_count: LAYER_STATS;
}

export interface LAYER_STATS {
total: number;
documents: number;
opensearch_base_map: number;
custom_tms: number;
custom_wms: number;
}
6 changes: 4 additions & 2 deletions server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@ import {
} from './types';
import { createGeospatialCluster } from './clusters';
import { GeospatialService, OpensearchService } from './services';
import { geospatial, opensearch } from '../server/routes';
import { geospatial, opensearch, statsRoute } from '../server/routes';
import { mapSavedObjectsType } from './saved_objects';
import { capabilitiesProvider } from './saved_objects/capabilities_provider';
import { ConfigSchema } from '../common/config';

export class CustomImportMapPlugin
implements Plugin<CustomImportMapPluginSetup, CustomImportMapPluginStart> {
implements Plugin<CustomImportMapPluginSetup, CustomImportMapPluginStart>
{
private readonly logger: Logger;
private readonly globalConfig$;
private readonly config$;
Expand Down Expand Up @@ -62,6 +63,7 @@ export class CustomImportMapPlugin
// Register server side APIs
geospatial(geospatialService, router);
opensearch(opensearchService, router);
statsRoute(router);

// Register saved object types
core.savedObjects.registerType(mapSavedObjectsType);
Expand Down
3 changes: 2 additions & 1 deletion server/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@

import geospatial from './geospatial';
import opensearch from './opensearch';
import { statsRoute } from './stats_router';

export { geospatial, opensearch };
export { geospatial, opensearch, statsRoute };
45 changes: 45 additions & 0 deletions server/routes/stats_router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { ResponseError } from '@opensearch-project/opensearch/lib/errors';
import {
IOpenSearchDashboardsResponse,
IRouter,
SavedObjectsFindResponse,
} from '../../../../src/core/server';
import { APP_API, APP_PATH, MAP_SAVED_OBJECT_TYPE } from '../../common';
import { getStats } from '../common/stats/stats_helper';
import { MapSavedObjectAttributes } from '../../common/map_saved_object_attributes';

export function statsRoute(router: IRouter) {
router.get(
{
path: `${APP_API}${APP_PATH.STATS}`,
validate: false,
},
async (
context,
request,
response
): Promise<IOpenSearchDashboardsResponse<any | ResponseError>> => {
try {
const savedObjectsClient = context.core.savedObjects.client;
const mapsSavedObjects: SavedObjectsFindResponse<MapSavedObjectAttributes> =
await savedObjectsClient?.find({ type: MAP_SAVED_OBJECT_TYPE });
const stats = getStats(mapsSavedObjects);
return response.ok({
body: stats,
});
} catch (error) {
// eslint-disable-next-line no-console
console.error(error);
return response.custom({
statusCode: error.statusCode || 500,
body: error.message,
});
}
}
);
}

0 comments on commit 7c74a3d

Please sign in to comment.