mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Maps] Fix proxy handling issues (#71182)
This commit is contained in:
parent
8d86a74ba8
commit
d7a679ba8c
5 changed files with 107 additions and 79 deletions
|
@ -17,8 +17,9 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { PluginConfigDescriptor } from 'kibana/server';
|
||||
import { PluginInitializerContext } from 'kibana/public';
|
||||
import { Plugin, PluginConfigDescriptor } from 'kibana/server';
|
||||
import { PluginInitializerContext } from 'src/core/server';
|
||||
import { Observable } from 'rxjs';
|
||||
import { configSchema, ConfigSchema } from '../config';
|
||||
|
||||
export const config: PluginConfigDescriptor<ConfigSchema> = {
|
||||
|
@ -37,13 +38,27 @@ export const config: PluginConfigDescriptor<ConfigSchema> = {
|
|||
schema: configSchema,
|
||||
};
|
||||
|
||||
export const plugin = (initializerContext: PluginInitializerContext) => ({
|
||||
setup() {
|
||||
export interface MapsLegacyPluginSetup {
|
||||
config$: Observable<ConfigSchema>;
|
||||
}
|
||||
|
||||
export class MapsLegacyPlugin implements Plugin<MapsLegacyPluginSetup> {
|
||||
readonly _initializerContext: PluginInitializerContext<ConfigSchema>;
|
||||
|
||||
constructor(initializerContext: PluginInitializerContext<ConfigSchema>) {
|
||||
this._initializerContext = initializerContext;
|
||||
}
|
||||
|
||||
public setup() {
|
||||
// @ts-ignore
|
||||
const config$ = initializerContext.config.create();
|
||||
const config$ = this._initializerContext.config.create();
|
||||
return {
|
||||
config: config$,
|
||||
config$,
|
||||
};
|
||||
},
|
||||
start() {},
|
||||
});
|
||||
}
|
||||
|
||||
public start() {}
|
||||
}
|
||||
|
||||
export const plugin = (initializerContext: PluginInitializerContext) =>
|
||||
new MapsLegacyPlugin(initializerContext);
|
||||
|
|
|
@ -36,6 +36,11 @@ describe('getGlyphUrl', () => {
|
|||
beforeAll(() => {
|
||||
require('./kibana_services').getIsEmsEnabled = () => true;
|
||||
require('./kibana_services').getEmsFontLibraryUrl = () => EMS_FONTS_URL_MOCK;
|
||||
require('./kibana_services').getHttp = () => ({
|
||||
basePath: {
|
||||
prepend: (url) => url, // No need to actually prepend a dev basepath for test
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
describe('EMS proxy enabled', () => {
|
||||
|
|
|
@ -30,8 +30,6 @@ import {
|
|||
getKibanaVersion,
|
||||
} from './kibana_services';
|
||||
|
||||
const GIS_API_RELATIVE = `../${GIS_API_PATH}`;
|
||||
|
||||
export function getKibanaRegionList(): unknown[] {
|
||||
return getRegionmapLayers();
|
||||
}
|
||||
|
@ -69,10 +67,14 @@ export function getEMSClient(): EMSClient {
|
|||
const proxyElasticMapsServiceInMaps = getProxyElasticMapsServiceInMaps();
|
||||
const proxyPath = '';
|
||||
const tileApiUrl = proxyElasticMapsServiceInMaps
|
||||
? relativeToAbsolute(`${GIS_API_RELATIVE}/${EMS_TILES_CATALOGUE_PATH}`)
|
||||
? relativeToAbsolute(
|
||||
getHttp().basePath.prepend(`/${GIS_API_PATH}/${EMS_TILES_CATALOGUE_PATH}`)
|
||||
)
|
||||
: getEmsTileApiUrl();
|
||||
const fileApiUrl = proxyElasticMapsServiceInMaps
|
||||
? relativeToAbsolute(`${GIS_API_RELATIVE}/${EMS_FILES_CATALOGUE_PATH}`)
|
||||
? relativeToAbsolute(
|
||||
getHttp().basePath.prepend(`/${GIS_API_PATH}/${EMS_FILES_CATALOGUE_PATH}`)
|
||||
)
|
||||
: getEmsFileApiUrl();
|
||||
|
||||
emsClient = new EMSClient({
|
||||
|
@ -101,8 +103,11 @@ export function getGlyphUrl(): string {
|
|||
return getHttp().basePath.prepend(`/${FONTS_API_PATH}/{fontstack}/{range}`);
|
||||
}
|
||||
return getProxyElasticMapsServiceInMaps()
|
||||
? relativeToAbsolute(`../${GIS_API_PATH}/${EMS_TILES_CATALOGUE_PATH}/${EMS_GLYPHS_PATH}`) +
|
||||
`/{fontstack}/{range}`
|
||||
? relativeToAbsolute(
|
||||
getHttp().basePath.prepend(
|
||||
`/${GIS_API_PATH}/${EMS_TILES_CATALOGUE_PATH}/${EMS_GLYPHS_PATH}`
|
||||
)
|
||||
) + `/{fontstack}/{range}`
|
||||
: getEmsFontLibraryUrl();
|
||||
}
|
||||
|
||||
|
|
|
@ -26,12 +26,14 @@ import { initRoutes } from './routes';
|
|||
import { ILicense } from '../../licensing/common/types';
|
||||
import { LicensingPluginSetup } from '../../licensing/server';
|
||||
import { HomeServerPluginSetup } from '../../../../src/plugins/home/server';
|
||||
import { MapsLegacyPluginSetup } from '../../../../src/plugins/maps_legacy/server';
|
||||
|
||||
interface SetupDeps {
|
||||
features: FeaturesPluginSetupContract;
|
||||
usageCollection: UsageCollectionSetup;
|
||||
home: HomeServerPluginSetup;
|
||||
licensing: LicensingPluginSetup;
|
||||
mapsLegacy: MapsLegacyPluginSetup;
|
||||
}
|
||||
|
||||
export class MapsPlugin implements Plugin {
|
||||
|
@ -129,9 +131,10 @@ export class MapsPlugin implements Plugin {
|
|||
|
||||
// @ts-ignore
|
||||
async setup(core: CoreSetup, plugins: SetupDeps) {
|
||||
const { usageCollection, home, licensing, features } = plugins;
|
||||
const { usageCollection, home, licensing, features, mapsLegacy } = plugins;
|
||||
// @ts-ignore
|
||||
const config$ = this._initializerContext.config.create();
|
||||
const mapsLegacyConfig = await mapsLegacy.config$.pipe(take(1)).toPromise();
|
||||
const currentConfig = await config$.pipe(take(1)).toPromise();
|
||||
|
||||
// @ts-ignore
|
||||
|
@ -150,7 +153,7 @@ export class MapsPlugin implements Plugin {
|
|||
initRoutes(
|
||||
core.http.createRouter(),
|
||||
license.uid,
|
||||
currentConfig,
|
||||
mapsLegacyConfig,
|
||||
this.kibanaVersion,
|
||||
this._logger
|
||||
);
|
||||
|
|
|
@ -73,9 +73,10 @@ export function initRoutes(router, licenseUid, mapConfig, kbnVersion, logger) {
|
|||
validate: {
|
||||
query: schema.object({
|
||||
id: schema.maybe(schema.string()),
|
||||
x: schema.maybe(schema.number()),
|
||||
y: schema.maybe(schema.number()),
|
||||
z: schema.maybe(schema.number()),
|
||||
elastic_tile_service_tos: schema.maybe(schema.string()),
|
||||
my_app_name: schema.maybe(schema.string()),
|
||||
my_app_version: schema.maybe(schema.string()),
|
||||
license: schema.maybe(schema.string()),
|
||||
}),
|
||||
},
|
||||
},
|
||||
|
@ -111,9 +112,9 @@ export function initRoutes(router, licenseUid, mapConfig, kbnVersion, logger) {
|
|||
path: `${ROOT}/${EMS_TILES_API_PATH}/${EMS_TILES_RASTER_TILE_PATH}`,
|
||||
validate: false,
|
||||
},
|
||||
async (context, request, { ok, badRequest }) => {
|
||||
async (context, request, response) => {
|
||||
if (!checkEMSProxyEnabled()) {
|
||||
return badRequest('map.proxyElasticMapsServiceInMaps disabled');
|
||||
return response.badRequest('map.proxyElasticMapsServiceInMaps disabled');
|
||||
}
|
||||
|
||||
if (
|
||||
|
@ -138,7 +139,7 @@ export function initRoutes(router, licenseUid, mapConfig, kbnVersion, logger) {
|
|||
.replace('{y}', request.query.y)
|
||||
.replace('{z}', request.query.z);
|
||||
|
||||
return await proxyResource({ url, contentType: 'image/png' }, { ok, badRequest });
|
||||
return await proxyResource({ url, contentType: 'image/png' }, response);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -203,7 +204,9 @@ export function initRoutes(router, licenseUid, mapConfig, kbnVersion, logger) {
|
|||
});
|
||||
//rewrite
|
||||
return ok({
|
||||
body: layers,
|
||||
body: {
|
||||
layers,
|
||||
},
|
||||
});
|
||||
}
|
||||
);
|
||||
|
@ -293,7 +296,11 @@ export function initRoutes(router, licenseUid, mapConfig, kbnVersion, logger) {
|
|||
path: `${ROOT}/${EMS_TILES_API_PATH}/${EMS_TILES_VECTOR_STYLE_PATH}`,
|
||||
validate: {
|
||||
query: schema.object({
|
||||
id: schema.maybe(schema.string()),
|
||||
id: schema.string(),
|
||||
elastic_tile_service_tos: schema.maybe(schema.string()),
|
||||
my_app_name: schema.maybe(schema.string()),
|
||||
my_app_version: schema.maybe(schema.string()),
|
||||
license: schema.maybe(schema.string()),
|
||||
}),
|
||||
},
|
||||
},
|
||||
|
@ -302,11 +309,6 @@ export function initRoutes(router, licenseUid, mapConfig, kbnVersion, logger) {
|
|||
return badRequest('map.proxyElasticMapsServiceInMaps disabled');
|
||||
}
|
||||
|
||||
if (!request.query.id) {
|
||||
logger.warn('Must supply id parameter to retrieve EMS vector style');
|
||||
return null;
|
||||
}
|
||||
|
||||
const tmsServices = await emsClient.getTMSServices();
|
||||
const tmsService = tmsServices.find((layer) => layer.getId() === request.query.id);
|
||||
if (!tmsService) {
|
||||
|
@ -342,8 +344,12 @@ export function initRoutes(router, licenseUid, mapConfig, kbnVersion, logger) {
|
|||
path: `${ROOT}/${EMS_TILES_API_PATH}/${EMS_TILES_VECTOR_SOURCE_PATH}`,
|
||||
validate: {
|
||||
query: schema.object({
|
||||
id: schema.maybe(schema.string()),
|
||||
id: schema.string(),
|
||||
sourceId: schema.maybe(schema.string()),
|
||||
elastic_tile_service_tos: schema.maybe(schema.string()),
|
||||
my_app_name: schema.maybe(schema.string()),
|
||||
my_app_version: schema.maybe(schema.string()),
|
||||
license: schema.maybe(schema.string()),
|
||||
}),
|
||||
},
|
||||
},
|
||||
|
@ -352,11 +358,6 @@ export function initRoutes(router, licenseUid, mapConfig, kbnVersion, logger) {
|
|||
return badRequest('map.proxyElasticMapsServiceInMaps disabled');
|
||||
}
|
||||
|
||||
if (!request.query.id || !request.query.sourceId) {
|
||||
logger.warn('Must supply id and sourceId parameter to retrieve EMS vector source');
|
||||
return null;
|
||||
}
|
||||
|
||||
const tmsServices = await emsClient.getTMSServices();
|
||||
const tmsService = tmsServices.find((layer) => layer.getId() === request.query.id);
|
||||
if (!tmsService) {
|
||||
|
@ -381,28 +382,21 @@ export function initRoutes(router, licenseUid, mapConfig, kbnVersion, logger) {
|
|||
path: `${ROOT}/${EMS_TILES_API_PATH}/${EMS_TILES_VECTOR_TILE_PATH}`,
|
||||
validate: {
|
||||
query: schema.object({
|
||||
id: schema.maybe(schema.string()),
|
||||
sourceId: schema.maybe(schema.string()),
|
||||
x: schema.maybe(schema.number()),
|
||||
y: schema.maybe(schema.number()),
|
||||
z: schema.maybe(schema.number()),
|
||||
id: schema.string(),
|
||||
sourceId: schema.string(),
|
||||
x: schema.number(),
|
||||
y: schema.number(),
|
||||
z: schema.number(),
|
||||
elastic_tile_service_tos: schema.maybe(schema.string()),
|
||||
my_app_name: schema.maybe(schema.string()),
|
||||
my_app_version: schema.maybe(schema.string()),
|
||||
license: schema.maybe(schema.string()),
|
||||
}),
|
||||
},
|
||||
},
|
||||
async (context, request, { ok, badRequest }) => {
|
||||
async (context, request, response) => {
|
||||
if (!checkEMSProxyEnabled()) {
|
||||
return badRequest('map.proxyElasticMapsServiceInMaps disabled');
|
||||
}
|
||||
|
||||
if (
|
||||
!request.query.id ||
|
||||
!request.query.sourceId ||
|
||||
typeof parseInt(request.query.x, 10) !== 'number' ||
|
||||
typeof parseInt(request.query.y, 10) !== 'number' ||
|
||||
typeof parseInt(request.query.z, 10) !== 'number'
|
||||
) {
|
||||
logger.warn('Must supply id/sourceId/x/y/z parameters to retrieve EMS vector tile');
|
||||
return null;
|
||||
return response.badRequest('map.proxyElasticMapsServiceInMaps disabled');
|
||||
}
|
||||
|
||||
const tmsServices = await emsClient.getTMSServices();
|
||||
|
@ -417,24 +411,29 @@ export function initRoutes(router, licenseUid, mapConfig, kbnVersion, logger) {
|
|||
.replace('{y}', request.query.y)
|
||||
.replace('{z}', request.query.z);
|
||||
|
||||
return await proxyResource({ url }, { ok, badRequest });
|
||||
return await proxyResource({ url }, response);
|
||||
}
|
||||
);
|
||||
|
||||
router.get(
|
||||
{
|
||||
path: `${ROOT}/${EMS_TILES_API_PATH}/${EMS_GLYPHS_PATH}/{fontstack}/{range}`,
|
||||
validate: false,
|
||||
validate: {
|
||||
params: schema.object({
|
||||
fontstack: schema.string(),
|
||||
range: schema.string(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
async (context, request, { ok, badRequest }) => {
|
||||
async (context, request, response) => {
|
||||
if (!checkEMSProxyEnabled()) {
|
||||
return badRequest('map.proxyElasticMapsServiceInMaps disabled');
|
||||
return response.badRequest('map.proxyElasticMapsServiceInMaps disabled');
|
||||
}
|
||||
const url = mapConfig.emsFontLibraryUrl
|
||||
.replace('{fontstack}', request.params.fontstack)
|
||||
.replace('{range}', request.params.range);
|
||||
|
||||
return await proxyResource({ url }, { ok, badRequest });
|
||||
return await proxyResource({ url }, response);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -442,19 +441,22 @@ export function initRoutes(router, licenseUid, mapConfig, kbnVersion, logger) {
|
|||
{
|
||||
path: `${ROOT}/${EMS_TILES_API_PATH}/${EMS_SPRITES_PATH}/{id}/sprite{scaling?}.{extension}`,
|
||||
validate: {
|
||||
query: schema.object({
|
||||
elastic_tile_service_tos: schema.maybe(schema.string()),
|
||||
my_app_name: schema.maybe(schema.string()),
|
||||
my_app_version: schema.maybe(schema.string()),
|
||||
license: schema.maybe(schema.string()),
|
||||
}),
|
||||
params: schema.object({
|
||||
id: schema.string(),
|
||||
scaling: schema.maybe(schema.string()),
|
||||
extension: schema.string(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
async (context, request, { ok, badRequest }) => {
|
||||
async (context, request, response) => {
|
||||
if (!checkEMSProxyEnabled()) {
|
||||
return badRequest('map.proxyElasticMapsServiceInMaps disabled');
|
||||
}
|
||||
|
||||
if (!request.params.id) {
|
||||
logger.warn('Must supply id parameter to retrieve EMS vector source sprite');
|
||||
return null;
|
||||
return response.badRequest('map.proxyElasticMapsServiceInMaps disabled');
|
||||
}
|
||||
|
||||
const tmsServices = await emsClient.getTMSServices();
|
||||
|
@ -479,7 +481,7 @@ export function initRoutes(router, licenseUid, mapConfig, kbnVersion, logger) {
|
|||
url: proxyPathUrl,
|
||||
contentType: request.params.extension === 'png' ? 'image/png' : '',
|
||||
},
|
||||
{ ok, badRequest }
|
||||
response
|
||||
);
|
||||
}
|
||||
);
|
||||
|
@ -570,25 +572,23 @@ export function initRoutes(router, licenseUid, mapConfig, kbnVersion, logger) {
|
|||
return proxyEMSInMaps;
|
||||
}
|
||||
|
||||
async function proxyResource({ url, contentType }, { ok, badRequest }) {
|
||||
async function proxyResource({ url, contentType }, response) {
|
||||
try {
|
||||
const resource = await fetch(url);
|
||||
const arrayBuffer = await resource.arrayBuffer();
|
||||
const bufferedResponse = Buffer.from(arrayBuffer);
|
||||
const headers = {
|
||||
'Content-Disposition': 'inline',
|
||||
};
|
||||
if (contentType) {
|
||||
headers['Content-type'] = contentType;
|
||||
}
|
||||
const buffer = Buffer.from(arrayBuffer);
|
||||
|
||||
return ok({
|
||||
body: bufferedResponse,
|
||||
headers,
|
||||
return response.ok({
|
||||
body: buffer,
|
||||
headers: {
|
||||
'content-disposition': 'inline',
|
||||
'content-length': buffer.length,
|
||||
...(contentType ? { 'Content-type': contentType } : {}),
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
logger.warn(`Cannot connect to EMS for resource, error: ${e.message}`);
|
||||
return badRequest(`Cannot connect to EMS`);
|
||||
return response.badRequest(`Cannot connect to EMS`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue