From a28d2433a019e0d01c8c83bfe72549117dae0acb Mon Sep 17 00:00:00 2001 From: "francesco.mangiacrapa" Date: Mon, 5 Jun 2023 16:54:40 +0200 Subject: [PATCH] Passing WFS requests from the servlet due to CORS issue, see #25074?#note-7 --- .settings/org.eclipse.wst.common.component | 32 ++-- .../client/GeoportalDataViewerService.java | 8 + .../GeoportalDataViewerServiceAsync.java | 2 + .../CrossFilteringLayerPanel.java | 163 ++++++++---------- .../client/ui/util/OLGeoJSONUtil.java | 30 ++-- .../client/util/URLUtil.java | 2 +- .../GeoportalDataViewerServiceImpl.java | 57 ++---- .../server/util/HTTPRequestUtil.java | 69 ++++++++ .../server/util/URLParserUtil.java | 2 +- 9 files changed, 214 insertions(+), 151 deletions(-) create mode 100644 src/main/java/org/gcube/portlets/user/geoportaldataviewer/server/util/HTTPRequestUtil.java diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component index 9a321a3..5714c34 100644 --- a/.settings/org.eclipse.wst.common.component +++ b/.settings/org.eclipse.wst.common.component @@ -1,5 +1,6 @@ - + + @@ -83,7 +84,8 @@ - + + @@ -167,7 +169,8 @@ - + + @@ -251,7 +254,8 @@ - + + @@ -335,7 +339,8 @@ - + + @@ -419,7 +424,8 @@ - + + @@ -503,10 +509,11 @@ - + uses - + + @@ -590,7 +597,8 @@ - + + @@ -674,7 +682,8 @@ - + + @@ -758,7 +767,8 @@ - + + diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/GeoportalDataViewerService.java b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/GeoportalDataViewerService.java index 9b9840b..3c9d549 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/GeoportalDataViewerService.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/GeoportalDataViewerService.java @@ -219,4 +219,12 @@ public interface GeoportalDataViewerService extends RemoteService { Map>> getAvaiableCustomGroupedLayersForUCD( GEOPORTAL_DATA_HANDLER theHandler); + /** + * Gets the HTTP response for URL. + * + * @param url the url + * @return the HTTP response for URL + */ + String getHTTPResponseForURL(String url); + } diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/GeoportalDataViewerServiceAsync.java b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/GeoportalDataViewerServiceAsync.java index ada1daf..a9b335b 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/GeoportalDataViewerServiceAsync.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/GeoportalDataViewerServiceAsync.java @@ -89,4 +89,6 @@ public interface GeoportalDataViewerServiceAsync { void getAvaiableCustomGroupedLayersForUCD(GEOPORTAL_DATA_HANDLER theHandler, AsyncCallback>>> callback); + void getHTTPResponseForURL(String url, AsyncCallback callback); + } diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/crossfiltering/CrossFilteringLayerPanel.java b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/crossfiltering/CrossFilteringLayerPanel.java index cd162d7..c93fbd1 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/crossfiltering/CrossFilteringLayerPanel.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/crossfiltering/CrossFilteringLayerPanel.java @@ -11,6 +11,7 @@ import org.gcube.application.geoportalcommon.shared.geoportal.config.layers.Laye import org.gcube.application.geoportalcommon.shared.geoportal.materialization.GCubeSDILayer; import org.gcube.application.geoportalcommon.shared.geoportal.materialization.IndexLayerDV; import org.gcube.portlets.user.geoportaldataviewer.client.GeoportalDataViewerConstants.MAP_PROJECTION; +import org.gcube.portlets.user.geoportaldataviewer.client.GeoportalDataViewerServiceAsync; import org.gcube.portlets.user.geoportaldataviewer.client.events.ApplyCQLToLayerMapEvent; import org.gcube.portlets.user.geoportaldataviewer.client.ui.util.OLGeoJSONUtil; import org.gcube.portlets.user.geoportaldataviewer.client.util.LoaderIcon; @@ -37,14 +38,10 @@ import com.google.gwt.event.dom.client.ChangeHandler; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.shared.HandlerManager; -import com.google.gwt.http.client.Request; -import com.google.gwt.http.client.RequestBuilder; -import com.google.gwt.http.client.RequestCallback; -import com.google.gwt.http.client.RequestException; -import com.google.gwt.http.client.Response; import com.google.gwt.http.client.URL; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.HTMLPanel; @@ -64,9 +61,6 @@ public class CrossFilteringLayerPanel extends Composite { public static String COLORSCALERANGE = "COLORSCALERANGE"; - // @UiField - // WellForm panelContainer; - @UiField Fieldset fieldSet; @@ -218,52 +212,55 @@ public class CrossFilteringLayerPanel extends Composite { } GWT.log("wfsURL request: " + wfsURL); - RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, wfsURL); - try { + GeoportalDataViewerServiceAsync.Util.getInstance().getHTTPResponseForURL(wfsURL, + new AsyncCallback() { - Request response = builder.sendRequest(null, new RequestCallback() { - public void onError(Request request, Throwable exception) { - // Code omitted for clarity - } + @Override + public void onSuccess(String response) { + GWT.log("wfsURL response: " + response); + Feature[] features = OLGeoJSONUtil.readGeoJsonFeatures(MAP_PROJECTION.EPSG_4326, response); - public void onResponseReceived(Request request, Response response) { - GWT.log("wfsURL response: " + response.getText()); - Feature[] features = OLGeoJSONUtil.readGeoJsonFeatures(MAP_PROJECTION.EPSG_4326, - response.getText()); + for (Feature feature : features) { + JsPropertyMap properties = feature.getProperties(); + Object keyValue = properties.get(crossFilteringLayer.getTable_key_field()); + Object itemField = properties.get(crossFilteringLayer.getTable_show_field()); - for (Feature feature : features) { - JsPropertyMap properties = feature.getProperties(); - Object keyValue = properties.get(crossFilteringLayer.getTable_key_field()); - Object itemField = properties.get(crossFilteringLayer.getTable_show_field()); + Object parentKey = null; + if (crossFilteringLayer.getTable_parent_key_field() != null + && !crossFilteringLayer.getTable_parent_key_field().isEmpty()) + parentKey = properties.get(crossFilteringLayer.getTable_parent_key_field()); - Object parentKey = null; - if (crossFilteringLayer.getTable_parent_key_field() != null - && !crossFilteringLayer.getTable_parent_key_field().isEmpty()) - parentKey = properties.get(crossFilteringLayer.getTable_parent_key_field()); + parentKey = parentKey == null ? "" : parentKey; - parentKey = parentKey == null ? "" : parentKey; + SelectableItem selectableItem = new SelectableItem( + crossFilteringLayer.getTable_key_field() + "", keyValue + "", + crossFilteringLayer.getTable_parent_key_field(), itemField + "", + crossFilteringLayer.getName(), crossFilteringLayer.getTable_geometry_name()); + GWT.log("selectableItem: " + selectableItem); - SelectableItem selectableItem = new SelectableItem( - crossFilteringLayer.getTable_key_field() + "", keyValue + "", - crossFilteringLayer.getTable_parent_key_field(), itemField + "", - crossFilteringLayer.getName(), crossFilteringLayer.getTable_geometry_name()); - GWT.log("selectableItem: " + selectableItem); + String pathFeatureKey = pathFeatureKey(selectableItem); + mapSelectableFeatures.put(pathFeatureKey, selectableItem); - String pathFeatureKey = pathFeatureKey(selectableItem); - mapSelectableFeatures.put(pathFeatureKey, selectableItem); + } + GWT.log("mapSelectableFeatures: " + mapSelectableFeatures); + mapInnestedFeatures.put(level, mapSelectableFeatures); + String placholder = placeholderLayer(layersIDV.get(0)); // Expected one + fillListBoxLevel(level, mapSelectableFeatures, listBoxes, placholder); } - GWT.log("mapSelectableFeatures: " + mapSelectableFeatures); - mapInnestedFeatures.put(level, mapSelectableFeatures); - String placholder = placeholderLayer(layersIDV.get(0)); // Expected one - fillListBoxLevel(level, mapSelectableFeatures, listBoxes, placholder); - } - }); - } catch (RequestException e) { - // Code omitted for clarity - } + @Override + public void onFailure(Throwable caught) { + panelResults.clear(); + HTML error = new HTML( + "Sorry, an issue is occurred on loading data for cross-filtering facility. Error is: " + + caught.getMessage()); + panelResults.add(error); + + } + }); + } } @@ -419,7 +416,6 @@ public class CrossFilteringLayerPanel extends Composite { GWT.log("CQL FILTER built: " + setCqlFilter); IndexLayerDV indexLayer = gCubeCollection.getIndexes().get(0); - applicationBus.fireEvent(new ApplyCQLToLayerMapEvent(indexLayer, setCqlFilter)); try { GCubeSDILayer layer = indexLayer.getLayer(); @@ -437,64 +433,57 @@ public class CrossFilteringLayerPanel extends Composite { } catch (Exception e) { // TODO: handle exception } + + applicationBus.fireEvent(new ApplyCQLToLayerMapEvent(indexLayer, setCqlFilter)); } public void showCountResultsOfWFSCrossFiltering(String wfsQuery) { - RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, wfsQuery); panelResults.clear(); panelResults.add(new HTML("
")); - panelResults.add(new LoaderIcon("Filtering...")); - try { + panelResults.add(new LoaderIcon("Applying spatial filter...")); + + GeoportalDataViewerServiceAsync.Util.getInstance().getHTTPResponseForURL(wfsQuery, new AsyncCallback() { + + @Override + public void onFailure(Throwable caught) { + panelResults.clear(); + panelResults.add(new HTML("
")); + Alert alert = new Alert("Error on returning number of items"); + alert.setType(AlertType.ERROR); + alert.setClose(false); + panelResults.add(alert); + + } + + @Override + public void onSuccess(String response) { + Feature[] features = OLGeoJSONUtil.readGeoJsonFeatures(MAP_PROJECTION.EPSG_4326, response); + + if (features != null) { + int dataCount = features.length; - Request response = builder.sendRequest(null, new RequestCallback() { - public void onError(Request request, Throwable exception) { -// showLoading(false); -// Window.alert(caught.getMessage()); panelResults.clear(); panelResults.add(new HTML("
")); - Alert alert = new Alert("Error on returning number of centroids"); - alert.setType(AlertType.ERROR); - alert.setClose(false); - panelResults.add(alert); - } - public void onResponseReceived(Request request, Response response) { + String message = ""; - Feature[] features = OLGeoJSONUtil.readGeoJsonFeatures(MAP_PROJECTION.EPSG_4326, - response.getText()); + if (dataCount <= 0) { + message = "No item found"; + } else { - if (features != null) { - int dataCount = features.length; - - panelResults.clear(); - panelResults.add(new HTML("
")); - - if (dataCount == 0) { - panelResults.add(new HTML("No result found")); - return; - } - - String message = ""; - - if (dataCount > 0) { - message = "Found " + dataCount; - message += dataCount > 1 ? " centroids" : " centroid"; - message += ". "; - } - - HTML resultMessage = new HTML(message); - resultMessage.getElement().addClassName("search_result_msg"); - - panelResults.add(resultMessage); + message = "Found " + dataCount; + message += dataCount > 1 ? " items" : " item"; + message += ". "; } - + HTML resultMessage = new HTML(); + resultMessage.getElement().addClassName("search_result_msg"); + resultMessage.setHTML(message); + panelResults.add(resultMessage); } - }); - } catch (RequestException e) { - panelResults.clear(); - } + } + }); } /** diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/util/OLGeoJSONUtil.java b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/util/OLGeoJSONUtil.java index 80e2aa2..4d1a038 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/util/OLGeoJSONUtil.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/ui/util/OLGeoJSONUtil.java @@ -15,7 +15,7 @@ import ol.proj.ProjectionOptions; * * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it * - * May 25, 2023 + * May 25, 2023 */ public class OLGeoJSONUtil { @@ -23,27 +23,31 @@ public class OLGeoJSONUtil { * Builds the geo JSON. * * @param projection the projection - * @param geoJSONString the geo JSON string * @return the geo json */ public static GeoJson buildGeoJSON(MAP_PROJECTION projection) { - GeoJsonFeatureOptions fo = new GeoJsonFeatureOptions(); - ProjectionOptions projectionOptions = new ProjectionOptions(); - projectionOptions.setCode(projection.getName()); - Projection fp = new Projection(projectionOptions); - fo.setFeatureProjection(fp); - fo.setDataProjection(fp); - GeoJsonOptions geoJsonOpt = new GeoJsonOptions(); - geoJsonOpt.setDefaultDataProjection(fp); - geoJsonOpt.setFeatureProjection(fp); - return OLFactory.createGeoJSON(geoJsonOpt); + try { + GeoJsonFeatureOptions fo = new GeoJsonFeatureOptions(); + ProjectionOptions projectionOptions = new ProjectionOptions(); + projectionOptions.setCode(projection.getName()); + Projection fp = new Projection(projectionOptions); + fo.setFeatureProjection(fp); + fo.setDataProjection(fp); + GeoJsonOptions geoJsonOpt = new GeoJsonOptions(); + geoJsonOpt.setDefaultDataProjection(fp); + geoJsonOpt.setFeatureProjection(fp); + return OLFactory.createGeoJSON(geoJsonOpt); + } catch (Exception e) { + // silent + return OLFactory.createGeoJSON(); + } } /** * Read geo json features. * - * @param projection the projection + * @param projection the projection * @param geoJSONString the geo JSON string * @return the feature[] */ diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/util/URLUtil.java b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/util/URLUtil.java index c245173..cdc727c 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/util/URLUtil.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/client/util/URLUtil.java @@ -1,7 +1,7 @@ package org.gcube.portlets.user.geoportaldataviewer.client.util; /** - * The Class URLUtil. + * The Class HTTPRequestUtil. * * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it * diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/server/GeoportalDataViewerServiceImpl.java b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/server/GeoportalDataViewerServiceImpl.java index ee64f81..ae212eb 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/server/GeoportalDataViewerServiceImpl.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/server/GeoportalDataViewerServiceImpl.java @@ -3,10 +3,6 @@ package org.gcube.portlets.user.geoportaldataviewer.server; import static org.gcube.application.geoportal.client.plugins.GeoportalAbstractPlugin.projects; import static org.gcube.application.geoportal.client.plugins.GeoportalAbstractPlugin.useCaseDescriptors; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -79,6 +75,7 @@ import org.gcube.portlets.user.geoportaldataviewer.server.gis.GisMakers; import org.gcube.portlets.user.geoportaldataviewer.server.gis.WMSUrlValidator; import org.gcube.portlets.user.geoportaldataviewer.server.mongoservice.GeoportalServiceIdentityProxy; import org.gcube.portlets.user.geoportaldataviewer.server.util.ContextRequest; +import org.gcube.portlets.user.geoportaldataviewer.server.util.HTTPRequestUtil; import org.gcube.portlets.user.geoportaldataviewer.server.util.SessionUtil; import org.gcube.portlets.user.geoportaldataviewer.server.util.TemporalComparatorUtil; import org.gcube.portlets.user.geoportaldataviewer.shared.GCubeCollection; @@ -608,7 +605,7 @@ public class GeoportalDataViewerServiceImpl extends RemoteServiceServlet impleme LOG.debug("listGroupedCustomLayers for type '{}' are: {}", configurationType, listGroupedCustomLayers); mapProfileIDCustomGroupedLayers.put(profileId, listGroupedCustomLayers); } else { - LOG.info("No handler '{}' found into UCD {}, continue...",theHandler, u.getId()); + LOG.info("No handler '{}' found into UCD {}, continue...", theHandler, u.getId()); mapProfileIDCustomGroupedLayers.put(profileId, null); } } @@ -1825,6 +1822,22 @@ public class GeoportalDataViewerServiceImpl extends RemoteServiceServlet impleme return url; } + /** + * Gets the HTTP response for URL. + * + * @param url the url + * @return the HTTP response for URL + */ + @Override + public String getHTTPResponseForURL(String url) { + LOG.info("getHTTPResponseForURL called"); + + if (LOG.isDebugEnabled()) { + LOG.debug("getHTTPResponseForURL for URL {} ", url); + } + return HTTPRequestUtil.getResponse(url); + } + /** * Gets the WFS response. * @@ -1846,39 +1859,7 @@ public class GeoportalDataViewerServiceImpl extends RemoteServiceServlet impleme } String url = getWFSRequest(layerItem, mapSrsName, mapBBOX, maxFeatures, outputFormat); - StringBuffer response = new StringBuffer(); - String theResponseString = ""; - HttpURLConnection con = null; - LOG.debug("Built URL: " + url); - try { - URL obj = new URL(url); - con = (HttpURLConnection) obj.openConnection(); - con.setRequestMethod("GET"); - int responseCode = con.getResponseCode(); - LOG.debug("GET Response Code: " + responseCode); - if (responseCode == HttpURLConnection.HTTP_OK) { // success - BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); - String inputLine; - while ((inputLine = in.readLine()) != null) { - response.append(inputLine); - } - in.close(); - } else { - LOG.info("GET request did not work."); - } - - theResponseString = response.toString(); - // LOG.trace(theResponseString); - - if (LOG.isDebugEnabled()) { - LOG.debug("getWFSResponse is empty? " + theResponseString.isEmpty()); - } - } catch (Exception e) { - LOG.error("Error on performing the request to URL: " + url, e); - } finally { - - } - return theResponseString; + return HTTPRequestUtil.getResponse(url); } } diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/server/util/HTTPRequestUtil.java b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/server/util/HTTPRequestUtil.java new file mode 100644 index 0000000..b601f8f --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/server/util/HTTPRequestUtil.java @@ -0,0 +1,69 @@ +package org.gcube.portlets.user.geoportaldataviewer.server.util; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; + +import org.gcube.portlets.user.geoportaldataviewer.server.GeoportalDataViewerServiceImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The Class HTTPRequestUtil. + * + * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it + * + * Jun 5, 2023 + */ +public class HTTPRequestUtil { + + private static final Logger LOG = LoggerFactory.getLogger(GeoportalDataViewerServiceImpl.class); + + /** + * Gets the response. + * + * @param url the url + * @return the response + */ + public static String getResponse(String url) { + if (url == null || url.isEmpty()) + return null; + + StringBuffer response = new StringBuffer(); + String theResponseString = ""; + HttpURLConnection con = null; + LOG.debug("Calling URL: " + url); + try { + URL obj = new URL(url); + con = (HttpURLConnection) obj.openConnection(); + con.setRequestMethod("GET"); + int responseCode = con.getResponseCode(); + LOG.debug("GET Response Code: " + responseCode); + if (responseCode == HttpURLConnection.HTTP_OK) { // success + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + in.close(); + } else { + LOG.info("GET request did not work."); + } + + theResponseString = response.toString(); + // LOG.trace(theResponseString); + + if (LOG.isDebugEnabled()) { + LOG.debug("getResponse is empty? " + theResponseString.isEmpty()); + } + } catch (Exception e) { + LOG.error("Error on performing the request to URL: " + url, e); + } finally { + + } + LOG.debug("returning response with size: " + theResponseString.length()); + return theResponseString; + } + +} diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/server/util/URLParserUtil.java b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/server/util/URLParserUtil.java index 01c8e62..58589cb 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataviewer/server/util/URLParserUtil.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataviewer/server/util/URLParserUtil.java @@ -9,7 +9,7 @@ import java.util.List; import java.util.Map; /** - * The Class URLUtil. + * The Class URLParserUtil. * * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) *