Skip to content

Commit

Permalink
Fix #4009 wms records and improved error handling (#4109)
Browse files Browse the repository at this point in the history
* Fix #4009 wms records and improved error handling

* fix lint error
  • Loading branch information
MV88 authored and Tobia Di Pisa committed Aug 27, 2019
1 parent 2759462 commit 66e3435
Show file tree
Hide file tree
Showing 17 changed files with 190 additions and 25 deletions.
10 changes: 5 additions & 5 deletions docs/developer-guide/map-query-parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ To dispatch additional actions when the map viewer is started, the **actions** q
"initialActionsWhiteList": ["ZOOM_TO_EXTENT", "ADD_LAYER", ...]
```

The value of this paramater is a JSON string containing an array with an object per action. The structure of the object consist of a property type and a bunch of other properties depending on the action.
The value of this parameter is a JSON string containing an array with an object per action. The structure of the object consist of a property type and a bunch of other properties depending on the action.

### Available actions
Only the following actions can be used in the **actions** json string.
Expand Down Expand Up @@ -78,18 +78,18 @@ For more details check out the [searchLayerWithFilter](https://mapstore2.geo-sol

#### Add Layers

This action allows to add layers from catalog present in the map
This action allows to add layers directly to the map by taking them from the Catalogs

Requirements:
- the number of values must be even
- catalog name must be present in the map

- The number of layers should match the number of sources
- The source name must match a catalog service name present in the map

Example:
```
{
"type": "CATALOG:ADD_LAYERS_FROM_CATALOGS",
"layers": ["layer1", "layer2"],
"layers": ["workspace1:layer1", "workspace2:layer2"],
"sources": ["catalog1", "catalog2"]
}
?actions=[{"type":"CATALOG:ADD_LAYERS_FROM_CATALOGS","layers":["layer1", "layer2"],"sources":["catalog1", "catalog2"]}]
Expand Down
10 changes: 9 additions & 1 deletion web/client/actions/__tests__/catalog-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ const {
changeUrl, CHANGE_URL, changeType, CHANGE_TYPE, addService, ADD_SERVICE, addCatalogService, ADD_CATALOG_SERVICE, resetCatalog, RESET_CATALOG,
changeAutoload, CHANGE_AUTOLOAD, deleteCatalogService, DELETE_CATALOG_SERVICE, deleteService, DELETE_SERVICE, savingService,
SAVING_SERVICE, DESCRIBE_ERROR, initCatalog, CATALOG_INITED, changeText, CHANGE_TEXT,
TOGGLE_ADVANCED_SETTINGS, toggleAdvancedSettings, TOGGLE_THUMBNAIL, toggleThumbnail, TOGGLE_TEMPLATE, toggleTemplate, CHANGE_METADATA_TEMPLATE, changeMetadataTemplate, SET_LOADING
TOGGLE_ADVANCED_SETTINGS, toggleAdvancedSettings, TOGGLE_THUMBNAIL, toggleThumbnail, TOGGLE_TEMPLATE, toggleTemplate, CHANGE_METADATA_TEMPLATE, changeMetadataTemplate, SET_LOADING,
recordsNotFound
} = require('../catalog');
const {CHANGE_LAYER_PROPERTIES, ADD_LAYER} = require('../layers');
const {SHOW_NOTIFICATION} = require('../notifications');
describe('Test correctness of the catalog actions', () => {

it('addLayersMapViewerUrl', () => {
Expand Down Expand Up @@ -295,4 +297,10 @@ describe('Test correctness of the catalog actions', () => {
expect(action.type).toBe(CHANGE_METADATA_TEMPLATE);
expect(action.metadataTemplate).toBe("${title}");
});
it('test recordsNotFound action', () => {
const action = recordsNotFound("topp:states , topp:states-tasmania");
expect(action.type).toBe(SHOW_NOTIFICATION);
expect(action.message).toBe("catalog.notification.errorSearchingRecords");
expect(action.values).toEqual({records: "topp:states , topp:states-tasmania"});
});
});
11 changes: 11 additions & 0 deletions web/client/actions/catalog.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import * as ConfigUtils from '../utils/ConfigUtils';
import {find} from 'lodash';
import {authkeyParamNameSelector} from '../selectors/catalog';


export const ADD_LAYERS_FROM_CATALOGS = 'CATALOG:ADD_LAYERS_FROM_CATALOGS';
export const TEXT_SEARCH = 'CATALOG:TEXT_SEARCH';
export const RECORD_LIST_LOADED = 'CATALOG:RECORD_LIST_LOADED';
Expand Down Expand Up @@ -281,3 +282,13 @@ export const changeMetadataTemplate = (metadataTemplate) => ({type: CHANGE_METAD
export const toggleAdvancedSettings = () => ({type: TOGGLE_ADVANCED_SETTINGS});
export const toggleTemplate = () => ({type: TOGGLE_TEMPLATE});
export const toggleThumbnail = () => ({type: TOGGLE_THUMBNAIL});

import {error} from './notifications';

export function recordsNotFound(records = "") {
return error({
title: "catalog.notification.errorTitle",
message: "catalog.notification.errorSearchingRecords",
values: {records}
});
}
87 changes: 87 additions & 0 deletions web/client/epics/__tests__/catalog-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@

import expect from 'expect';
import csw from '../../api/CSW';
import wms from '../../api/WMS';
import wmts from '../../api/WMTS';
const API = {
csw,
wms,
wmts
};
import catalog from '../catalog';
Expand All @@ -37,6 +39,7 @@ import {
SET_LOADING
} from '../../actions/catalog';


describe('catalog Epics', () => {
it('getMetadataRecordById', (done) => {
testEpic(getMetadataRecordById, 2, initAction(), (actions) => {
Expand Down Expand Up @@ -185,6 +188,90 @@ describe('catalog Epics', () => {
}
});
});
it('addLayersFromCatalogsEpic csw and wms both found', (done) => {
const NUM_ACTIONS = 3;
testEpic(addTimeoutEpic(addLayersFromCatalogsEpic, 10), NUM_ACTIONS, addLayersMapViewerUrl(["gs:us_states", "some_layer"], ["cswCatalog", "wmsCatalog"]), (actions) => {
expect(actions.length).toBe(NUM_ACTIONS);
actions.map((action) => {
switch (action.type) {
case ADD_LAYER:
if (action.layer.name === "gs:us_states") {
expect(action.layer.title).toBe("States of US");
expect(action.layer.type).toBe("wms");
expect(action.layer.url).toBe("https://sample.server/geoserver/wms");
} else {
expect(action.layer.name).toBe("some_layer");
expect(action.layer.title).toBe("some layer");
expect(action.layer.type).toBe("wms");
expect(action.layer.url).toBe("base/web/client/test-resources/wms/attribution.xml");
}
break;
case TEST_TIMEOUT:
break;
default:
expect(true).toBe(false);
}
});
done();
}, {
catalog: {
delayAutoSearch: 50,
selectedService: "cswCatalog",
services: {
"cswCatalog": {
type: "csw",
url: "base/web/client/test-resources/csw/getRecordsResponse-gs-us_states.xml"
},
"wmsCatalog": {
type: "wms",
url: "base/web/client/test-resources/wms/attribution.xml"
}
},
pageSize: 2
}
});
});
it('addLayersFromCatalogsEpic csw found and wms not found', (done) => {
const NUM_ACTIONS = 3;
testEpic(addTimeoutEpic(addLayersFromCatalogsEpic, 10), NUM_ACTIONS, addLayersMapViewerUrl(["gs:us_states", "not_found"], ["cswCatalog", "wmsCatalog"]), (actions) => {
expect(actions.length).toBe(NUM_ACTIONS);
actions.map((action) => {
switch (action.type) {
case ADD_LAYER:
expect(action.layer.name).toBe("gs:us_states");
expect(action.layer.title).toBe("States of US");
expect(action.layer.type).toBe("wms");
expect(action.layer.url).toBe("https://sample.server/geoserver/wms");
break;
case SHOW_NOTIFICATION:
expect(action.message).toBe("catalog.notification.errorSearchingRecords");
expect(action.values).toEqual({records: "not_found"});
break;
case TEST_TIMEOUT:
break;
default:
expect(true).toBe(false);
}
});
done();
}, {
catalog: {
delayAutoSearch: 50,
selectedService: "cswCatalog",
services: {
"cswCatalog": {
type: "csw",
url: "base/web/client/test-resources/csw/getRecordsResponse-gs-us_states.xml"
},
"wmsCatalog": {
type: "wms",
url: "base/web/client/test-resources/wms/attribution.xml"
}
},
pageSize: 2
}
});
});
it('addLayersFromCatalogsEpic wmts', (done) => {
const NUM_ACTIONS = 2;
testEpic(addTimeoutEpic(addLayersFromCatalogsEpic, 0), NUM_ACTIONS, addLayersMapViewerUrl(["topp:tasmania_cities_hidden"], ["cswCatalog"]), (actions) => {
Expand Down
47 changes: 31 additions & 16 deletions web/client/epics/catalog.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

import * as Rx from 'rxjs';
import {head, isArray} from 'lodash';
import {head, isArray, isString, isObject} from 'lodash';
import {
ADD_SERVICE,
ADD_LAYERS_FROM_CATALOGS,
Expand All @@ -18,6 +18,7 @@ import {
addCatalogService,
setLoading,
deleteCatalogService,
recordsNotFound,
recordsLoaded,
recordsLoadError,
savingService,
Expand Down Expand Up @@ -94,7 +95,9 @@ module.exports = (API) => ({
addLayersFromCatalogsEpic: (action$, store) =>
action$.ofType(ADD_LAYERS_FROM_CATALOGS)
.filter(({layers, sources}) => isArray(layers) && isArray(sources) && layers.length && layers.length === sources.length)
.switchMap(({layers, sources, options, startPosition = 1, maxRecords = 1 }) => {
// maxRecords is 4 (by default), but there can be a possibility that the record desired is not among
// the results. In that case a more detailed search with full record name can be helpful
.switchMap(({layers, sources, options, startPosition = 1, maxRecords = 4 }) => {
const state = store.getState();
const addLayerOptions = options || searchOptionsSelector(state);
const services = servicesSelector(state);
Expand All @@ -104,23 +107,17 @@ module.exports = (API) => ({
const {type: format, url} = services[sources[i]];
const text = layers[i];
return Rx.Observable.defer( () =>
API[format].textSearch(url, startPosition, maxRecords, text, addLayerOptions)
).map(r => ({...r, format, url}));
API[format].textSearch(url, startPosition, maxRecords, text, addLayerOptions).catch(() => ({results: []}))
).map(r => ({...r, format, url, text}));
});
return Rx.Observable.forkJoin(actions)
.switchMap((results) => {
if (isArray(results) && results.length) {
return Rx.Observable.from(results.filter(r => {
// filter results with no records
const {format, url, ...result} = r;
return Rx.Observable.of(results.map(r => {
const {format, url, text, ...result} = r;
const locales = currentMessagesSelector(state);
const records = getCatalogRecords(format, result, addLayerOptions, locales) || [];
return records && records.length >= 1;
}).map(r => {
const {format, url, ...result} = r;
const locales = currentMessagesSelector(state);
const records = getCatalogRecords(format, result, addLayerOptions, locales) || [];
const record = head(records);
const record = head(records.filter(rec => rec.identifier === text)); // exact match of text and record identifier
const {wms, wmts} = extractOGCServicesReferences(record);
let layer = {};
const layerBaseConfig = {}; // DO WE NEED TO FETCH IT FROM STATE???
Expand All @@ -133,7 +130,7 @@ module.exports = (API) => ({
}
layer = recordToLayer(record, "wms", {
removeParams: authkeyParamName,
catalogURL: format === 'csw' && url ? url + "?request=GetRecordById&service=CSW&version=2.0.2&elementSetName=full&id=" + record.identifier : null
catalogURL: format === 'csw' && url ? url + "?request=GetRecordById&service=CSW&version=2.0.2&elementSetName=full&id=" + record.identifier : url
}, layerBaseConfig);
} else if (wmts) {
layer = {};
Expand All @@ -151,12 +148,30 @@ module.exports = (API) => ({
layer = esriToLayer(record, layerBaseConfig);
}
}
return addLayer(layer);
if (!record) {
return text;
}
return layer;
}));
}
return Rx.Observable.empty();
});
}).catch( () => {
})
.mergeMap(results => {
if (results) {
const allRecordsNotFound = results.filter(r => isString(r)).join(" ");
let actions = [];
if (allRecordsNotFound) {
// return one notification for all records that have not been found
actions = [recordsNotFound(allRecordsNotFound)];
}
// add all layers found to the map
actions = [...actions, ...results.filter(r => isObject(r)).map(r => addLayer(r))];
return Rx.Observable.from(actions);
}
return Rx.Observable.empty();
})
.catch( () => {
return Rx.Observable.empty();
}),
/**
Expand Down
2 changes: 2 additions & 0 deletions web/client/translations/data.de-DE
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,8 @@
"advancedSettings": "Erweiterte Einstellungen",
"templateMetadataAvailable": "Metadaten im Dublin Core-Format verfügbar: abstract, boundingBox, contributor, creator, description, format, identifier, references, rights, source, subject, temporal, title, type, uri",
"notification": {
"errorTitle": "Error",
"errorSearchingRecords": "Einige Datensätze wurden nicht gefunden: {records} . Bitte überprüfen Sie die URL des Abfrageparameters",
"warningAddCatalogService": "Geben Sie eine gültige URL und einen Titel ein",
"addCatalogService": "Service wurde korrekt hinzugefügt",
"duplicatedServiceTitle": "Ein Service mit diesem Titel existiert bereits, bitte ändere den Titel",
Expand Down
2 changes: 2 additions & 0 deletions web/client/translations/data.en-US
Original file line number Diff line number Diff line change
Expand Up @@ -1139,6 +1139,8 @@
"advancedSettings": "Advanced settings",
"templateMetadataAvailable": "Metadata available from Dublin Core format: abstract, boundingBox, contributor, creator, description, format, identifier, references, rights, source, subject, temporal, title, type, uri",
"notification": {
"errorTitle": "Error",
"errorSearchingRecords": "Some records have not been found: {records} Please check the query param url",
"warningAddCatalogService": "Insert a valid url and title",
"addCatalogService": "Service added correctly",
"duplicatedServiceTitle": "A service with that title already exists. Please, change title",
Expand Down
2 changes: 2 additions & 0 deletions web/client/translations/data.es-ES
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,8 @@
"advancedSettings": "Ajustes avanzados",
"templateMetadataAvailable": "Metadatos disponibles en formato Dublin Core: abstract, boundingBox, contributor, creator, description, format, identifier, references, rights, source, subject, temporal, title, type, uri",
"notification": {
"errorTitle": "Error",
"errorSearchingRecords": "No se han encontrado algunos registros: {records} . Por favor revise la consulta param url",
"warningAddCatalogService": "Introduzca una url y un título válidos",
"addCatalogService": "Servicio añadido correctamente",
"duplicatedServiceTitle": "Ya existe un servicio con ese título, Por favor, cambie el título",
Expand Down
2 changes: 2 additions & 0 deletions web/client/translations/data.fr-FR
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,8 @@
"advancedSettings": "Réglages avancés",
"templateMetadataAvailable": "Métadonnées disponibles au format Dublin Core: abstract, boundingBox, contributor, creator, description, format, identifier, references, rights, source, subject, temporal, title, type, uri",
"notification": {
"errorTitle": "Erreur",
"errorSearchingRecords": "Certains enregistrements n'ont pas été trouvés: {records} . S'il vous plaît vérifier la requête param url",
"warningAddCatalogService": "Insérer une URL et un titre valides",
"addCatalogService": "Service ajouté correctement",
"duplicatedServiceTitle": "Un service avec ce titre existe déjà, veuillez modifier le titre",
Expand Down
2 changes: 2 additions & 0 deletions web/client/translations/data.hr-HR
Original file line number Diff line number Diff line change
Expand Up @@ -1139,6 +1139,8 @@
"advancedSettings": "Napredne mogućnosti",
"templateMetadataAvailable": "Metapodaci distupni iz Dublin Core formata: abstract, boundingBox, contributor, creator, description, format, identifier, references, rights, source, subject, temporal, title, type, uri",
"notification": {
"errorTitle": "Error",
"errorSearchingRecords": "Some records have not been found: {records} Please check the query param url",
"warningAddCatalogService": "Unesi ispravni url i naslov",
"addCatalogService": "Servis je dodan ispravno",
"duplicatedServiceTitle": "Servis sa tim naslovom već postoji. Molim, promijenite naslov",
Expand Down
2 changes: 2 additions & 0 deletions web/client/translations/data.it-IT
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,8 @@
"advancedSettings": "Impostazioni avanzante",
"templateMetadataAvailable": "Metadati disponibili del formato Dublin Core: abstract, boundingBox, contributor, creator, description, format, identifier, references, rights, source, subject, temporal, title, type, uri",
"notification": {
"errorTitle": "Errore",
"errorSearchingRecords": "Alcuni record non sono stati trovati: {records} . Controlla la lista dei parametri nella barra degli indirizzi",
"warningAddCatalogService": "Inserisci un url e titolo validi.",
"addCatalogService": "Servizio aggiunto corretamente.",
"duplicatedServiceTitle": "Un servizio con quel titolo esiste già, Per favore cambia titolo",
Expand Down
Loading

0 comments on commit 66e3435

Please sign in to comment.