Skip to content

Commit

Permalink
Fix/tms without ems access (elastic#28111)
Browse files Browse the repository at this point in the history
* Consolidate ems/tms request error handling, add timeout, ensure consistent return types

* Ensure tms is loaded (if configured), otherwise EMS. If neither is available, nothing is loaded

* Up time limit to 32 seconds
  • Loading branch information
kindsun authored Jan 7, 2019
1 parent d80adb3 commit 837b00f
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 50 deletions.
103 changes: 60 additions & 43 deletions src/legacy/core_plugins/tile_map/common/ems_client.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,10 @@ const unescapeTemplateVars = url => {
const DEFAULT_LANGUAGE = 'en';



export class EMSClientV66 {

EMS_LOAD_TIMEOUT = 32000;

constructor({ kbnVersion, manifestServiceUrl, htmlSanitizer, language, landingPageUrl }) {

Expand All @@ -103,7 +105,6 @@ export class EMSClientV66 {

this._sanitizer = htmlSanitizer ? htmlSanitizer : x => x;
this._manifestServiceUrl = manifestServiceUrl;
this._loadCatalogue = null;
this._loadFileLayers = null;
this._loadTMSServices = null;
this._emsLandingPageUrl = landingPageUrl;
Expand All @@ -125,11 +126,39 @@ export class EMSClientV66 {
* this internal method is overridden by the tests to simulate custom manifest.
*/
async _getManifest(manifestUrl) {
const url = extendUrl(manifestUrl, { query: this._queryParams });
const result = await fetch(url);
return await result.json();
let result;
try {
const url = extendUrl(manifestUrl, { query: this._queryParams });
result = await this._fetchWithTimeout(url);
} catch (e) {
if (!e) {
e = new Error('Unknown error');
}
if (!(e instanceof Error)) {
e = new Error(e.data || `status ${e.statusText || e.status}`);
}
throw new Error(`Unable to retrieve manifest from ${manifestUrl}: ${e.message}`);
} finally {
return result
? await result.json()
: null;
}
}

_fetchWithTimeout(url) {
return new Promise(
(resolve, reject) => {
const timer = setTimeout(
() => reject(new Error(`Request to ${url} timed out`)),
this.EMS_LOAD_TIMEOUT
);
fetch(url)
.then(
response => resolve(response),
err => reject(err)
).finally(() => clearTimeout(timer));
});
}

/**
* Add optional query-parameters to all requests
Expand All @@ -151,54 +180,42 @@ export class EMSClientV66 {

_invalidateSettings() {

this._loadCatalogue = _.once(async () => {
this._getManifestWithParams = _.once(
async url => this._getManifest(this.extendUrlWithParams(url)));

try {
const url = this.extendUrlWithParams(this._manifestServiceUrl);
return await this._getManifest(url);
} catch (e) {
if (!e) {
e = new Error('Unknown error');
}
if (!(e instanceof Error)) {
e = new Error(e.data || `status ${e.statusText || e.status}`);
}
throw new Error(`Could not retrieve manifest from the tile service: ${e.message}`);
this._getCatalogueService = async serviceType => {
const catalogueManifest = await this._getManifestWithParams(this._manifestServiceUrl);
let service;
if(_.has(catalogueManifest, 'services')) {
service = catalogueManifest.services
.find(s => s.type === serviceType);
}
});


this._loadFileLayers = _.once(async () => {
return service || {};
};

const catalogue = await this._loadCatalogue();
const fileService = catalogue.services.find(service => service.type === 'file');
if (!fileService) {
return [];
this._wrapServiceAttribute = async (manifestUrl, attr, WrapperClass) => {
const manifest = await this._getManifest(manifestUrl);
if (_.has(manifest, attr)) {
return manifest[attr].map(config => {
return new WrapperClass(config, this);
});
}
return [];
};

const manifest = await this._getManifest(fileService.manifest, this._queryParams);

return manifest.layers.map(layerConfig => {
return new FileLayer(layerConfig, this);
});
this._loadFileLayers = _.once(async () => {
const fileService = await this._getCatalogueService('file');
return _.isEmpty(fileService)
? []
: this._wrapServiceAttribute(fileService.manifest, 'layers', FileLayer);
});

this._loadTMSServices = _.once(async () => {

const catalogue = await this._loadCatalogue();
const tmsService = catalogue.services.find((service) => service.type === 'tms');
if (!tmsService) {
return [];
}
const tmsManifest = await this._getManifest(tmsService.manifest, this._queryParams);


return tmsManifest.services.map(serviceConfig => {
return new TMSService(serviceConfig, this);
});

const tmsService = await this._getCatalogueService('tms');
return _.isEmpty(tmsService)
? []
: await this._wrapServiceAttribute(tmsService.manifest, 'services', TMSService);
});

}

getLandingPageUrl() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ export function BaseMapsVisualizationProvider(serviceSettings, i18n) {

async _updateBaseLayer() {

const DEFAULT_EMS_BASEMAP = 'road_map';

if (!this._kibanaMap) {
return;
}
Expand All @@ -151,13 +153,11 @@ export function BaseMapsVisualizationProvider(serviceSettings, i18n) {
if (!this._tmsConfigured()) {
try {
const tmsServices = await serviceSettings.getTMSServices();
const firstRoadMapLayer = tmsServices.find((s) => {
return s.id === 'road_map';//first road map layer
});
const fallback = firstRoadMapLayer ? firstRoadMapLayer : tmsServices[0];
if (fallback) {
this._setTmsLayer(firstRoadMapLayer);
}
const userConfiguredTmsLayer = tmsServices[0];
const initBasemapLayer = userConfiguredTmsLayer
? userConfiguredTmsLayer
: tmsServices.find(s => s.id === DEFAULT_EMS_BASEMAP);
if (initBasemapLayer) { this._setTmsLayer(initBasemapLayer); }
} catch (e) {
toastNotifications.addWarning(e.message);
return;
Expand Down

0 comments on commit 837b00f

Please sign in to comment.