Skip to content

Commit

Permalink
[Backport 2024.01.xx]: #10281: Use Cache Options functionality extend…
Browse files Browse the repository at this point in the history
…ed to be applied on all the layers from a service (#10349, #10361) (#10363)

* fix conflicts in merging  #10281: Use Cache Options functionality extended to be applied on all the layers from a service (#10349)

* #10281: Use Cache Options functionality extended to be applied on all the layers from a service (#10361)

* #10281: Use Cache Options functionality extended to be applied on all the layers from a service
Description:
- handle a missing case of showing a warning message in case of not able to fetch the grid sets
- add unit tests

* fix FE unit test failure  #10281

* fix FE unit test failure  #10281
  • Loading branch information
mahmoudadel54 committed May 27, 2024
1 parent 549784e commit ff10464
Show file tree
Hide file tree
Showing 12 changed files with 188 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,10 @@ function WMSCacheOptions({
}) {

const [tileGridLoading, setTileGridLoading] = useState(false);
const [tileGridsResponseMsgId, setTileGridsResponseMsgId] = useState('');
const [tileGridsResponseMsgId, setTileGridsResponseMsgId] = useState(() => {
const noTileGrids = layer?.tileGridStrategy === 'custom' && layer?.tiled && layer?.tileGrids?.length === 0;
return noTileGrids ? "layerProperties.noConfiguredGridSets" : "";
});
const [tileGridsResponseMsgStyle, setTileGridsResponseMsgStyle] = useState('');
const [standardTileGridInfo, setStandardTileGridInfo] = useState({});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1045,5 +1045,30 @@ describe('WMSCacheOptions', () => {
.catch(done);

});
it('should display noConfiguredGridSets warning message if layer is configured from catalog to `Use Cache Options`, with no grid sets available', () => {
ReactDOM.render(<WMSCacheOptions layer={{
url: '/geoserver/wms',
name: 'topp:states',
tileGridStrategy: 'custom',
format: 'image/jpeg',
tileGridCacheSupport: {
formats: ['image/png']
},
tiled: true,
tileGrids: []
}} projection="EPSG:3857" />, document.getElementById('container'));
expect(document.querySelector('.ms-wms-cache-options')).toBeTruthy();
const inputs = document.querySelectorAll('input[type="checkbox"]');
expect(inputs.length).toBe(1);
const buttons = document.querySelectorAll('button');
expect(buttons.length).toBe(2);
expect([...buttons].map(button => button.querySelector('.glyphicon').getAttribute('class'))).toEqual([
'glyphicon glyphicon-refresh',
'glyphicon glyphicon-grid-custom'
]);

const alert = document.querySelector('.alert');
expect(alert.innerText).toBe('layerProperties.noConfiguredGridSets');
});
});

Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,14 @@ export default ({
onChange={event => onChangeServiceProperty("layerOptions", { ...service.layerOptions, serverType: event?.value })} />
</InputGroup>
</FormGroup>
{![ServerTypes.NO_VENDOR].includes(service.layerOptions?.serverType) && service.type === "wms" && <FormGroup controlId="useCacheOption" key="useCacheOption">
<Checkbox data-qa="display-interactive-legend-option"
onChange={(e) => onChangeServiceProperty("layerOptions", { ...service.layerOptions, remoteTileGrids: e.target.checked})}
checked={!isNil(service.layerOptions?.remoteTileGrids) ? service.layerOptions?.remoteTileGrids : false}>
<Message msgId="layerProperties.useCacheOptionInfo.label" />
&nbsp;<InfoPopover text={<Message msgId="layerProperties.useCacheOptionInfo.info" />} />
</Checkbox>
</FormGroup>}
<hr style={{margin: "8px 0"}}/>
<FormGroup style={advancedRasterSettingsStyles} className="form-group-flex">
<ControlLabel className="strong"><Message msgId="layerProperties.format.title" /></ControlLabel>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ describe('Test Raster advanced settings', () => {
const advancedSettingPanel = document.getElementsByClassName("mapstore-switch-panel");
expect(advancedSettingPanel).toBeTruthy();
const fields = document.querySelectorAll(".form-group");
expect(fields.length).toBe(13);
expect(fields.length).toBe(14);
});
it('test csw advanced options', () => {
ReactDOM.render(<RasterAdvancedSettings service={{type: "csw", autoload: false}}/>, document.getElementById("container"));
Expand Down Expand Up @@ -209,6 +209,25 @@ describe('Test Raster advanced settings', () => {
expect(spyOn).toHaveBeenCalled();
expect(spyOn.calls[1].arguments).toEqual([ 'allowUnsecureLayers', false ]);
});
it('test component onChangeServiceProperty useCacheOption for remote tile grids', () => {
const action = {
onChangeServiceProperty: () => {}
};
const spyOn = expect.spyOn(action, 'onChangeServiceProperty');
ReactDOM.render(<RasterAdvancedSettings
onChangeServiceProperty={action.onChangeServiceProperty}
service={{ type: "wms" }}
/>, document.getElementById("container"));
const advancedSettingsPanel = document.getElementsByClassName("mapstore-switch-panel");
expect(advancedSettingsPanel).toBeTruthy();
const formGroup = document.querySelectorAll('.form-group')[6];
expect(formGroup.textContent.trim()).toBe('layerProperties.useCacheOptionInfo.label');
const useCacheOption = formGroup.querySelector('input[type="checkbox"]');
expect(useCacheOption).toBeTruthy();
TestUtils.Simulate.change(useCacheOption, { "target": { "checked": true }});
expect(spyOn).toHaveBeenCalled();
expect(spyOn.calls[0].arguments).toEqual([ 'layerOptions', { remoteTileGrids: true } ]);
});
it('test component onChangeServiceProperty singleTile', () => {
const action = {
onChangeServiceProperty: () => {}
Expand Down
61 changes: 61 additions & 0 deletions web/client/epics/__tests__/catalog-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,67 @@ describe('catalog Epics', () => {
}
});
});
it('addLayerAndDescribeEpic for wms layer with remoteTileGrids = true', (done) => {
const layer = {
type: 'wms',
url: 'base/web/client/test-resources/wms/DescribeLayers.xml',
visibility: true,
dimensions: [],
name: 'workspace:vector_layer',
title: 'workspace:vector_layer',
bbox: {"crs": "EPSG:4326", "bounds": {"minx": "-103.87791475407893", "miny": "44.37246687108142", "maxx": "-103.62278893469492", "maxy": "44.50235105543566"}},
links: [],
params: {
CQL_FILTER: 'NAME=\'Test\''
},
allowedSRS: {
'EPSG:3857': true,
'EPSG:4326': true
},
remoteTileGrids: true
};
const NUM_ACTIONS = 3;
testEpic(addTimeoutEpic(addLayerAndDescribeEpic, 0), NUM_ACTIONS,
addLayerAndDescribe(layer),
(actions) => {
expect(actions.length).toBe(NUM_ACTIONS);
actions.map((action) => {
switch (action.type) {
case ADD_LAYER:
expect(action.layer.name).toBe("workspace:vector_layer");
expect(action.layer.title).toBe("workspace:vector_layer");
expect(action.layer.type).toBe("wms");
expect(action.layer.params).toEqual(layer.params);
break;
case CHANGE_LAYER_PROPERTIES:
expect(action.newProperties).toExist();
expect(action.newProperties.search).toExist();
expect(action.newProperties.search.url).toBe("http://some.geoserver.org:80/geoserver/wfs");
expect(action.newProperties.search.type).toBe("wfs");
expect(action.newProperties.tileGridStrategy).toEqual('custom');
expect(action.newProperties.tileGrids).toExist();
break;
case TEST_TIMEOUT:
break;
default:
expect(true).toBe(false);
}
});
done();
}, {
catalog: {
delayAutoSearch: 50,
selectedService: "wmsCatalog",
services: {
"wmsCatalog": {
type: "wms",
url: "base/web/client/test-resources/wms/GetCapabilities-1.1.1.xml"
}
},
pageSize: 2
}
});
});
it('addLayerAndDescribeEpic multiple urls', (done) => {
const layer = {
type: 'wms',
Expand Down
32 changes: 29 additions & 3 deletions web/client/epics/catalog.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import {
updateServiceData
} from '../utils/CatalogUtils';
import { getCapabilities, describeLayers, flatLayers } from '../api/WMS';
import {generateGeoServerWMTSUrl} from '../utils/WMTSUtils';
import CoordinatesUtils from '../utils/CoordinatesUtils';
import ConfigUtils from '../utils/ConfigUtils';
import {getCapabilitiesUrl, getLayerId, getLayerUrl, removeWorkspace, DEFAULT_GROUP_ID} from '../utils/LayersUtils';
Expand All @@ -75,6 +76,8 @@ import { extractGeometryType } from '../utils/WFSLayerUtils';
import { createDefaultStyle } from '../utils/StyleUtils';
import { removeDuplicateLines } from '../utils/StringUtils';
import { logError } from '../utils/DebugUtils';
import { isProjectionAvailable } from '../utils/ProjectionUtils';
import {getLayerTileMatrixSetsInfo} from '../api/WMTS';

const onErrorRecordSearch = (isNewService, errObj) => {
logError({message: errObj});
Expand Down Expand Up @@ -270,8 +273,28 @@ export default (API) => ({
actions.push(zoomToExtent(layer.bbox.bounds, layer.bbox.crs));
}
if (layer.type === 'wms') {
return Rx.Observable.defer(() => describeLayers(getLayerUrl(layer), layer.name))
.switchMap(results => {
// * fetch the api of cashe option if layer has 'remoteTileGrids' property with true value
return Rx.Observable.forkJoin(
Rx.Observable.defer(() => describeLayers(getLayerUrl(layer), layer.name)),
(!layer?.remoteTileGrids) ?
Rx.Observable.of(null) :
Rx.Observable.defer(() => getLayerTileMatrixSetsInfo(generateGeoServerWMTSUrl(layer), layer.name, layer))
.catch(() => Rx.Observable.of(null))
)
.switchMap(([results, tileGridData]) => {
let tileGridProperties = {};
if (tileGridData) {
const filteredTileGrids = tileGridData.tileGrids.filter(({ crs }) => isProjectionAvailable(CoordinatesUtils.normalizeSRS(crs)));
tileGridProperties = tileGridData !== undefined ? {
tiled: true,
tileGrids: tileGridData.tileGrids,
tileGridStrategy: 'custom',
tileGridCacheSupport: filteredTileGrids?.length > 0 ?
tileGridData.formats ? {formats: tileGridData.formats} : {}
: undefined
} : {};

}
if (results) {
let description = find(results, (desc) => desc.name === layer.name );
if (description && description.owsType === 'WFS') {
Expand All @@ -280,9 +303,12 @@ export default (API) => ({
search: {
url: filteredUrl,
type: 'wfs'
}
}, ...tileGridProperties
}));
}
return Rx.Observable.of(changeLayerProperties(id, {
...tileGridProperties
}));
}
return Rx.Observable.empty();
})
Expand Down
23 changes: 21 additions & 2 deletions web/client/plugins/widgetbuilder/MapBuilder.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ import mapToolbar from './enhancers/mapToolbar';
import MapLayerSelectorComp from './MapLayerSelector';
import MapSelector from './MapSelector';
import { catalogEditorEnhancer } from './enhancers/catalogEditorEnhancer';
import { getLayerTileMatrixSetsInfo } from '../../api/WMTS';
import { generateGeoServerWMTSUrl } from '../../utils/WMTSUtils';
import { isProjectionAvailable } from '../../utils/ProjectionUtils';
import { normalizeSRS } from '../../utils/CoordinatesUtils';


const Toolbar = mapToolbar(ToolbarComp);
Expand All @@ -51,8 +55,23 @@ const chooseMapEnhancer = compose(
manageLayers,
withHandlers({
onLayerChoice: ({ toggleLayerSelector = () => { }, addLayer = () => { } }) => (layer) => {
addLayer(layer);
toggleLayerSelector(false);
// fetching 'tileGridData' if layer has truthy flag 'remoteTileGrids' and adding the required props to layer object
let tileGridPromise = layer.type === 'wms' && layer.remoteTileGrids ? getLayerTileMatrixSetsInfo(generateGeoServerWMTSUrl(layer), layer.name, layer) : new Promise((resolve) => resolve(null));
tileGridPromise.then((tileGridData) => {
let tileGridProperties = {};
if (tileGridData) {
const filteredTileGrids = tileGridData.tileGrids.filter(({ crs }) => isProjectionAvailable(normalizeSRS(crs)));
tileGridProperties = tileGridData !== undefined ? {
tileGrids: tileGridData.tileGrids,
tileGridStrategy: 'custom',
tileGridCacheSupport: filteredTileGrids?.length > 0 ?
tileGridData.formats ? {formats: tileGridData.formats} : {}
: undefined
} : {};
}
addLayer({...layer, ...tileGridProperties});
toggleLayerSelector(false);
});
}
}),
layerSelector
Expand Down
4 changes: 4 additions & 0 deletions web/client/translations/data.de-DE.json
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,10 @@
"label": "Lokalisierten Stil aktivieren",
"tooltip": "Hinweis: Diese Einstellung benötigt spezifische Konfigurationen im GeoServer"
},
"useCacheOptionInfo": {
"label": "Verwenden Sie entfernte benutzerdefinierte Kachelraster",
"info": "Stellen Sie sicher, dass WMTS aktiviert ist, um benutzerdefinierte Kachelraster verwenden zu können"
},
"format": {
"title": "Format",
"tile": "Fliese",
Expand Down
4 changes: 4 additions & 0 deletions web/client/translations/data.en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,10 @@
"label": "Enable localized style",
"tooltip": "Note: This parameter requires specific configurations on GeoServer"
},
"useCacheOptionInfo": {
"label": "Use remote custom tile grids",
"info": "Make sure to have WMTS enabled in order to use custom tile grids"
},
"format": {
"title": "Format",
"tile": "Tile",
Expand Down
4 changes: 4 additions & 0 deletions web/client/translations/data.es-ES.json
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,10 @@
"label": "Habilitar estilo localizado",
"tooltip": "Nota: este parámetro requiere configuraciones específicas en GeoServer"
},
"useCacheOptionInfo": {
"label": "Utilice cuadrículas de mosaicos personalizadas remotas",
"info": "Asegúrese de que WMTS esté habilitado para poder usar cuadrículas de mosaicos personalizadas"
},
"format": {
"title": "Formato",
"tile": "Teja",
Expand Down
4 changes: 4 additions & 0 deletions web/client/translations/data.fr-FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,10 @@
"label": "Activer le style localisé",
"tooltip": "Remarque: ce paramètre nécessite des configurations spécifiques sur GeoServer"
},
"useCacheOptionInfo": {
"label": "Utiliser des grilles de carreaux personnalisées à distance",
"info": "Assurez-vous que WMTS est activé afin d'utiliser des grilles de tuiles personnalisées"
},
"format": {
"title": "Format",
"tile": "Tile",
Expand Down
4 changes: 4 additions & 0 deletions web/client/translations/data.it-IT.json
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,10 @@
"label": "Abilita stile localizzato",
"tooltip": "Nota: questo parametro richiede configurazioni specifiche su GeoServer"
},
"useCacheOptionInfo": {
"label": "Utilizza griglie di riquadri personalizzate remote",
"info": "Assicurati che WMTS sia abilitato per utilizzare griglie di riquadri personalizzate"
},
"format": {
"title": "Formato",
"tile": "Tile",
Expand Down

0 comments on commit ff10464

Please sign in to comment.