diff --git a/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml b/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml new file mode 100644 index 0000000..cc81385 --- /dev/null +++ b/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml index 716ef74..8461581 100644 --- a/.settings/org.eclipse.wst.common.project.facet.core.xml +++ b/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -4,4 +4,5 @@ + diff --git a/GetResponseRecords.xml b/GetResponseRecords.xml deleted file mode 100644 index 5b61cda..0000000 --- a/GetResponseRecords.xml +++ /dev/null @@ -1,1942 +0,0 @@ - - - - - - - 2b63fa58-0f9d-462f-b73e-b3c7bbb6e189 - - - English - - - UTF-8 - - - Dataset - - - 2017-06-16T11:54:12.608+02:00 - - - - - - - Points Map - - - - - 93d70bd4-f9a7-497f-a1c9-f985c43672a6 - - - - - - - This metadata has been automatically generated from the Statistical Manager on the basis of a distribution of points and according the resolution of 0.0 degrees. - - - - - http://www.d4science.org/D4ScienceOrg-Social-theme/images/custom/D4ScienceInfrastructure.png - - - - - - - 0.0 - - - - - English - - - biota - - - - - - - -180.0 - - - -90.0 - - - 180.0 - - - 90.0 - - - - - - - - - - - - - WMS - - - 1.3.0 - - - - - - - WFS - - - 1.0.0 - - - - - - - WCS - - - 1.0.0 - - - - - - - HTTP - - - 1.0.0 - - - - - - - - - http://geoserver.d4science.org/geoserver/wms?service=wms&version=1.1.0&request=GetMap&layers=stat7c9915d7ea924b568fe759ecfc2a3d42&styles=point&bbox=-180.0,-90.0,180.0,90.0&width=676&height=330&srs=EPSG:4326&crs=point&format=application/openlayers - - - - - - - http://geoserver.d4science.org/geoserver/ows?service=wfs&version=1.0.0&request=GetFeature&typeName=stat7c9915d7ea924b568fe759ecfc2a3d42&format=json - - - - - - - http://geoserver.d4science.org/geoserver/wcs?service=wcs&version=1.0.0&request=GetCoverage&coverage=stat7c9915d7ea924b568fe759ecfc2a3d42&CRS=EPSG:4326&bbox=-180.0,-90.0,180.0,90.0&width=676&height=330&format=geotiff - - - - - - - https://goo.gl/wVqX4e - - - - - - - - - - - 39d7207e-3bec-4086-98c4-8d9c787db9c4 - - - English - - - UTF-8 - - - Dataset - - - 2017-06-16T11:23:27.113+02:00 - - - - - - - test_config - - - - - 3db38550-e1b2-4080-8c48-82a97a66baee - - - - - - - CSV - - - - - 0.5 - - - - - English - - - biota - - - - - - - -180.0 - - - -90.0 - - - 180.0 - - - 90.0 - - - - - - - - - - - - - WMS - - - 1.3.0 - - - - - - - WFS - - - 1.0.0 - - - - - - - WCS - - - 1.0.0 - - - - - - - HTTP - - - 1.0.0 - - - - - - - - - http://geoserver.d4science.org/geoserver/wms?service=wms&version=1.1.0&request=GetMap&layers=tdmc67c6f906f6d45e89b751d494763c197&styles=speciesid1d6ef820c1524a278e374654905639d8&bbox=-180.0,-90.0,180.0,90.0&width=676&height=330&srs=EPSG:4326&crs=EPSG:4326&format=application/openlayers - - - - - - - http://geoserver.d4science.org/geoserver/ows?service=wfs&version=1.0.0&request=GetFeature&typeName=tdmc67c6f906f6d45e89b751d494763c197&format=json - - - - - - - http://geoserver.d4science.org/geoserver/wcs?service=wcs&version=1.0.0&request=GetCoverage&coverage=tdmc67c6f906f6d45e89b751d494763c197&CRS=EPSG:4326&bbox=-180.0,-90.0,180.0,90.0&width=676&height=330&format=geotiff - - - - - - - - - - - df936ffc-12f6-4b04-adbc-faf30c18ce8b - - - English - - - UTF-8 - - - Dataset - - - 2017-07-11T14:59:58.053+02:00 - - - - - - - sparus aurata occurrences layer - - - - - 32c1ae74-ee2d-469b-b5b8-a6b50d00d588 - - - - - - - sparus aurata occurrences layer - - - - - 0.5 - - - - - English - - - biota - - - - - - - -180.0 - - - -90.0 - - - 180.0 - - - 90.0 - - - - - - - - - - - - - WMS - - - 1.3.0 - - - - - - - WFS - - - 1.0.0 - - - - - - - WCS - - - 1.0.0 - - - - - - - HTTP - - - 1.0.0 - - - - - - - - - http://geoserver.d4science.org/geoserver/wms?service=wms&version=1.1.0&request=GetMap&layers=spda8153828923d4e118668864b25f8375f&styles=point&bbox=-180.0,-90.0,180.0,90.0&width=676&height=330&srs=EPSG:4326&crs=EPSG:4326&format=application/openlayers - - - - - - - http://geoserver.d4science.org/geoserver/ows?service=wfs&version=1.0.0&request=GetFeature&typeName=spda8153828923d4e118668864b25f8375f&format=json - - - - - - - http://geoserver.d4science.org/geoserver/wcs?service=wcs&version=1.0.0&request=GetCoverage&coverage=spda8153828923d4e118668864b25f8375f&CRS=EPSG:4326&bbox=-180.0,-90.0,180.0,90.0&width=676&height=330&format=geotiff - - - - - - - https://goo.gl/KGJtvr - - - - - - - - - - - aae0655d-488c-41d3-a534-e6a567bc0a09 - - - English - - - UTF-8 - - - Dataset - - - 2017-04-28T15:39:09.645+02:00 - - - - - - - AccountingDataminer1_201704 - - - - - 6ecdce71-fdec-44b7-b01b-74b984821c26 - - - - - - - CSV - - - - - 0.5 - - - - - English - - - biota - - - - - - - -180.0 - - - -90.0 - - - 180.0 - - - 90.0 - - - - - - - - - - - - - WMS - - - 1.3.0 - - - - - - - WFS - - - 1.0.0 - - - - - - - WCS - - - 1.0.0 - - - - - - - HTTP - - - 1.0.0 - - - - - - - - - http://geoserver3.d4science.org/geoserver/wms?service=wms&version=1.1.0&request=GetMap&layers=tdmfb9cec5da0cc4391b0efb6c66700f6bc&styles=Organizationb430fd850dcd495792775ae1ef9fe52d&bbox=-180.0,-90.0,180.0,90.0&width=676&height=330&srs=EPSG:4326&crs=EPSG:4326&format=application/openlayers - - - - - - - http://geoserver3.d4science.org/geoserver/ows?service=wfs&version=1.0.0&request=GetFeature&typeName=tdmfb9cec5da0cc4391b0efb6c66700f6bc&format=json - - - - - - - http://geoserver3.d4science.org/geoserver/wcs?service=wcs&version=1.0.0&request=GetCoverage&coverage=tdmfb9cec5da0cc4391b0efb6c66700f6bc&CRS=EPSG:4326&bbox=-180.0,-90.0,180.0,90.0&width=676&height=330&format=geotiff - - - - - - - https://goo.gl/8iIH3F - - - - - - - - - - - 6c55a5f8-a0fa-4ba5-a479-c5db13d2cc42 - - - English - - - UTF-8 - - - Dataset - - - 2017-04-28T15:45:20.153+02:00 - - - - - - - AccountingDataminer2_201704 - - - - - 82165868-6851-4106-b556-f1e236d87b00 - - - - - - - CSV - - - - - 0.5 - - - - - English - - - biota - - - - - - - -180.0 - - - -90.0 - - - 180.0 - - - 90.0 - - - - - - - - - - - - - WMS - - - 1.3.0 - - - - - - - WFS - - - 1.0.0 - - - - - - - WCS - - - 1.0.0 - - - - - - - HTTP - - - 1.0.0 - - - - - - - - - http://geoserver4.d4science.org/geoserver/wms?service=wms&version=1.1.0&request=GetMap&layers=tdme2d91f5dc5f84c278906006f28d2cb51&styles=Organization8d6513f67b5f4bf8aca639ccf6813d45&bbox=-180.0,-90.0,180.0,90.0&width=676&height=330&srs=EPSG:4326&crs=EPSG:4326&format=application/openlayers - - - - - - - http://geoserver4.d4science.org/geoserver/ows?service=wfs&version=1.0.0&request=GetFeature&typeName=tdme2d91f5dc5f84c278906006f28d2cb51&format=json - - - - - - - http://geoserver4.d4science.org/geoserver/wcs?service=wcs&version=1.0.0&request=GetCoverage&coverage=tdme2d91f5dc5f84c278906006f28d2cb51&CRS=EPSG:4326&bbox=-180.0,-90.0,180.0,90.0&width=676&height=330&format=geotiff - - - - - - - https://goo.gl/NkAw9V - - - - - - - - - - - geo_fea_slope - - - English - - - UTF-8 - - - Dataset - - - dataset - - - 2014-02-05 - - - INSPIRE Metadata Implementing Rules: Technical Guidelines based on EN ISO 19115 and EN ISO 19119 - - - V. 1.2 - - - - - - - http://www.opengis.net/def/crs/EPSG/0/4326 - - - - - - - - - - - 0 - - - - - - - - - - - Slope geomorphic feature layer - - - - - c9c1d53a-f9d6-48f5-bf5a-4d27831a7728 - - - - - - - Miles Macmillan-Lawler - - - GRID-Arendal - - - - - - - Miles.Macmillan-Lawler@grida.no - - - - - - - Custodian - - - - - - - The slope geomorphic feature layer represents the spatial extent of the slope areas of the worlds oceans based on interpretation of the SRTM30 plus v7 global bathymetry model. The layer is one of the 25 layers that make up the global seafloor geomorphic features map (Harris et.al. 2014). The slope is “the deepening sea floor out from the shelf edge to the upper limit of the continental rise, or the point where there is a general decrease in steepness” (IHO, 2008). In this study, the foot of slope was digitised manually at a nominal spatial scale of 1:500,000 in ArcGIS based on 100 m contours and 3D viewing. ArcGIS was used to highlight zones of abrupt changes in seabed gradient (contour spacing) which suggests the foot of slope in many areas. In areas where marginal plateaus abut the margin, the foot of slope was allowed to extend offshore to encompass the plateau feature, where a clear seaward dipping gradient was apparent. Otherwise the first significant decrease in gradient encountered in a seaward direction from the shelf break was selected as the foot of slope. Note our foot of slope locations are based only on bathymetric data and our interpretation is not intended to define the foot of slope under Article 76 of the 1982 United Nations Convention on the Law of the Sea, particularly in areas of geomorphologically complex, continent-ocean transition. - - - - - Miles Macmillan-Lawler - - - GRID-Arendal - - - - - - - Miles.Macmillan-Lawler@grida.no - - - - - - - Custodian - - - - - - - The global seafloor geomorphic feature map is available for download from bluehabitats.org - - - - - - - Other restrictions - - - - - Vector - - - English - - - UTF-8 - - - oceans - - - - - - - -180.0 - - - -76.516483 - - - 180.0 - - - 84.540813 - - - - - - - - - - - - - WMS - - - 1.1.0 - - - - - - - WFS - - - 1.1.0 - - - - - - - WCS - - - 1.0.0 - - - - - - - - - http://geoserver.d4science.org/geoserver/wms?service=wms&version=1.1.0&request=GetMap&layers=W_mpa:geo_fea_slope&styles=&bbox=-180,-90,180,90&width=676&height=330&srs=EPSG:4326&crs=EPSG:4326&format=application/openlayers - - - - - - - http://geoserver.d4science.org/geoserver/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=W_mpa:geo_fea_slope&format=json - - - - - - - http://geoserver.d4science.org/geoserver/wms?service=wms&version=1.1.0&request=GetMap&layers=W_mpa:geo_fea_slope&styles=&bbox=-180,-90,180,90&width=676&height=330&srs=EPSG:4326&crs=EPSG:4326&format=application/openlayers - - - - - - - http://data.d4science.org/gis?scope=%252Fd4science.research-infrastructures.eu%252FgCubeApps&gis-UUID=c9c1d53a-f9d6-48f5-bf5a-4d27831a7728 - - - - - - - - - - - - - This data was generated based on interpretation of the SRTM30 plus v7 global bathymetry model. The layer is one of the 25 layers that make up the global seafloor geomorphic features map (Harris et.al. 2014). - - - - - - - - - geo_fea_shelf - - - English - - - UTF-8 - - - Dataset - - - dataset - - - 2014-02-05 - - - INSPIRE Metadata Implementing Rules: Technical Guidelines based on EN ISO 19115 and EN ISO 19119 - - - V. 1.2 - - - - - - - http://www.opengis.net/def/crs/EPSG/0/4326 - - - - - - - - - - - 0 - - - - - - - - - - - Shelf geomorphic feature layer - - - - - d7733bec-0ecd-4ff7-a4f1-f185032eb527 - - - - - - - Miles Macmillan-Lawler - - - GRID-Arendal - - - - - - - Miles.Macmillan-Lawler@grida.no - - - - - - - Custodian - - - - - - - The shelf geomorphic feature layer represents the spatial extent of the shelf areas of the worlds oceans based on interpretation of the SRTM30 plus v7 global bathymetry model. The layer is one of the 25 layers that make up the global seafloor geomorphic features map (Harris et.al. 2014). The continental shelf is defined by IHO (2008)as “a zone adjacent to a continent (or around an island) and extending from the low water line to a depth at which there is usually a marked increase of slope towards oceanic depths”. The low-water mark is taken in this study as the 0 m depth contour. The shelf break (i.e. the line along which there is marked increase of slope at the seaward margin of a shelf) was digitised manually at a nominal spatial scale of 1:500,000 in ArcGIS based on 10 m, 50 m and 100 m contours, depending on the slope and bathymetric profile of the region. In most cases 100 m contours were sufficient at the selected scale of 1:500,000 to identify the shelf break. However, where there was a gradual break in slope over a broad area, more closely spaced contours were used. Floating ice shelves cover large sections of the Antarctic continental shelf and these areas were simply left blank. - - - - - Miles Macmillan-Lawler - - - GRID-Arendal - - - - - - - Miles.Macmillan-Lawler@grida.no - - - - - - - Custodian - - - - - - - The global seafloor geomorphic feature map is available for download from bluehabitats.org - - - - - - - Other restrictions - - - - - Vector - - - English - - - UTF-8 - - - oceans - - - - - - - -180.0 - - - -78.686972 - - - 180.0 - - - 84.207354 - - - - - - - - - - - - - WMS - - - 1.1.0 - - - - - - - WFS - - - 1.1.0 - - - - - - - WCS - - - 1.0.0 - - - - - - - - - http://geoserver.d4science.org/geoserver/wms?service=wms&version=1.1.0&request=GetMap&layers=W_mpa:geo_fea_shelf&styles=&bbox=-180,-90,180,90&width=676&height=330&srs=EPSG:4326&crs=EPSG:4326&format=application/openlayers - - - - - - - http://geoserver.d4science.org/geoserver/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=W_mpa:geo_fea_shelf&format=json - - - - - - - http://geoserver.d4science.org/geoserver/wms?service=wms&version=1.1.0&request=GetMap&layers=W_mpa:geo_fea_shelf&styles=&bbox=-180,-90,180,90&width=676&height=330&srs=EPSG:4326&crs=EPSG:4326&format=application/openlayers - - - - - - - http://data.d4science.org/gis?scope=%252Fd4science.research-infrastructures.eu%252FgCubeApps&gis-UUID=d7733bec-0ecd-4ff7-a4f1-f185032eb527 - - - - - - - - - - - - - This data was generated based on interpretation of the SRTM30 plus v7 global bathymetry model. The layer is one of the 25 layers that make up the global seafloor geomorphic features map (Harris et.al. 2014). - - - - - - - - - geo_fea_troughs - - - English - - - UTF-8 - - - Dataset - - - dataset - - - 2014-02-05 - - - INSPIRE Metadata Implementing Rules: Technical Guidelines based on EN ISO 19115 and EN ISO 19119 - - - V. 1.2 - - - - - - - http://www.opengis.net/def/crs/EPSG/0/4326 - - - - - - - - - - - 0 - - - - - - - - - - - Trough geomorphic feature layer - - - - - 1e0c14c6-4719-42e8-a57f-d6c04cd02518 - - - - - - - Miles Macmillan-Lawler - - - GRID-Arendal - - - - - - - Miles.Macmillan-Lawler@grida.no - - - - - - - Custodian - - - - - - - The trough geomorphic feature layer represents the spatial extent of the troughs of the worlds oceans based on interpretation of the SRTM30 plus v7 global bathymetry model. The layer is one of the 25 layers that make up the global seafloor geomorphic features map (Harris et.al. 2014). The IHO (IHO, 2008) definition of a trough is “a long depression of the sea floor characteristically flat bottomed and steep sided and normally shallower than a trench”. In this study we found that troughs are also commonly open at one end (i.e. not defined by closed bathymetric contours) and their broad, flat floors may exhibit a continuous gradient along a thalweg. Troughs may originate from glacial erosion processes or have formed through tectonic processes. In this study, glacial troughs incised into the shelf are a separate category; here we include all troughs not of a glacial origin, typically superimposed on the slope and/or abyssal base layers. Trenches that have been infilled with sediment may evolve into troughs, as appears to have occurred in troughs adjacent to North and South America, for example. Slumping on the sides of some troughs has formed a bridge across the trough, thereby dividing it into two separate sections (see “bridges” below). In this study all troughs were digitised by hand based on the interpretation of 100 m bathymetric contours. - - - - - Miles Macmillan-Lawler - - - GRID-Arendal - - - - - - - Miles.Macmillan-Lawler@grida.no - - - - - - - Custodian - - - - - - - The global seafloor geomorphic feature map is available for download from bluehabitats.org - - - - - - - Other restrictions - - - - - Vector - - - English - - - UTF-8 - - - oceans - - - - - - - -180.0 - - - -71.905139 - - - 180.0 - - - 89.049382 - - - - - - - - - - - - - WMS - - - 1.1.0 - - - - - - - WFS - - - 1.1.0 - - - - - - - WCS - - - 1.0.0 - - - - - - - - - http://geoserver.d4science.org/geoserver/wms?service=wms&version=1.1.0&request=GetMap&layers=W_mpa:geo_fea_troughs&styles=&bbox=-180,-90,180,90&width=676&height=330&srs=EPSG:4326&crs=EPSG:4326&format=application/openlayers - - - - - - - http://geoserver.d4science.org/geoserver/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=W_mpa:geo_fea_troughs&format=json - - - - - - - http://geoserver.d4science.org/geoserver/wms?service=wms&version=1.1.0&request=GetMap&layers=W_mpa:geo_fea_troughs&styles=&bbox=-180,-90,180,90&width=676&height=330&srs=EPSG:4326&crs=EPSG:4326&format=application/openlayers - - - - - - - http://data.d4science.org/gis?scope=%25252Fd4science.research-infrastructures.eu%25252FgCubeApps&gis-UUID=1e0c14c6-4719-42e8-a57f-d6c04cd02518 - - - - - - - - - - - - - This data was generated based on interpretation of the SRTM30 plus v7 global bathymetry model. The layer is one of the 25 layers that make up the global seafloor geomorphic features map (Harris et.al. 2014). - - - - - - - - - geo_fea_terraces - - - English - - - UTF-8 - - - Dataset - - - dataset - - - 2014-02-05 - - - INSPIRE Metadata Implementing Rules: Technical Guidelines based on EN ISO 19115 and EN ISO 19119 - - - V. 1.2 - - - - - - - http://www.opengis.net/def/crs/EPSG/0/4326 - - - - - - - - - - - 0 - - - - - - - - - - - Terrace geomorphic feature layer - - - - - 5ea07cca-1696-40b4-bf40-3482b5e628ef - - - - - - - Miles Macmillan-Lawler - - - GRID-Arendal - - - - - - - Miles.Macmillan-Lawler@grida.no - - - - - - - Custodian - - - - - - - The terrace geomorphic feature layer represents the spatial extent of the terraces of the worlds oceans based on interpretation of the SRTM30 plus v7 global bathymetry model. The layer is one of the 25 layers that make up the global seafloor geomorphic features map (Harris et.al. 2014). Terraces are “An isolated (or group of) relatively flat horizontal or gently inclined surface(s), sometimes long and narrow, which is (are) bounded by a steeper ascending slope on one side and by a steeper descending slope on the opposite side” (IHO, 2008). In this study terraces (broad steps) were calculated based on the gradient of the SRTM30_PLUS model. The SRTM30_PLUS model was masked using the slope feature layer (i.e. terraces we only mapped on the continental slope). - - - - - Miles Macmillan-Lawler - - - GRID-Arendal - - - - - - - Miles.Macmillan-Lawler@grida.no - - - - - - - Custodian - - - - - - - The global seafloor geomorphic feature map is available for download from bluehabitats.org - - - - - - - Other restrictions - - - - - Vector - - - English - - - UTF-8 - - - oceans - - - - - - - -179.999938 - - - -74.686809 - - - 179.999965 - - - 88.860097 - - - - - - - - - - - - - WMS - - - 1.1.0 - - - - - - - WFS - - - 1.1.0 - - - - - - - WCS - - - 1.0.0 - - - - - - - - - http://geoserver.d4science.org/geoserver/wms?service=wms&version=1.1.0&request=GetMap&layers=W_mpa:geo_fea_terraces&styles=&bbox=-180,-90,180,90&width=676&height=330&srs=EPSG:4326&crs=EPSG:4326&format=application/openlayers - - - - - - - http://geoserver.d4science.org/geoserver/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=W_mpa:geo_fea_terraces&format=json - - - - - - - http://geoserver.d4science.org/geoserver/wms?service=wms&version=1.1.0&request=GetMap&layers=W_mpa:geo_fea_terraces&styles=&bbox=-180,-90,180,90&width=676&height=330&srs=EPSG:4326&crs=EPSG:4326&format=application/openlayers - - - - - - - http://data.d4science.org/gis?scope=%25252Fd4science.research-infrastructures.eu%25252FgCubeApps&gis-UUID=5ea07cca-1696-40b4-bf40-3482b5e628ef - - - - - - - - - - - - - This data was generated based on interpretation of the SRTM30 plus v7 global bathymetry model. The layer is one of the 25 layers that make up the global seafloor geomorphic features map (Harris et.al. 2014). - - - - - - - - - geo_fea_trenches - - - English - - - UTF-8 - - - Dataset - - - dataset - - - 2014-02-05 - - - INSPIRE Metadata Implementing Rules: Technical Guidelines based on EN ISO 19115 and EN ISO 19119 - - - V. 1.2 - - - - - - - http://www.opengis.net/def/crs/EPSG/0/4326 - - - - - - - - - - - 0 - - - - - - - - - - - Trench geomorphic feature layer - - - - - 2e5f7df1-aa2d-4901-8ad2-471b00c8b674 - - - - - - - Miles Macmillan-Lawler - - - GRID-Arendal - - - - - - - Miles.Macmillan-Lawler@grida.no - - - - - - - Custodian - - - - - - - The trench geomorphic feature layer represents the spatial extent of the trenches of the worlds oceans based on interpretation of the SRTM30 plus v7 global bathymetry model. The layer is one of the 25 layers that make up the global seafloor geomorphic features map (Harris et.al. 2014). Trenches are “a long narrow, characteristically very deep and asymmetrical depression of the sea floor, with relatively steep sides” (IHO, 2008). Trenches are generally distinguished from troughs by their “V” shape in cross section (in contrast with flat-bottomed troughs). In this study trenches were mapped by selecting closed bathymetric contours that defined basins contained within the trench feature, and then joining the basin segments together by hand digitizing along more elevated sections. In this way, bridge features were also identified (as coinciding with infilled sections of trenches; see section on “bridges”). - - - - - Miles Macmillan-Lawler - - - GRID-Arendal - - - - - - - Miles.Macmillan-Lawler@grida.no - - - - - - - Custodian - - - - - - - The global seafloor geomorphic feature map is available for download from bluehabitats.org - - - - - - - Other restrictions - - - - - Vector - - - English - - - UTF-8 - - - oceans - - - - - - - -180.0 - - - -61.062679 - - - 180.0 - - - 55.526452 - - - - - - - - - - - - - WMS - - - 1.1.0 - - - - - - - WFS - - - 1.1.0 - - - - - - - WCS - - - 1.0.0 - - - - - - - - - http://geoserver.d4science.org/geoserver/wms?service=wms&version=1.1.0&request=GetMap&layers=W_mpa:geo_fea_trenches&styles=&bbox=-180,-90,180,90&width=676&height=330&srs=EPSG:4326&crs=EPSG:4326&format=application/openlayers - - - - - - - http://geoserver.d4science.org/geoserver/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=W_mpa:geo_fea_trenches&format=json - - - - - - - http://geoserver.d4science.org/geoserver/wms?service=wms&version=1.1.0&request=GetMap&layers=W_mpa:geo_fea_trenches&styles=&bbox=-180,-90,180,90&width=676&height=330&srs=EPSG:4326&crs=EPSG:4326&format=application/openlayers - - - - - - - http://data.d4science.org/gis?scope=%25252Fd4science.research-infrastructures.eu%25252FgCubeApps&gis-UUID=2e5f7df1-aa2d-4901-8ad2-471b00c8b674 - - - - - - - - - - - - - This data was generated based on interpretation of the SRTM30 plus v7 global bathymetry model. The layer is one of the 25 layers that make up the global seafloor geomorphic features map (Harris et.al. 2014). - - - - - - - - - diff --git a/distro/changelog.xml b/distro/changelog.xml index d16f593..8868dc6 100644 --- a/distro/changelog.xml +++ b/distro/changelog.xml @@ -94,7 +94,17 @@ - [Task #9538] Geonetwork-Uri Resolver enhancement: provide new filters and improve current ones + [Task #9538] Geonetwork-Uri Resolver enhancement: provide new + filters and improve current ones + + + + [Task #10381] Geonetwork Resolver enhancement: porting to + Geonetwork connector + + [Task #10070] Catalogue Resolver enhancement: resolve + public/private items to public/private catalogue \ No newline at end of file diff --git a/pom.xml b/pom.xml index f8f9141..ccaec7d 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ org.gcube.data.transfer uri-resolver - 1.14.0-SNAPSHOT + 1.15.0-SNAPSHOT war The URI Resolver is an HTTP URI resolver implemented as an HTTP servlet which gives access trough HTTP to different protocols URIs. @@ -22,7 +22,7 @@ distro 1.7 1.8 - + @@ -98,6 +98,12 @@ 2.6 + + org.gcube.common + authorization-client + [2.0.0-SNAPSHOT, 3.0.0-SNAPSHOT) + + org.w3c @@ -106,6 +112,13 @@ compile + + org.gcube.data-catalogue + ckan-util-library + [2.0.0-SNAPSHOT, 3.0.0-SNAPSHOT) + compile + + diff --git a/src/main/java/org/gcube/datatransfer/resolver/GeonetworkRequestCriteria.java b/src/main/java/org/gcube/datatransfer/resolver/GeonetworkRequestCriteria.java index cfe7938..de8f586 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/GeonetworkRequestCriteria.java +++ b/src/main/java/org/gcube/datatransfer/resolver/GeonetworkRequestCriteria.java @@ -3,6 +3,8 @@ */ package org.gcube.datatransfer.resolver; +import java.util.Map; + import org.gcube.datatransfer.resolver.GeonetworkRequestFilterParameters.MODE; import org.gcube.datatransfer.resolver.GeonetworkRequestFilterParameters.VISIBILITY; @@ -13,12 +15,17 @@ import org.gcube.datatransfer.resolver.GeonetworkRequestFilterParameters.VISIBIL * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it * Jun 15, 2016 */ -public class GeonetworkRequestCriteria { +public class GeonetworkRequestCriteria{ private String scope; + private String gCubeToken; private MODE mode; - private String owner; //This is optional + private Map filters; //This is optional private VISIBILITY visibility; + + public GeonetworkRequestCriteria(){ + + } /** * @param scope * @param mode @@ -26,15 +33,37 @@ public class GeonetworkRequestCriteria { * @param visibility */ public GeonetworkRequestCriteria( - String scope, MODE mode, String owner, VISIBILITY visibility) { + String scope, String gCubeToken, MODE mode, Map filters, VISIBILITY visibility) { super(); this.scope = scope; + this.gCubeToken = gCubeToken; this.mode = mode; - this.owner = owner; + this.filters = filters; this.visibility = visibility; } + /** + * Gets the gcube token. + * + * @return the gCubeToken + */ + public String getGcubeToken() { + + return gCubeToken; + } + + + /** + * @param gCubeToken the gCubeToken to set + */ + public void setgCubeToken(String gCubeToken) { + + this.gCubeToken = gCubeToken; + } + + + /** * @return the scope */ @@ -52,11 +81,11 @@ public class GeonetworkRequestCriteria { } /** - * @return the owner + * @return the filters */ - public String getOwner() { + public Map getFilters() { - return owner; + return filters; } /** @@ -83,12 +112,13 @@ public class GeonetworkRequestCriteria { this.mode = mode; } - /** - * @param owner the owner to set - */ - public void setOwner(String owner) { - this.owner = owner; + /** + * @param filters the filters to set + */ + public void setFilters(Map filters) { + + this.filters = filters; } /** @@ -98,7 +128,6 @@ public class GeonetworkRequestCriteria { this.visibility = visibility; } - /* (non-Javadoc) * @see java.lang.Object#toString() */ @@ -108,10 +137,12 @@ public class GeonetworkRequestCriteria { StringBuilder builder = new StringBuilder(); builder.append("GeonetworkRequestCriteria [scope="); builder.append(scope); + builder.append(", gCubeToken="); + builder.append(gCubeToken); builder.append(", mode="); builder.append(mode); - builder.append(", owner="); - builder.append(owner); + builder.append(", filters="); + builder.append(filters); builder.append(", visibility="); builder.append(visibility); builder.append("]"); @@ -120,4 +151,5 @@ public class GeonetworkRequestCriteria { + } diff --git a/src/main/java/org/gcube/datatransfer/resolver/GeonetworkRequestDecoder.java b/src/main/java/org/gcube/datatransfer/resolver/GeonetworkRequestDecoder.java index 367351e..255b09b 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/GeonetworkRequestDecoder.java +++ b/src/main/java/org/gcube/datatransfer/resolver/GeonetworkRequestDecoder.java @@ -3,6 +3,11 @@ */ package org.gcube.datatransfer.resolver; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + import javax.servlet.ServletException; import org.gcube.datatransfer.resolver.GeonetworkRequestFilterParameters.MODE; @@ -62,13 +67,22 @@ public class GeonetworkRequestDecoder { logger.debug("scope value is: "+geonetworkRequestCriteria.getScope()); //newURI = UriResolverRewriteFilter.SERVLET_GEONETWORK + "?" + GeonetworkResolver.SCOPE + "=" + geonetworkRequestCriteria.getScope() +"&"+ GeonetworkResolver.PARAMETER_FILTER_PUBLIC_IDS +"="+geonetworkRequestCriteria.isValueOfFilterPublicIds() +"&"+GeonetworkResolver.PARAMETER_NO_AUTHENTICATION+"="+geonetworkRequestCriteria.isNoAuthOnGeonetwork(); + //+ GeonetworkResolver.GCUBETOKEN + "=" + geonetworkRequestCriteria.getGcubeToken()!=null?geonetworkRequestCriteria.getGcubeToken():"" +"&" + gnResolverUriRequest = UriResolverRewriteFilter.SERVLET_GEONETWORK + "?" + GeonetworkResolver.SCOPE + "=" + geonetworkRequestCriteria.getScope() +"&" + + GeonetworkResolver.GCUBETOKEN + "=" + geonetworkRequestCriteria.getGcubeToken() +"&" + GeonetworkRequestFilterParameters.MODE.class.getSimpleName() +"="+geonetworkRequestCriteria.getMode() +"&" + GeonetworkRequestFilterParameters.VISIBILITY.class.getSimpleName()+"="+geonetworkRequestCriteria.getVisibility(); - if(geonetworkRequestCriteria.getOwner()!=null){ - gnResolverUriRequest+="&"+GeonetworkRequestFilterParameters.OWNER_PARAM +"="+geonetworkRequestCriteria.getOwner(); + if(geonetworkRequestCriteria.getFilters()!=null){ + Set keyset = geonetworkRequestCriteria.getFilters().keySet(); + + for (String key : keyset) { + gnResolverUriRequest+="&"+GeonetworkRequestFilterParameters.FILTER_KEY +"="+key; + gnResolverUriRequest+="&"+GeonetworkRequestFilterParameters.FILTER_VALUE +"="+geonetworkRequestCriteria.getFilters().get(key); + } + } //BUILDING REMAINING PATH WITHOUT GeonetworkRequestFilterParameters.REQUEST_DELIMITIER @@ -81,33 +95,6 @@ public class GeonetworkRequestDecoder { gnResolverUriRequest+="&"+queryString; logger.info("built Geonetwork Resolver GET Request: "+gnResolverUriRequest); - /* - String[] params = pathWithoutGN.split("/"); - if(params[0]==null || params[0].isEmpty()){ - logger.error("Scope is null or empty, you must set a valid scope /geonetwork/root|vo|vre"); - throw new ServletException("Scope is null or empty, you must set a valid scope /geonetwork/root"+SCOPE_SEPARATOR+"vo"+SCOPE_SEPARATOR+"vre"); - } - - geonetworkRequestCriteria = getGeonetworkRequestCriteria(params[0]); - logger.debug("scope value is: "+geonetworkRequestCriteria.getScope()); - newURI = UriResolverRewriteFilter.SERVLET_GEONETWORK + "?" + GeonetworkResolver.SCOPE + "=" + geonetworkRequestCriteria.getScope() +"&"+ GeonetworkResolver.PARAMETER_FILTER_PUBLIC_IDS +"="+geonetworkRequestCriteria.isValueOfFilterPublicIds() +"&"+GeonetworkResolver.PARAMETER_NO_AUTHENTICATION+"="+geonetworkRequestCriteria.isNoAuthOnGeonetwork(); - logger.debug(GeonetworkResolver.PARAMETER_FILTER_PUBLIC_IDS +" is: "+geonetworkRequestCriteria.isValueOfFilterPublicIds()); - logger.debug(GeonetworkResolver.PARAMETER_NO_AUTHENTICATION +" is: "+geonetworkRequestCriteria.isNoAuthOnGeonetwork()); - */ -// if(params.length>1){ -// String remainPath = ""; -//// newURI +="&remainPath="; -// for (int i = 1; i < params.length; i++) { -// String httpGetParam = params[i]; -// if(httpGetParam!=null && !httpGetParam.isEmpty()) -// remainPath+="/"+httpGetParam; -// } -// newURI +="&"+GeonetworkResolver.REMAIN_PATH+"="+remainPath; -// } -// -// if(queryString!=null && !queryString.isEmpty()) -// newURI+="&"+queryString; - } @@ -116,9 +103,9 @@ public class GeonetworkRequestDecoder { * Creates a request criteria from input parameter pathWithoutGN * The parameter pathWithoutGN should be an ordered string (like REST request): - * MODE/SCOPE/VISIBILITY/OWNER + * MODE/SCOPE|GCUBETOKEN/VISIBILITY/OWNER * MODE must be: {@link MODE} - * SCOPE must be: ROOT|VO|VRE + * SCOPE must be: ROOT|VO|VRE or a GCUBETOKEN * VISIBILITY must be: {@link VISIBILITY} * OWNER (is optional): filter by owner * @param pathWithoutGN the path without Geonetwork base URL @@ -130,21 +117,30 @@ public class GeonetworkRequestDecoder { String[] params = pathWithoutGN.split("/"); MODE mode = null; - String theScope = null; + String contextScopeOrToken = null; VISIBILITY visibility = null; - String owner = null; + Map filters = null; + + GeonetworkRequestCriteria requestCriteria = new GeonetworkRequestCriteria(); if(params.length < 3){ throw new BadRequestException("Bad request. Read the request "+pathWithoutGN+". You must pass a valid request like [GEONETWORK_BASE_URL]/SCOPE/MODE/VISIBILITY/OWNER"); } - //SCOPE + //SCOPE or gcube-token if(params[0]!=null && !params[0].isEmpty()){ - theScope = params[0]; - logger.debug("Read parameter scope: "+theScope); - theScope = theScope.replaceAll("\\"+SCOPE_SEPARATOR, "/"); - if (!theScope.startsWith("/")) - theScope="/"+theScope; + contextScopeOrToken = params[0]; + logger.debug("Read first parameter: "+contextScopeOrToken); + boolean isToken = isValidUUID(contextScopeOrToken); + + if(!isToken){ + contextScopeOrToken = contextScopeOrToken.replaceAll("\\"+SCOPE_SEPARATOR, "/"); + if (!contextScopeOrToken.startsWith("/")) + contextScopeOrToken="/"+contextScopeOrToken; + requestCriteria.setScope(contextScopeOrToken); + }else{ + requestCriteria.setgCubeToken(contextScopeOrToken); + } }else{ logger.error("The first parameter 'scope' is null or empty, you must set a valid scope as ROOT"+SCOPE_SEPARATOR+"VO"+SCOPE_SEPARATOR+"VRE as first parameter"); throw new ServletException("Scope is null or empty. You must pass a valid scope as ROOT"+SCOPE_SEPARATOR+"VO"+SCOPE_SEPARATOR+"VRE as first parameter"); @@ -193,11 +189,21 @@ public class GeonetworkRequestDecoder { //OWNER if(params.length > 3 && params[3]!=null && params[3]!=GeonetworkRequestFilterParameters.REQUEST_DELIMITIER){ - owner = params[3]; - logger.debug("Read parameter owner: "+owner); + filters = new HashMap(1); + filters.put(params[3], ""); + logger.debug("Read filter key: "+params[3]); + if(params.length > 4 && params[4]!=null && params[4]!=GeonetworkRequestFilterParameters.REQUEST_DELIMITIER){ + logger.debug("Read filter value: "+params[4]); + filters.put(params[3], params[4]); + } + } - return new GeonetworkRequestCriteria(theScope, mode, owner, visibility); + requestCriteria.setMode(mode); + requestCriteria.setFilters(filters); + requestCriteria.setVisibility(visibility); + + return requestCriteria; } @@ -222,6 +228,31 @@ public class GeonetworkRequestDecoder { } + + /** + * Checks if is valid uuid. + * + * @param uuid the uuid + * @return true, if is valid uuid + */ + public static boolean isValidUUID(String uuid){ + + if(uuid == null || uuid.isEmpty()) + return false; + + try{ + UUID id = UUID.fromString(uuid); + if(id.toString().equals(uuid)) + return true; + }catch(Exception e){ + return false; + } + + return true; + + } + + /* (non-Javadoc) * @see java.lang.Object#toString() */ diff --git a/src/main/java/org/gcube/datatransfer/resolver/GeonetworkRequestFilterParameters.java b/src/main/java/org/gcube/datatransfer/resolver/GeonetworkRequestFilterParameters.java index 763e5cf..737f5f2 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/GeonetworkRequestFilterParameters.java +++ b/src/main/java/org/gcube/datatransfer/resolver/GeonetworkRequestFilterParameters.java @@ -15,5 +15,7 @@ public interface GeonetworkRequestFilterParameters { public static enum VISIBILITY {PUB, PRV}; public static String REQUEST_DELIMITIER = "/$$"; - public static String OWNER_PARAM = "OWNER"; + public static String FILTER_KEY = "FKEY"; + + public static String FILTER_VALUE = "FVALUE"; } diff --git a/src/main/java/org/gcube/datatransfer/resolver/catalogue/CatalogueResolver.java b/src/main/java/org/gcube/datatransfer/resolver/catalogue/CatalogueResolver.java index a32046e..36ac781 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/catalogue/CatalogueResolver.java +++ b/src/main/java/org/gcube/datatransfer/resolver/catalogue/CatalogueResolver.java @@ -21,7 +21,8 @@ import org.gcube.datatransfer.resolver.ResourceCatalogueCodes; import org.gcube.datatransfer.resolver.UriResolverRewriteFilter; import org.gcube.datatransfer.resolver.applicationprofile.ApplicationProfileNotFoundException; import org.gcube.datatransfer.resolver.catalogue.resource.ApplicationProfileReaderForCatalogueResolver; -import org.gcube.datatransfer.resolver.catalogue.resource.CkanPorltetApplicationProfile; +import org.gcube.datatransfer.resolver.catalogue.resource.CkanCatalogueConfigurationsReader; +import org.gcube.datatransfer.resolver.catalogue.resource.GatewayCKANCatalogueReference; import org.gcube.datatransfer.resolver.catalogue.resource.UpdateApplicationProfileCatalogueResolver; import org.gcube.datatransfer.resolver.scope.ScopeUtil; import org.json.JSONArray; @@ -30,6 +31,8 @@ import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import eu.trentorise.opendata.jackan.model.CkanDataset; + /** * The Class GisResolver. @@ -200,14 +203,35 @@ public class CatalogueResolver extends HttpServlet{ try{ logger.info("Setting scope "+scope+ " to search Ckan Portlet URL from IS"); ScopeProvider.instance.set(scope); - ckanPorltetUrl = CkanPorltetApplicationProfile.getPortletUrlFromInfrastrucure(); + GatewayCKANCatalogueReference ckanCatalogueReference = CkanCatalogueConfigurationsReader.loadCatalogueEndPoints(); + + //IS THE PRODUCT PLUBLIC OR PRIVATE? + //USING ACCESS TO PUBLIC PORTLET IF THE ITEM IS PUBLIC, OTHERWISE ACCESS TO PRIVATE PORTLET + ckanPorltetUrl = ckanCatalogueReference.getPrivatePortletURL(); + String datasetName = cer.getValueOfParameter(CatalogueRequestParameter.ENTITY_NAME.getKey()); + if(ckanCatalogueReference.getCkanURL()!=null){ + try{ + CkanDataset dataset = CkanCatalogueConfigurationsReader.getDataset(datasetName, ckanCatalogueReference.getCkanURL()); + if(dataset!=null){ + ckanPorltetUrl = ckanCatalogueReference.getPublicPortletURL(); + logger.info("The dataset "+datasetName+" is a public item using public access to CKAN portlet: "+ckanPorltetUrl); + } + }catch(Exception e){ + logger.warn("Error on checking if dataset: "+datasetName+" is private or not"); + ckanPorltetUrl = ckanCatalogueReference.getPublicPortletURL(); + } + } + + if(ckanPorltetUrl == null || ckanPorltetUrl.isEmpty()){ - sendError(resp, HttpStatus.SC_INTERNAL_SERVER_ERROR, "An error occurred during discovery Data Catalogue URL, try again later"); + sendError(resp, HttpStatus.SC_INTERNAL_SERVER_ERROR, "An error occurred during discovery the resource: "+CkanCatalogueConfigurationsReader.APPLICATION_PROFILE_NAME+" in the scope: "+scope+", try again later"); return; } + + }catch(Exception e){ - logger.error("An error occurred during discovery Data Catalogue URL: ",e); - sendError(resp, HttpStatus.SC_INTERNAL_SERVER_ERROR, "An error occurred during discovery Data Catalogue URL, try again later"); + logger.error("Error during discovery the resource: "+CkanCatalogueConfigurationsReader.APPLICATION_PROFILE_NAME+" in the scope: "+scope, e); + sendError(resp, HttpStatus.SC_INTERNAL_SERVER_ERROR, "An error occurred during discovery the resource: "+CkanCatalogueConfigurationsReader.APPLICATION_PROFILE_NAME+" in the scope: "+scope+", try again later"); return; }finally{ @@ -227,6 +251,7 @@ public class CatalogueResolver extends HttpServlet{ buildPath+= PATH_SEPARATOR+cer.getValueOfParameter(CatalogueRequestParameter.ENTITY_CONTEXT.getKey()) + PATH_SEPARATOR; buildPath+=cer.getValueOfParameter(CatalogueRequestParameter.ENTITY_NAME.getKey()); + String finalUrl = ckanPorltetUrl+"?"+buildPath; logger.info("Builded final URL: "+finalUrl); resp.sendRedirect(resp.encodeRedirectURL(finalUrl)); @@ -511,7 +536,7 @@ public class CatalogueResolver extends HttpServlet{ public static void main(String[] args) { try{ - String scope = "d4science.research"; + String scope = "/d4science.research-infrastructures.eu"; ApplicationProfileReaderForCatalogueResolver appPrCatResolver = new ApplicationProfileReaderForCatalogueResolver(scope, true); logger.info("Reosurce for Catalogue Resolver: "+appPrCatResolver); }catch(Exception e){ diff --git a/src/main/java/org/gcube/datatransfer/resolver/catalogue/endpoint/CatalogueServiceEndpointReader.java b/src/main/java/org/gcube/datatransfer/resolver/catalogue/endpoint/CatalogueServiceEndpointReader.java new file mode 100644 index 0000000..cb7908c --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/catalogue/endpoint/CatalogueServiceEndpointReader.java @@ -0,0 +1,139 @@ +/** + * + */ +package org.gcube.datatransfer.resolver.catalogue.endpoint; + +import static org.gcube.resources.discovery.icclient.ICFactory.clientFor; +import static org.gcube.resources.discovery.icclient.ICFactory.queryFor; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.gcube.common.resources.gcore.ServiceEndpoint; +import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueImpl; +import org.gcube.resources.discovery.client.api.DiscoveryClient; +import org.gcube.resources.discovery.client.queries.api.SimpleQuery; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * The Class CatalogueServiceEndpointReader. + * + * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it + * Apr 20, 2018 + */ +public class CatalogueServiceEndpointReader { + + // data catalogue info + private final static String RUNTIME_CATALOGUE_RESOURCE_NAME = "CKanDataCatalogue"; + private final static String PLATFORM_CATALOGUE_NAME = "Tomcat"; + private final static String CKAN_IS_ROOT_MASTER = "IS_ROOT_MASTER"; + private static final Logger logger = LoggerFactory.getLogger(CatalogueServiceEndpointReader.class); + + + /** A map to cache couple SCOPE - THE CKAN PORTLET URL OPERATING IN THE SCOPE*/ + private static Map cacheCkanDataCatalogue = new HashMap(); + + + /** + * Instantiates a new catalogue service endpoint reader. + */ + public CatalogueServiceEndpointReader(){ + } + + + /** + * Retrieve endpoints information from IS for DataCatalogue URL. + * + * @return list of endpoints for ckan data catalogue + * @throws Exception the exception + */ + public static List getConfigurationFromISFORCatalogueUrl() throws Exception{ + + logger.info("Searching SE "+RUNTIME_CATALOGUE_RESOURCE_NAME+" configurations in the scope: "+ScopeProvider.instance.get()); + + SimpleQuery query = queryFor(ServiceEndpoint.class); + query.addCondition("$resource/Profile/Name/text() eq '"+ RUNTIME_CATALOGUE_RESOURCE_NAME +"'"); + query.addCondition("$resource/Profile/Platform/Name/text() eq '"+ PLATFORM_CATALOGUE_NAME +"'"); + query.addVariable("$prop", "$resource/Profile/AccessPoint/Properties/Property") + .addCondition("$prop/Name/text() eq '"+CKAN_IS_ROOT_MASTER+"'") + .addCondition("$prop/Value/text() eq 'true'"); + + logger.info("Performing query 1 with property '"+CKAN_IS_ROOT_MASTER+"': "+query); + + DiscoveryClient client = clientFor(ServiceEndpoint.class); + List toReturn = client.submit(query); + + logger.info("The query 1 returned "+toReturn.size()+ " ServiceEndpoint/s"); + + if(toReturn.size()==0){ + logger.info("NO "+RUNTIME_CATALOGUE_RESOURCE_NAME+" having "+CKAN_IS_ROOT_MASTER+" property"); + query = queryFor(ServiceEndpoint.class); + query.addCondition("$resource/Profile/Name/text() eq '"+ RUNTIME_CATALOGUE_RESOURCE_NAME +"'"); + query.addCondition("$resource/Profile/Platform/Name/text() eq '"+ PLATFORM_CATALOGUE_NAME +"'"); + logger.info("Performing query 2: "+query); + client = clientFor(ServiceEndpoint.class); + toReturn = client.submit(query); + logger.info("The query 2 returned "+toReturn.size()+ " ServiceEndpoint/s"); + } + + return toReturn; + + + } + + + /** + * Gets the catalogue url. + * + * @return the catalogue url + */ + public static String getCatalogueUrl() { + String scope = ScopeProvider.instance.get(); + logger.debug("Getting Catalogue URL for scope: "+scope +" read from ScopeProvider"); + String catalogueURLForScope = cacheCkanDataCatalogue.get(scope); + + if(catalogueURLForScope==null){ + logger.debug("Catalogue URL not found in cache, loading from IS"); + + try{ + logger.debug("Instancing again the scope provider with scope value: "+scope); + ScopeProvider.instance.set(scope); + DataCatalogueImpl utilCKAN = new DataCatalogueImpl(scope); + catalogueURLForScope = utilCKAN.getCatalogueUrl(); + if(catalogueURLForScope==null) + throw new Exception("No cataluge url found in the scope: "+scope); + + cacheCkanDataCatalogue.put(scope, catalogueURLForScope); + }catch(Exception e){ + logger.error("Error on getting the catalogue url in the scope: "+scope, e); + } + + } + logger.info("Returning Catalogue URL: "+catalogueURLForScope +" for the scope: "+scope); + return catalogueURLForScope; + } + + +// /** +// * The main method. +// * +// * @param args the arguments +// */ +// public static void main(String[] args) { +// +// String scope = "/d4science.research-infrastructures.eu/gCubeApps/BiodiversityLab"; +// ScopeProvider.instance.set(scope); +// try { +// String catalogueURL = CatalogueServiceEndpointReader.getCatalogueUrl(scope); +// System.out.println(catalogueURL); +// } +// catch (Exception e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } +// } +} diff --git a/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/CkanCatalogueConfigurationsReader.java b/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/CkanCatalogueConfigurationsReader.java new file mode 100644 index 0000000..a75168d --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/CkanCatalogueConfigurationsReader.java @@ -0,0 +1,193 @@ +/** + * + */ + +package org.gcube.datatransfer.resolver.catalogue.resource; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static org.gcube.resources.discovery.icclient.ICFactory.client; + +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.net.URI; +import java.util.List; +import java.util.Properties; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.gcube.common.resources.gcore.utils.XPathHelper; +import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.datatransfer.resolver.applicationprofile.ApplicationProfileNotFoundException; +import org.gcube.datatransfer.resolver.catalogue.endpoint.CatalogueServiceEndpointReader; +import org.gcube.resources.discovery.client.api.DiscoveryClient; +import org.gcube.resources.discovery.client.queries.api.Query; +import org.gcube.resources.discovery.client.queries.impl.QueryBox; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Node; +import org.xml.sax.InputSource; + +import eu.trentorise.opendata.jackan.CkanClient; +import eu.trentorise.opendata.jackan.model.CkanDataset; + + +/** + * The Class CkanCatalogueConfigurationsReader. + * + * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it + * Apr 20, 2018 + */ +public class CkanCatalogueConfigurationsReader { + + private static final Logger logger = LoggerFactory.getLogger(CkanCatalogueConfigurationsReader.class); + public final static String APPLICATION_PROFILE_NAME = "CkanPortlet"; + private static final String DATACATALOGUECONFIGURATION_PROPERTIES = "datacatalogueconfiguration.properties"; + + + + /** + * Load catalogue end points. + * + * @return the gateway ckan catalogue reference + * @throws Exception the exception + */ + public static GatewayCKANCatalogueReference loadCatalogueEndPoints() throws Exception{ + GatewayCKANCatalogueReference links = new GatewayCKANCatalogueReference(); + links.setScope(ScopeProvider.instance.get()); + + String privatePortletURL = getPortletUrlForScopeFromIS(); + links.setPrivatePortletURL(privatePortletURL); + + //Building public URL from private portlet URL + try{ + URI toURL = new URI(privatePortletURL); + String publicURL = privatePortletURL.startsWith("https://")?"https://"+toURL.getHost():"http://"+toURL.getHost(); + String realiveURLToPublicCtlg = getRelativeURLToCatalogue(); + links.setPublicPortletURL(publicURL+"/"+realiveURLToPublicCtlg); + }catch(Exception e){ + logger.warn("Erron on generating public catalogue URL from private URL: "+privatePortletURL, e); + } + + //Getting the CKAN Portet URL for current scope + try{ + String ckanPortletURL = CatalogueServiceEndpointReader.getCatalogueUrl(); + links.setCkanURL(ckanPortletURL); + }catch(Exception e){ + logger.warn("Erron on getting CKAN Porlet URL for scope: "+ScopeProvider.instance.get(), e); + } + + return links; + } + + + /** + * Retrieve a ckan dataset given its id. The CkanClient is used, without api key. The result is null also when the dataset is private. + * @param datasetIdorName + * @param catalogueURL + * @return + * @throws Exception + */ + public static CkanDataset getDataset(String datasetIdorName, String catalogueURL) throws Exception{ + logger.info("Request ckan dataset with id " + datasetIdorName); + + // checks + checkNotNull(datasetIdorName); + checkArgument(!datasetIdorName.isEmpty()); + + CkanClient client = new CkanClient(catalogueURL); + return client.getDataset(datasetIdorName); + + } + + /** + * Gets the portlet url for scope from is. + * + * @return the portlet url for scope from is + * @throws Exception the exception + */ + private static String getPortletUrlForScopeFromIS() throws Exception { + + String scope = ScopeProvider.instance.get(); + logger.debug("Trying to fetch applicationProfile profile from the infrastructure for " + + APPLICATION_PROFILE_NAME + " scope: " + scope); + try { + Query q = + new QueryBox( + "for $profile in collection('/db/Profiles/GenericResource')//Resource " + + "where $profile/Profile/SecondaryType/string() eq 'ApplicationProfile' and $profile/Profile/Name/string() " + + " eq '" + + APPLICATION_PROFILE_NAME + + "'" + + "return $profile"); + DiscoveryClient client = client(); + List appProfile = client.submit(q); + if (appProfile == null || appProfile.size() == 0) + throw new ApplicationProfileNotFoundException( + "Your applicationProfile is not registered in the infrastructure"); + else { + String elem = appProfile.get(0); + DocumentBuilder docBuilder = + DocumentBuilderFactory.newInstance().newDocumentBuilder(); + Node node = docBuilder.parse(new InputSource(new StringReader(elem))).getDocumentElement(); + XPathHelper helper = new XPathHelper(node); + List currValue = null; + currValue = + helper.evaluate("/Resource/Profile/Body/url/text()"); + if (currValue != null && currValue.size() > 0) { + logger.debug("CKAN Portlet url found is " + currValue.get(0)); + return currValue.get(0); + } + } + } + catch (Exception e) { + throw new Exception("Error while trying to fetch applicationProfile profile for name "+APPLICATION_PROFILE_NAME+"from the infrastructure, using scope: "+scope); + } + + return null; + } + + /** + * Gets the relative url to catalogue. + * + * @return the relative url to catalogue + */ + private static String getRelativeURLToCatalogue(){ + Properties prop = new Properties(); + String relativeURLToCatalogue = null; + try { + InputStream in = CkanCatalogueConfigurationsReader.class.getResourceAsStream(DATACATALOGUECONFIGURATION_PROPERTIES); + // load a properties file + prop.load(in); + // get the property value + relativeURLToCatalogue = prop.getProperty("PORTAL_RELATIVE_URL_TO_CATALOGUE"); + + if(relativeURLToCatalogue==null || relativeURLToCatalogue.isEmpty()) + return "catalogue"; + + } catch (IOException e) { + logger.error("An error occurred on read property file: "+DATACATALOGUECONFIGURATION_PROPERTIES, e); + } + return relativeURLToCatalogue; + } + +// /** +// * The main method. +// * +// * @param args the arguments +// */ +// public static void main(String[] args) { +// +// ScopeProvider.instance.set("/gcube/devsec/devVRE"); +// try { +// GatewayCKANCatalogueReference links = CkanCatalogueConfigurationsReader.loadCatalogueEndPoints(); +// System.out.println(links); +// } +// catch (Exception e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } +// } +} diff --git a/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/CkanPorltetApplicationProfile.java b/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/CkanPorltetApplicationProfile.java deleted file mode 100644 index 6866368..0000000 --- a/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/CkanPorltetApplicationProfile.java +++ /dev/null @@ -1,84 +0,0 @@ -/** - * - */ - -package org.gcube.datatransfer.resolver.catalogue.resource; - -import static org.gcube.resources.discovery.icclient.ICFactory.client; - -import java.io.StringReader; -import java.util.List; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; - -import org.gcube.common.resources.gcore.utils.XPathHelper; -import org.gcube.common.scope.api.ScopeProvider; -import org.gcube.datatransfer.resolver.applicationprofile.ApplicationProfileNotFoundException; -import org.gcube.resources.discovery.client.api.DiscoveryClient; -import org.gcube.resources.discovery.client.queries.api.Query; -import org.gcube.resources.discovery.client.queries.impl.QueryBox; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.w3c.dom.Node; -import org.xml.sax.InputSource; - - -/** - * The Class CkanPorltetApplicationProfile. - * - * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it - * May 16, 2017 - */ -public class CkanPorltetApplicationProfile { - - private static final Logger logger = LoggerFactory.getLogger(CkanPorltetApplicationProfile.class); - private final static String APPLICATION_PROFILE_NAME = "CkanPortlet"; - - /** - * Gets the portlet url from infrastrucure. - * - * @return the portlet url from infrastrucure - * @throws Exception the exception - */ - public static String getPortletUrlFromInfrastrucure() throws Exception { - - String scope = ScopeProvider.instance.get(); - logger.debug("Trying to fetch applicationProfile profile from the infrastructure for " + - APPLICATION_PROFILE_NAME + " scope: " + scope); - try { - Query q = - new QueryBox( - "for $profile in collection('/db/Profiles/GenericResource')//Resource " + - "where $profile/Profile/SecondaryType/string() eq 'ApplicationProfile' and $profile/Profile/Name/string() " + - " eq '" + - APPLICATION_PROFILE_NAME + - "'" + - "return $profile"); - DiscoveryClient client = client(); - List appProfile = client.submit(q); - if (appProfile == null || appProfile.size() == 0) - throw new ApplicationProfileNotFoundException( - "Your applicationProfile is not registered in the infrastructure"); - else { - String elem = appProfile.get(0); - DocumentBuilder docBuilder = - DocumentBuilderFactory.newInstance().newDocumentBuilder(); - Node node = docBuilder.parse(new InputSource(new StringReader(elem))).getDocumentElement(); - XPathHelper helper = new XPathHelper(node); - List currValue = null; - currValue = - helper.evaluate("/Resource/Profile/Body/url/text()"); - if (currValue != null && currValue.size() > 0) { - logger.debug("CKAN Portlet url found is " + currValue.get(0)); - return currValue.get(0); - } - } - } - catch (Exception e) { - throw new Exception("Error while trying to fetch applicationProfile profile for name "+APPLICATION_PROFILE_NAME+"from the infrastructure, using scope: "+scope); - } - - return null; - } -} diff --git a/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/GatewayCKANCatalogueReference.java b/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/GatewayCKANCatalogueReference.java new file mode 100644 index 0000000..fe05f97 --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/GatewayCKANCatalogueReference.java @@ -0,0 +1,140 @@ +/** + * + */ +package org.gcube.datatransfer.resolver.catalogue.resource; + +import java.io.Serializable; + + +/** + * + * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it + * Nov 23, 2017 + */ +public class GatewayCKANCatalogueReference implements Serializable{ + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String privatePortletURL; + private String publicPortletURL; + private String scope; + private String ckanURL; + + /** + * + */ + public GatewayCKANCatalogueReference() { + + } + + /** + * @param privatePortletURL + * @param publicPortletURL + * @param ckanURL + * @param scope + */ + public GatewayCKANCatalogueReference(String scope, + String privatePortletURL, String publicPortletURL, String ckanURL) { + this.scope = scope; + this.privatePortletURL = privatePortletURL; + this.publicPortletURL = publicPortletURL; + this.ckanURL = ckanURL; + } + + + /** + * @return the ckanURL + */ + public String getCkanURL() { + + return ckanURL; + } + + + /** + * @param ckanURL the ckanURL to set + */ + public void setCkanURL(String ckanURL) { + + this.ckanURL = ckanURL; + } + + /** + * @return the privatePortletURL + */ + public String getPrivatePortletURL() { + + return privatePortletURL; + } + + + /** + * @return the publicPortletURL + */ + public String getPublicPortletURL() { + + return publicPortletURL; + } + + + /** + * @return the scope + */ + public String getScope() { + + return scope; + } + + + /** + * @param privatePortletURL the privatePortletURL to set + */ + public void setPrivatePortletURL(String privatePortletURL) { + + this.privatePortletURL = privatePortletURL; + } + + + /** + * @param publicPortletURL the publicPortletURL to set + */ + public void setPublicPortletURL(String publicPortletURL) { + + this.publicPortletURL = publicPortletURL; + } + + + /** + * @param scope the scope to set + */ + public void setScope(String scope) { + + this.scope = scope; + } + + + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + + StringBuilder builder = new StringBuilder(); + builder.append("GatewayCatalogueReference [privatePortletURL="); + builder.append(privatePortletURL); + builder.append(", publicPortletURL="); + builder.append(publicPortletURL); + builder.append(", scope="); + builder.append(scope); + builder.append(", ckanURL="); + builder.append(ckanURL); + builder.append("]"); + return builder.toString(); + } + + +} diff --git a/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/datacatalogueconfiguration.properties b/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/datacatalogueconfiguration.properties new file mode 100644 index 0000000..c4729dc --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/datacatalogueconfiguration.properties @@ -0,0 +1,7 @@ +# Property files +# +# author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it +# created 11/2017 +# + +PORTAL_RELATIVE_URL_TO_CATALOGUE = catalogue \ No newline at end of file diff --git a/src/main/java/org/gcube/datatransfer/resolver/gis/geonetwork/FilterGetRecords.java b/src/main/java/org/gcube/datatransfer/resolver/gis/geonetwork/FilterGetRecords.java index 794e786..bac8055 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/gis/geonetwork/FilterGetRecords.java +++ b/src/main/java/org/gcube/datatransfer/resolver/gis/geonetwork/FilterGetRecords.java @@ -34,44 +34,101 @@ public class FilterGetRecords { private List foundPublicIds = null; + private static FilterGetRecords instance = null; + + private Object lock1 = new Object(); + + + private long delay = 60000; //1 min + /** * Instantiates a new filter get records. - * - * @param readBody the read body */ - public FilterGetRecords(String readBody) { + private FilterGetRecords() { - if(readBody!=null && !readBody.isEmpty() && readBody.contains(CSW_GET_RECORDS)){ - logger.info("Is "+CSW_GET_RECORDS+" request, getting public ids"); - GeoNetworkReader reader; - try { - reader = GeoNetwork.get(); - final GNSearchRequest req=new GNSearchRequest(); - req.addParam(GNSearchRequest.Param.any,""); - GNSearchResponse resp=reader.query(req); + new java.util.Timer().scheduleAtFixedRate(new java.util.TimerTask() { - foundPublicIds = new ArrayList(); - Iterator iterator=resp.iterator(); - while(iterator.hasNext()){ - foundPublicIds.add(iterator.next().getUUID()); - } - logger.info("Public Metadata ids are: "+foundPublicIds.size()); - }catch (Exception e) { - logger.error("Error during sending GNSearchRequest: ",e); + @Override + public void run() { + + resetCache(); } - }else - logger.trace("Is not a"+CSW_GET_RECORDS+" request, skipping"); + }, delay, delay); } + /** + * Gets the single instance of FilterGetRecords. + * + * @return single instance of FilterGetRecords + */ + public static FilterGetRecords getInstance() { + + if(instance == null) + instance = new FilterGetRecords(); + + return instance; + + } + + public void resetCache(){ + synchronized(lock1) { + foundPublicIds = null; + logger.info("Reset publid ids performed"); + } + } /** * Gets the public file identifiers. * + * @param bodyRequest the body request + * @param useCache the use cache * @return the public file identifiers */ - public List getPublicFileIdentifiers(){ + public List getPublicFileIdentifiers(String bodyRequest, boolean useCache){ + //System.out.println("the readBody: "+readBody); + + synchronized (lock1) { + + if(bodyRequest!=null && !bodyRequest.isEmpty() && bodyRequest.contains(CSW_GET_RECORDS)){ + + if(useCache && foundPublicIds!=null) + return foundPublicIds; + + logger.info("Is "+CSW_GET_RECORDS+" request, getting public ids"); + GeoNetworkReader reader; + try { + reader = GeoNetwork.get(); + final GNSearchRequest req=new GNSearchRequest(); + req.addParam(GNSearchRequest.Param.any,""); + GNSearchResponse resp=reader.query(req); + + foundPublicIds = new ArrayList(); + Iterator iterator=resp.iterator(); + while(iterator.hasNext()){ + foundPublicIds.add(iterator.next().getUUID()); + } + logger.info("Public Metadata ids are: "+foundPublicIds.size()); + }catch (Exception e) { + logger.error("Error during sending GNSearchRequest: ",e); + } + }else + logger.trace("Is not a: "+CSW_GET_RECORDS+" request, skipping"); + + return foundPublicIds; + } + } + + + + + /** + * Csw request get public identifier. + * + * @return the list + */ + public List cswRequestGetPublicIdentifier(){ logger.info("Performing query to retrieve the public file identifiers"); GeoNetworkReader reader; diff --git a/src/main/java/org/gcube/datatransfer/resolver/gis/geonetwork/GeonetworkResolver.java b/src/main/java/org/gcube/datatransfer/resolver/gis/geonetwork/GeonetworkResolver.java index 5dc8d69..8cf4a44 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/gis/geonetwork/GeonetworkResolver.java +++ b/src/main/java/org/gcube/datatransfer/resolver/gis/geonetwork/GeonetworkResolver.java @@ -3,6 +3,8 @@ */ package org.gcube.datatransfer.resolver.gis.geonetwork; +import static org.gcube.common.authorization.client.Constants.authorizationService; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -24,6 +26,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.IOUtils; +import org.gcube.common.authorization.library.AuthorizationEntry; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.datatransfer.resolver.GeonetworkRequestFilterParameters; import org.gcube.datatransfer.resolver.GeonetworkRequestFilterParameters.MODE; @@ -54,6 +57,15 @@ import org.w3c.dom.Document; */ public class GeonetworkResolver extends HttpServlet{ + /** + * + */ + public static final String REPLACED_UUID_BY_FILTER_PLEASE_IGNORE = + "Replaced UUID by GeonetworkResolver filter, please ignore"; + /** + * + */ + public static final String REPLACED_A_PUBLIC_UUID_PLEASE_IGNORE = "Replaced a public UUID, please ignore"; /** * */ @@ -71,6 +83,7 @@ public class GeonetworkResolver extends HttpServlet{ */ private static final long serialVersionUID = -61097584153314181L; public static final String SCOPE = "scope"; + public static final String GCUBETOKEN = "gcube-token"; public static final String REMAIN_PATH_PARAM = "remainPath"; public static final String RESET_CACHE_PARAM = "resetcache"; public static final String RESET_CACHED_SCOPE_PARAM = "resetcachedscope"; @@ -92,6 +105,7 @@ public class GeonetworkResolver extends HttpServlet{ //TEN SECONDS public static final long CACHE_RESET_DELAY = 10*1000; + /* (non-Javadoc) * @see javax.servlet.GenericServlet#init() */ @@ -116,18 +130,20 @@ public class GeonetworkResolver extends HttpServlet{ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { logger.info("doGET running... query string: "+req.getQueryString()); String scopeValue = req.getParameter(SCOPE); + String gCubeToken = req.getParameter(GCUBETOKEN); String remainValue = req.getParameter(REMAIN_PATH_PARAM); String mode = req.getParameter(GeonetworkRequestFilterParameters.MODE.class.getSimpleName()); String visibility = req.getParameter(GeonetworkRequestFilterParameters.VISIBILITY.class.getSimpleName()); - String owner = req.getParameter(GeonetworkRequestFilterParameters.OWNER_PARAM); + String filterKeyParam = req.getParameter(GeonetworkRequestFilterParameters.FILTER_KEY); + String filterValueParam = req.getParameter(GeonetworkRequestFilterParameters.FILTER_VALUE); String resetCache = req.getParameter(RESET_CACHE_PARAM); String resetScope = req.getParameter(RESET_CACHED_SCOPE_PARAM); String originalScope = ScopeProvider.instance.get(); - if (scopeValue == null || scopeValue.equals("")) { + if ((scopeValue == null || scopeValue.isEmpty()) && (gCubeToken==null || gCubeToken.isEmpty())) { logger.debug("Scope not found"); - sendError(resp, HttpServletResponse.SC_BAD_REQUEST, SCOPE+" not found or empty"); + sendError(resp, HttpServletResponse.SC_BAD_REQUEST, SCOPE+" and "+GCUBETOKEN+" not found or empty"); return; } @@ -146,19 +162,24 @@ public class GeonetworkResolver extends HttpServlet{ } logger.info("SCOPE: " + scopeValue); + logger.info("GCUBETOKEN: " + gCubeToken); logger.info("MODE is: "+theMode); logger.info("VISIBILITY is: "+theVisibility); - logger.info(GeonetworkRequestFilterParameters.OWNER_PARAM +" is: "+owner); + logger.info(GeonetworkRequestFilterParameters.FILTER_KEY +" is: "+filterKeyParam); + logger.info(GeonetworkRequestFilterParameters.FILTER_VALUE +" is: "+filterValueParam); try { - GeonetworkInstance gnInstance = getGeonetworkInstanceForScope(scopeValue); + if(isValidToken(gCubeToken)){ + AuthorizationEntry entry = authorizationService().get(gCubeToken); + //retrieve the info of the token owner + //entry.getClientInfo(); + //retrieve the context of the token owner + scopeValue = entry.getContext(); + logger.info("Got scope "+scopeValue+" from token: "+gCubeToken+" via authorization service"); + } -// if(gnInstance==null){ -// logger.info("GeonetworkInstance not istanciable via geonetwork library.. using "); -// ServerParameters serverParams = getGeonetworkCachedServerParameters(scopeValue); -// gnInstance = gntwAccess.getGeonetworkInstance(); -// } + GeonetworkInstance gnInstance = getGeonetworkInstanceForScope(scopeValue); ScopeProvider.instance.set(scopeValue); @@ -221,6 +242,272 @@ public class GeonetworkResolver extends HttpServlet{ } } + /* (non-Javadoc) + * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) + * This call is authenticated + */ + @SuppressWarnings("resource") + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException { + + /*MultiReadHttpServletRequest req2; + if(req instanceof MultiReadHttpServletRequest) + req2 = (MultiReadHttpServletRequest) req;*/ + + String originalScope = ScopeProvider.instance.get(); + logger.info("doPost running..."); + String scope = req.getParameter(SCOPE); + String gCubeToken = req.getParameter(GCUBETOKEN); + String remainValue = req.getParameter(REMAIN_PATH_PARAM); + String mode = req.getParameter(GeonetworkRequestFilterParameters.MODE.class.getSimpleName()); + String visibility = req.getParameter(GeonetworkRequestFilterParameters.VISIBILITY.class.getSimpleName()); + + //HOW TO PASS MORE THAN ONE? + String filterKeyParam = req.getParameter(GeonetworkRequestFilterParameters.FILTER_KEY); + String filterValueParam = req.getParameter(GeonetworkRequestFilterParameters.FILTER_VALUE); + + Map filters = new HashMap(); + //boolean filterPublicMetadata = false; + boolean noAuthenticationB = false; + + MODE theMode; + VISIBILITY theVisibility; + + if ((scope == null || scope.isEmpty()) && (gCubeToken==null || gCubeToken.isEmpty())) { + logger.debug("Scope not found"); + sendError(resp, HttpServletResponse.SC_BAD_REQUEST, SCOPE+" and "+GCUBETOKEN+" not found or empty"); + return; + } + + theMode = GeonetworkRequestFilterParameters.MODE.valueOf(mode); + theVisibility = GeonetworkRequestFilterParameters.VISIBILITY.valueOf(visibility); + + logger.info(SCOPE +" is: " + scope); + logger.info(GeonetworkRequestFilterParameters.MODE.class.getSimpleName() +" is: "+theMode); + logger.info(GeonetworkRequestFilterParameters.VISIBILITY.class.getSimpleName() +" is: "+theVisibility); + logger.info(GeonetworkRequestFilterParameters.FILTER_KEY +" are: "+filterKeyParam); + logger.info(GeonetworkRequestFilterParameters.FILTER_VALUE +" are: "+filterValueParam); + + if(filterKeyParam!=null && filterValueParam!=null){ + filters.put(filterKeyParam, filterValueParam); + logger.debug("Added filter parmas to map filters: "+filters); + } + + try { + + if(isValidToken(gCubeToken)){ + AuthorizationEntry entry = authorizationService().get(gCubeToken); + //retrieve the info of the token owner + //entry.getClientInfo(); + //retrieve the context of the token owner + scope = entry.getContext(); + logger.info("Got scope "+scope+" from token: "+gCubeToken+" via authorization service"); + } + + GeonetworkServiceInterface gntwAccess = new GeonetworkAccessParameter(scope); + GeonetworkInstance gnInstance = gntwAccess.getGeonetworkInstance(); + + ScopeProvider.instance.set(scope); + logger.info("set scope provider "+scope); + Configuration config = gnInstance.getGeonetworkPublisher().getConfiguration(); + Account account = config.getScopeConfiguration().getAccounts().get(Type.CKAN); + logger.info("CKAN user owner is: "+account.getUser()); + + logger.info("Parameters.."); + for (Enumeration e = req.getParameterNames(); e.hasMoreElements();){ + String p = e.nextElement(); + logger.debug("param "+p + " value "+Arrays.toString(req.getParameterValues(p))); + } + + //DEBUG BODY +// String readBody = IOUtils.toString(req.getReader()); +// logger.debug("doPost read body request: "+readBody); + ByteArrayOutputStream byteArray = new ByteArrayOutputStream(); + + String geonetworkUrl = config.getGeoNetworkEndpoint(); + + // SPECIFIC HANDLER FOR GEONETWORK REQUEST: /srv/en/mef.export + String gnCSWlURL; + if(remainValue!=null && remainValue.compareTo(SRV_EN_MEF_EXPORT)==0){ + logger.info("In case of mef.export, perfoming a custom handler"); + gnCSWlURL = geonetworkUrl + SRV_EN_MEF_EXPORT; + String[] uuidValues = req.getParameterValues(UUID); + if(uuidValues!=null){ + String data = null; + for (String uuid : uuidValues) { + data = UUID+"="+uuid; + } + if(data!=null){ + logger.debug("Writing "+data +" into byte array"); + byteArray.write(data.getBytes()); + }else + IOUtils.copy(req.getReader(), byteArray); + }else + IOUtils.copy(req.getReader(), byteArray); + }else{ + gnCSWlURL = remainValue==null ||remainValue.isEmpty()?geonetworkUrl+"/"+CSW_SERVER:geonetworkUrl+"/"+CSW_SERVER+remainValue; + IOUtils.copy(req.getReader(), byteArray); + } + + //filterPublicMetadata = theVisibility.equals(VISIBILITY.PRV)?true:false; + + HTTPCallsUtils httpUtils = new HTTPCallsUtils(); + + //String theOwner = null; + + //PRIVATE LAYERS + if(theVisibility.equals(VISIBILITY.PRV)){ + logger.debug("Visibility: "+VISIBILITY.PRV+" getting private layers.."); + //VRE LAYERS + if(theMode.equals(MODE.VRE)){ + logger.debug("Getting "+MODE.VRE+" layers.."); + + //HARVESTED LAYERS + }else{ +// logger.debug("Getting "+MODE.HARVEST+" layers, I'm using filters [key: '"+filter_keys +"' and value: '"+filter_values +"'] passed as parameter to filter layer/s returned.."); +// if(filter_keys==null || filter_keys.isEmpty() || filter_values==null || filter_values.isEmpty()){ +// String error = "Harvest owner is missing. It is not possible to filter layers for the request "+MODE.HARVEST + " in the scope: "+scope+", without a valid filter as input"; +// logger.error(error); +// sendError(resp, HttpServletResponse.SC_BAD_REQUEST, error); +// return; +// } + filters.put("isHarvested", "y"); + logger.debug("Getting "+MODE.HARVEST+" layers, I'm using filters ["+filters+"]"); + } + + if(account.getUser()!=null){ + boolean authorized = GNAuthentication.login(httpUtils, geonetworkUrl, account.getUser(), account.getPassword()); + logger.trace("Authorized on "+geonetworkUrl +" ? "+authorized); + }else + logger.info("Skipping authentication, ckan user (the owner) is null"); + + //PUBLIC LAYERS + }else{ + logger.debug("Visibility: "+VISIBILITY.PUB+" getting public layers.."); + //VRE LAYERS + if(theMode.equals(MODE.VRE)){ + logger.debug("Getting "+MODE.VRE+" layers, the VRE account: "+account.getUser() +" will be used as owner user for filtering... Is it right?"); + filters.put("ownername", account.getUser()); + + //HARVESTED LAYERS + }else{ +// logger.debug("Getting "+MODE.HARVEST+" layers, I'm using filters [key: '"+filter_keys +"' and value: '"+filter_values +"'] passed as parameter to filter layer/s returned.."); +// if(filter_keys==null || filter_keys.isEmpty() || filter_values==null || filter_values.isEmpty()){ +// String error = "Harvest owner is missing. It is not possible to filter layers for the request "+MODE.HARVEST + " in the scope: "+scope+", without a valid filter as input"; +// logger.error(error); +// sendError(resp, HttpServletResponse.SC_BAD_REQUEST, error); +// return; +// } + filters.put("isHarvested", "y"); + logger.debug("Getting "+MODE.HARVEST+" layers, I'm using filters ["+filters+"] as default"); + + } + } + + logger.info("Sending CSW POST request to URL: "+gnCSWlURL); + logger.debug("Content-Type: "+req.getContentType()); + //DEBUG + //logger.debug("POST - BODY: "+byteArray.toString()); + String body = byteArray.toString(); + InputStream in = httpUtils.post(gnCSWlURL, new ByteArrayInputStream(byteArray.toByteArray()), req.getContentType(), req.getParameterMap()); + //END DEBUG + logger.debug("Response return Content-Type: "+httpUtils.getLastContentType()); + resp.setContentType(httpUtils.getLastContentType()); + OutputStream out = resp.getOutputStream(); + + if(in==null){ + logger.warn("Input stream returned is null, sending "+HttpServletResponse.SC_NOT_FOUND); + resp.sendError(HttpServletResponse.SC_NOT_FOUND); + return; + } + + try{ + + ReusableInputStream reus = new ReusableInputStream(in); + + if(theVisibility.equals(VISIBILITY.PRV)){ + logger.info("Private VISIBILITY getting public file identifiers to remove them..."); + FilterGetRecords filterGetRecords = FilterGetRecords.getInstance(); + List publicIds = filterGetRecords.getPublicFileIdentifiers(body, true); + if(publicIds!=null && publicIds.size()>0){ + logger.info("I'm removing list of public IDs with "+publicIds.size() +" item/s. Is it right?"); + //System.out.println("The response is: "+IOUtils.toString(reus)); + + Document doc = GetResponseRecordFilter.inputStreamToW3CDocument(reus); + doc = GetResponseRecordFilter.overrideResponseIdsByListIds(doc, filterGetRecords.getFoundPublicIds(), REPLACED_A_PUBLIC_UUID_PLEASE_IGNORE); + in = GetResponseRecordFilter.w3CDocumentToInputStream(doc); + + //in = GetResponseRecordFilter.overrideResponseIdsByListIds(reus, publicIds, REPLACED_A_PUBLIC_UUID_PLEASE_IGNORE); + } + } + + if(filters.size()>0){ + logger.info("Applying filtering on geonet:info..."); + Document doc = GetResponseRecordFilter.inputStreamToW3CDocument(reus); + List fileIdentifiers = GetResponseRecordFilter.getTextContentStringsForTagName(doc, "gmd:fileIdentifier"); + List noMatchingFilter = new ArrayList(); + for (String fileId : fileIdentifiers) { + + //CKECKING THE FILTERS + for (String fkey : filters.keySet()) { + String value = GetResponseRecordFilter.getMetadataValueByFileIdentifier(fileId, config.getGeoNetworkEndpoint(),config.getAdminAccount().getUser(), config.getAdminAccount().getPassword(), fkey); + //String own = GetResponseRecordFilter.getMetaOwnerNameByFileIdentifier(fileId, config.getGeoNetworkEndpoint(),config.getAdminAccount().getUser(), config.getAdminAccount().getPassword()); + String fValue = filters.get(fkey); + if(value!=null && value.compareTo(fValue)!=0){ + logger.debug(fkey +" of file Identifier "+fileId+" not matching the filter: "+fkey+" with value: "+fValue+", adding it to list to remove file identifier and exit from loop.."); + noMatchingFilter.add(fileId); + //WHEN I ADD THE FILE IDENTIFIER TO FILTERED ID, I CAN EXIT FROM CKECKING FILTERS LOOP + break; + } + } + } + + if(noMatchingFilter.size()>0){ + logger.info("Removing "+noMatchingFilter.size()+" layer/s not macthing the filters: "+filters); + //Document doc2 = GetResponseRecordFilter.inputStreamToW3CDocument(reus); + doc = GetResponseRecordFilter.overrideResponseIdsByListIds(doc, noMatchingFilter, REPLACED_UUID_BY_FILTER_PLEASE_IGNORE); + in = GetResponseRecordFilter.w3CDocumentToInputStream(doc); + + }else{ + logger.info("No replace on UUIDs was applied from filters: "+filters); + in = reus; + } + + } + + ReusableInputStream reusIs = new ReusableInputStream(in); + int bytes = IOUtils.copy(reusIs, out); + //logger.trace("POST - RETURN : "+IOUtils.toString(reusIs)); + + if(bytes==0) + logger.warn("ResponseBody is empty, returning empty resp"); + }catch(Exception e){ + logger.error("Error on copy response:", e); + }finally{ + IOUtils.closeQuietly(in); + } + + } catch (IllegalArgumentException e){ + logger.error("IllegalArgumentException:", e); + sendError(resp, HttpServletResponse.SC_BAD_REQUEST, "Illegal argument to carry out the request!"); + return; + + } catch (Exception e) { + logger.error("Exception:", e); + String error = "Sorry, an error occurred on resolving geonetwork request with scope "+scope+". Please, contact support!"; + sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, error); + return; + }finally{ + if(originalScope!=null){ + ScopeProvider.instance.set(originalScope); + logger.info("scope provider set to orginal scope: "+originalScope); + }else{ + ScopeProvider.instance.reset(); + logger.info("scope provider reset"); + } + } + } + /** * Purge remain from query string. * @@ -274,222 +561,6 @@ public class GeonetworkResolver extends HttpServlet{ return queryString; } - /* (non-Javadoc) - * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) - * This call is authenticated - */ - @SuppressWarnings("resource") - @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException { - - /*MultiReadHttpServletRequest req2; - if(req instanceof MultiReadHttpServletRequest) - req2 = (MultiReadHttpServletRequest) req;*/ - - String originalScope = ScopeProvider.instance.get(); - logger.info("doPost running..."); - String scope = req.getParameter(SCOPE); - String remainValue = req.getParameter(REMAIN_PATH_PARAM); - String mode = req.getParameter(GeonetworkRequestFilterParameters.MODE.class.getSimpleName()); - String visibility = req.getParameter(GeonetworkRequestFilterParameters.VISIBILITY.class.getSimpleName()); - String theOwner = req.getParameter(GeonetworkRequestFilterParameters.OWNER_PARAM); - //boolean filterPublicMetadata = false; - boolean noAuthenticationB = false; - - MODE theMode; - VISIBILITY theVisibility; - - if (scope == null || scope.equals("")) { - logger.debug("Scope not found"); - sendError(resp, HttpServletResponse.SC_BAD_REQUEST, SCOPE+" not found or empty"); - return; - } - - theMode = GeonetworkRequestFilterParameters.MODE.valueOf(mode); - theVisibility = GeonetworkRequestFilterParameters.VISIBILITY.valueOf(visibility); - - logger.info(SCOPE +" is: " + scope); - logger.info(GeonetworkRequestFilterParameters.MODE.class.getSimpleName() +" is: "+theMode); - logger.info(GeonetworkRequestFilterParameters.VISIBILITY.class.getSimpleName() +" is: "+theVisibility); - logger.info(GeonetworkRequestFilterParameters.OWNER_PARAM +" is: "+theOwner); - - try { - - GeonetworkServiceInterface gntwAccess = new GeonetworkAccessParameter(scope); - GeonetworkInstance gnInstance = gntwAccess.getGeonetworkInstance(); - - ScopeProvider.instance.set(scope); - logger.info("set scope provider "+scope); - Configuration config = gnInstance.getGeonetworkPublisher().getConfiguration(); - Account account = config.getScopeConfiguration().getAccounts().get(Type.CKAN); - logger.info("CKAN user owner is: "+account.getUser()); - - logger.info("Parameters.."); - for (Enumeration e = req.getParameterNames(); e.hasMoreElements();){ - String p = e.nextElement(); - logger.debug("param "+p + " value "+Arrays.toString(req.getParameterValues(p))); - } - - //DEBUG BODY -// String readBody = IOUtils.toString(req.getReader()); -// logger.debug("doPost read body request: "+readBody); - ByteArrayOutputStream byteArray = new ByteArrayOutputStream(); - - String geonetworkUrl = config.getGeoNetworkEndpoint(); - - // SPECIFIC HANDLER FOR GEONETWORK REQUEST: /srv/en/mef.export - String gnCSWlURL; - if(remainValue!=null && remainValue.compareTo(SRV_EN_MEF_EXPORT)==0){ - logger.info("In case of mef.export, perfoming a custom handler"); - gnCSWlURL = geonetworkUrl + SRV_EN_MEF_EXPORT; - String[] uuidValues = req.getParameterValues(UUID); - if(uuidValues!=null){ - String data = null; - for (String uuid : uuidValues) { - data = UUID+"="+uuid; - } - if(data!=null){ - logger.debug("Writing "+data +" into byte array"); - byteArray.write(data.getBytes()); - }else - IOUtils.copy(req.getReader(), byteArray); - }else - IOUtils.copy(req.getReader(), byteArray); - }else{ - gnCSWlURL = remainValue==null ||remainValue.isEmpty()?geonetworkUrl+"/"+CSW_SERVER:geonetworkUrl+"/"+CSW_SERVER+remainValue; - IOUtils.copy(req.getReader(), byteArray); - } - - //filterPublicMetadata = theVisibility.equals(VISIBILITY.PRV)?true:false; - - HTTPCallsUtils httpUtils = new HTTPCallsUtils(); - - //PRIVATE LAYERS - if(theVisibility.equals(VISIBILITY.PRV)){ - logger.debug("Visibility: "+VISIBILITY.PRV+" getting private layers.."); - //VRE LAYERS - if(theMode.equals(MODE.VRE)){ - logger.debug("Getting "+MODE.VRE+" layers.."); - - //HARVESTED LAYERS - }else{ - logger.debug("Getting "+MODE.HARVEST+" layers, I'm using the owner: '"+theOwner +"' passed as parameter to filter layer/s returned.."); - if(theOwner==null || theOwner.isEmpty()){ - String error = "Harvest owner is missing. It is not possible to filter layers for the request "+MODE.HARVEST + " in the scope: "+scope+", without a valid owner as input"; - logger.error(error); - sendError(resp, HttpServletResponse.SC_BAD_REQUEST, error); - return; - } - } - - if(account.getUser()!=null){ - boolean authorized = GNAuthentication.login(httpUtils, geonetworkUrl, account.getUser(), account. getPassword()); - logger.trace("Authorized on "+geonetworkUrl +" ? "+authorized); - }else - logger.info("Skipping authentication, ckan user (the owner) is null"); - - //PUBLIC LAYERS - }else{ - logger.debug("Visibility: "+VISIBILITY.PUB+" getting public layers.."); - //VRE LAYERS - if(theMode.equals(MODE.VRE)){ - logger.debug("Getting "+MODE.VRE+" layers, the VRE account: "+account.getUser() +" will be used as owner user for filtering... Is it right?"); - theOwner = account.getUser(); - - //HARVESTED LAYERS - }else{ - logger.debug("Getting "+MODE.HARVEST+" layers, I'm using the owner: '"+theOwner +"' passed as parameter to filter layer/s returned.."); - if(theOwner==null || theOwner.isEmpty()){ - String error = "Harvest owner is missing. It is not possible to filter layers for the request "+MODE.HARVEST + " in the scope: "+scope+", without a valid owner as input"; - logger.error(error); - sendError(resp, HttpServletResponse.SC_BAD_REQUEST, error); - return; - } - } - } - - logger.info("Sending CSW POST request to URL: "+gnCSWlURL); - logger.debug("Content-Type: "+req.getContentType()); - //DEBUG - //logger.debug("POST - BODY : "+byteArray.toString()); - InputStream in = httpUtils.post(gnCSWlURL, new ByteArrayInputStream(byteArray.toByteArray()), req.getContentType(), req.getParameterMap()); - //END DEBUG - logger.debug("Response return Content-Type: "+httpUtils.getLastContentType()); - resp.setContentType(httpUtils.getLastContentType()); - OutputStream out = resp.getOutputStream(); - - if(in==null){ - logger.warn("Input stream returned is null, sending "+HttpServletResponse.SC_NOT_FOUND); - resp.sendError(HttpServletResponse.SC_NOT_FOUND); - return; - } - - try{ - - ReusableInputStream reus = new ReusableInputStream(in); - - if(theVisibility.equals(VISIBILITY.PRV)){ - logger.info("Private VISIBILITY performing so getting public file identifiers to apply filtering.."); - FilterGetRecords filterGetRecords = new FilterGetRecords(byteArray.toString()); - if(filterGetRecords.getFoundPublicIds()!=null && filterGetRecords.getFoundPublicIds().size()>0){ - logger.info("I'm removing list of public IDs with "+filterGetRecords.getFoundPublicIds().size() +" item/s. Is it right?"); - in = GetResponseRecordFilter.overrideResponseIdsByListIds(reus, filterGetRecords.getFoundPublicIds(), "Replaced a public UUID, please ignore"); - } - }else { - - logger.info("Public VISIBILITY perfoming check on ownership..."); - Document doc = GetResponseRecordFilter.inputStreamToW3CDocument(reus); - List fileIdentifiers = GetResponseRecordFilter.getTextContentStringsForTagName(doc, "gmd:fileIdentifier"); - List noMatchingOwner = new ArrayList(); - for (String fileId : fileIdentifiers) { - String own = GetResponseRecordFilter.getMetaCategoryByFileIdentifier(fileId, config.getGeoNetworkEndpoint(),config.getAdminAccount().getUser(), config.getAdminAccount().getPassword()); - //String own = GetResponseRecordFilter.getMetaOwnerNameByFileIdentifier(fileId, config.getGeoNetworkEndpoint(),config.getAdminAccount().getUser(), config.getAdminAccount().getPassword()); - if(own.compareTo(theOwner)!=0){ - logger.debug("Owner of file Identifier "+fileId+" not matching the owner passed: "+theOwner+", removing it.."); - noMatchingOwner.add(fileId); - } - } - if(noMatchingOwner.size()>0){ - logger.info("Removing "+noMatchingOwner.size()+" layer/s not macthing the owner: "+theOwner); - in = GetResponseRecordFilter.overrideResponseIdsByListIds(reus, noMatchingOwner, "Replaced UUID owned by another user, please ignore"); - }else{ - logger.info("No replace on UUIDs was applied for the owner: "+theOwner); - in = reus; - } - } - - ReusableInputStream reusIs = new ReusableInputStream(in); - int bytes = IOUtils.copy(reusIs, out); - //logger.trace("POST - RETURN : "+IOUtils.toString(reusIs)); - - if(bytes==0) - logger.warn("ResponseBody is empty, returning empty resp"); - }catch(Exception e){ - logger.error("Error on copy response:", e); - }finally{ - IOUtils.closeQuietly(in); - } - - } catch (IllegalArgumentException e){ - logger.error("IllegalArgumentException:", e); - sendError(resp, HttpServletResponse.SC_BAD_REQUEST, "Illegal argument to carry out the request!"); - return; - - } catch (Exception e) { - logger.error("Exception:", e); - String error = "Sorry, an error occurred on resolving geonetwork request with scope "+scope+". Please, contact support!"; - sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, error); - return; - }finally{ - if(originalScope!=null){ - ScopeProvider.instance.set(originalScope); - logger.info("scope provider set to orginal scope: "+originalScope); - }else{ - ScopeProvider.instance.reset(); - logger.info("scope provider reset"); - } - } - } /** @@ -595,4 +666,14 @@ public class GeonetworkResolver extends HttpServlet{ response.sendRedirect(response.encodeRedirectURL(redirectTo)); return; } + + /** + * Checks if is valid token. + * + * @param gCubeToken the g cube token + * @return true, if is valid token + */ + public static boolean isValidToken(String gCubeToken){ + return gCubeToken!=null && !gCubeToken.isEmpty() && !(gCubeToken.compareTo("null")==0); + } } diff --git a/src/main/java/org/gcube/datatransfer/resolver/gis/util/GetResponseRecordFilter.java b/src/main/java/org/gcube/datatransfer/resolver/gis/util/GetResponseRecordFilter.java index 9787954..4ab803c 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/gis/util/GetResponseRecordFilter.java +++ b/src/main/java/org/gcube/datatransfer/resolver/gis/util/GetResponseRecordFilter.java @@ -15,6 +15,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URLEncoder; @@ -22,13 +23,19 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import javax.xml.namespace.NamespaceContext; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathFactory; import org.apache.commons.httpclient.HttpStatus; import org.gcube.datatransfer.resolver.gis.GeonetworkInstance; @@ -45,6 +52,7 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; /** @@ -55,6 +63,14 @@ import org.w3c.dom.NodeList; */ public class GetResponseRecordFilter { + /** + * + */ + private static final String FILE_IDENTIFIER = "fileIdentifier"; + /** + * + */ + private static final String GMD_FILE_IDENTIFIER = "gmd:fileIdentifier"; /** * */ @@ -67,8 +83,16 @@ public class GetResponseRecordFilter { * */ private static final String MESSAGE_TO_REPLACED_ID = "Replaced ID please ignore"; + public static Logger logger = LoggerFactory.getLogger(GetResponseRecordFilter.class); + + public static NamespaceCsw cswNamesapces = new NamespaceCsw(); + + public static NamespaceContextMap namespaces = new NamespaceContextMap(cswNamesapces.getMapPrefix()); + + + /** * Delete summary record. * @@ -84,7 +108,7 @@ public class GetResponseRecordFilter { for (int i = 0; i < nodes.getLength(); i++) { Element mdMetadata = (Element) nodes.item(i); // - Element id = (Element) mdMetadata.getElementsByTagName("gmd:fileIdentifier").item(0); + Element id = (Element) mdMetadata.getElementsByTagName(GMD_FILE_IDENTIFIER).item(0); Element gco = (Element) id.getElementsByTagName("gco:CharacterString").item(0); String idValue = gco.getTextContent(); logger.trace("Summary gmd:fileIdentifier is: " + idValue); @@ -119,41 +143,69 @@ public class GetResponseRecordFilter { return fileIds; } - /** * Override summary record. * - * @param doc the doc + * @param getRecordsResponse the get records response * @param identifier the identifier * @param messageToReplace the message to replace * @return true, if successful + * @throws Exception the exception */ - private static boolean overrideSummaryRecord(Document doc, String identifier, String messageToReplace) { + public static boolean overrideSummaryRecord(Document getRecordsResponse, String identifier, String messageToReplace) throws Exception { - // list - NodeList nodes = doc.getElementsByTagName("gmd:MD_Metadata"); + // USING XPATH + //String xpathExpression ="//gmd:MD_Metadata/gmd:fileIdentifier[gco:CharacterString='"+identifier+"']/gco:CharacterString"; + String xpathExpression ="//MD_Metadata/fileIdentifier/CharacterString[text()='"+identifier+"']"; + logger.trace("Searching identifier: " + identifier +" xpath: "+xpathExpression); + + NodeList nodes = getNodesFromXPathExpression(namespaces, getRecordsResponse, xpathExpression); + //Document doc = inputStreamToW3CDocument(getRecordsResponse); + + if(nodes!=null && nodes.getLength()>0){ + logger.trace("Found gmd:fileIdentifier for: " + identifier); + for (int i = 0; i < nodes.getLength(); i++) { + Node mdId = nodes.item(i); + String idValue = mdId.getTextContent(); + logger.trace("ovveriding gmd:fileIdentifier value: " + idValue+ " as public: "+messageToReplace); + String msg = messageToReplace==null?MESSAGE_TO_REPLACED_ID:messageToReplace; + mdId.setTextContent(msg); + } + return true; + } + + return false; + + /*NodeList nodes = getRecordsResponse.getElementsByTagName("gmd:MD_Metadata"); logger.trace("gmd:MD_Metadata are: " + nodes.getLength()); + for (int i = 0; i < nodes.getLength(); i++) { Element mdMetadata = (Element) nodes.item(i); - // - NodeList fileIdentifierLst = mdMetadata.getElementsByTagName("gmd:fileIdentifier"); + //printElement(mdMetadata); + + // nodelist with element or + NodeList fileIdentifierLst = mdMetadata.getElementsByTagName(GMD_FILE_IDENTIFIER); if(fileIdentifierLst==null || fileIdentifierLst.getLength()==0 || fileIdentifierLst.item(0)==null){ - logger.info("skipping identifier: " + identifier +" it has not fileidentifier"); - return false; + logger.info("NodeList of "+GMD_FILE_IDENTIFIER+" is empty, trying search 'fileIdentifier'"); + fileIdentifierLst = mdMetadata.getElementsByTagName(FILE_IDENTIFIER); + if(fileIdentifierLst==null || fileIdentifierLst.getLength()==0 || fileIdentifierLst.item(0)==null){ + logger.info("Also "+FILE_IDENTIFIER+" is missing, returning no override'"); + return false; + } } Element id = (Element) fileIdentifierLst.item(0); NodeList gcoLst = id.getElementsByTagName("gco:CharacterString"); if(gcoLst==null || gcoLst.getLength()==0 || gcoLst.item(0)==null){ - logger.info("skipping identifier: " + identifier +" it has not gco:CharacterString"); + logger.info("gco:CharacterString is missing, returning no override"); return false; } Element gco = (Element) gcoLst.item(0); String idValue = gco.getTextContent(); - logger.trace("Summary gmd:fileIdentifier is: " + idValue); + logger.trace("gmd:fileIdentifier/fileIdentifier value is: " + idValue); if (idValue!=null && idValue.equals(identifier)) { String msg = messageToReplace==null?MESSAGE_TO_REPLACED_ID:messageToReplace; gco.setTextContent(msg); @@ -161,11 +213,202 @@ public class GetResponseRecordFilter { return true; } } - return false; + return false;*/ + } + /** + * Gets the nodes from x path expression. + * + * @param context the context + * @param getRecordsResponse the get records response + * @param xpathExpression the xpath expression + * @return the nodes from x path expression + */ + private static NodeList getNodesFromXPathExpression(NamespaceContextMap context, Document getRecordsResponse, String xpathExpression) { + + try { + + XPath xpath = XPathFactory.newInstance().newXPath(); + xpath.setNamespaceContext(context); + XPathExpression xPathExpression = xpath.compile(xpathExpression); + return (NodeList) xPathExpression.evaluate(getRecordsResponse, XPathConstants.NODESET); + + } catch (Exception e) { + logger.warn("Error on searching xpath expression: "+xpathExpression+", returning null", e); + return null; + } + } + + /** + * Override summary record. + * + * @param getRecordsResponse the get records response + * @param identifier the identifier + * @param messageToReplace the message to replace + * @return true, if successful + * @throws Exception the exception + */ + private static InputStream overrideSummaryRecord(InputStream getRecordsResponse, String identifier, String messageToReplace) throws Exception { + + //String xpathExpression ="//gmd:MD_Metadata/gmd:fileIdentifier[gco:CharacterString='"+identifier+"']/gco:CharacterString"; + String xpathExpression ="//gmd:MD_Metadata/gmd:fileIdentifier/gco:CharacterString[text()='"+identifier+"']"; + logger.trace("Searching identifier: " + identifier +" xpath: "+xpathExpression); + + NodeList nodes = getNodesFromXPathExpression(namespaces, getRecordsResponse, xpathExpression); + //Document doc = inputStreamToW3CDocument(getRecordsResponse); + + if(nodes!=null && nodes.getLength()>0){ + logger.trace("Found gmd:fileIdentifier for: " + identifier); + for (int i = 0; i < nodes.getLength(); i++) { + Node mdId = nodes.item(i); + String idValue = mdId.getTextContent(); + logger.trace("ovveriding gmd:fileIdentifier value: " + idValue+ " as public: "+messageToReplace); + String msg = messageToReplace==null?MESSAGE_TO_REPLACED_ID:messageToReplace; + mdId.setTextContent(msg); + } + return getRecordsResponse; + } + + xpathExpression ="//gmd:MD_Metadata/fileIdentifier/gco:CharacterString[text()='"+identifier+"']"; + nodes = getNodesFromXPathExpression(namespaces, getRecordsResponse, xpathExpression); + + if(nodes!=null && nodes.getLength()>0){ + logger.trace("Found fileIdentifier for: " + identifier); + for (int i = 0; i < nodes.getLength(); i++) { + Node mdId = nodes.item(i); + String idValue = mdId.getTextContent(); + logger.trace("ovveriding fileIdentifier value: " + idValue+ " as public: "+messageToReplace); + String msg = messageToReplace==null?MESSAGE_TO_REPLACED_ID:messageToReplace; + mdId.setTextContent(msg); + } + return getRecordsResponse; + } + + return getRecordsResponse; + + + + /*NodeList nodes = doc.getElementsByTagName("gmd:MD_Metadata"); + logger.trace("gmd:MD_Metadata are: " + nodes.getLength()); + + for (int i = 0; i < nodes.getLength(); i++) { + Element mdMetadata = (Element) nodes.item(i); + + //printElement(mdMetadata); + + // nodelist with element or + NodeList fileIdentifierLst = mdMetadata.getElementsByTagName(GMD_FILE_IDENTIFIER); + if(fileIdentifierLst==null || fileIdentifierLst.getLength()==0 || fileIdentifierLst.item(0)==null){ + logger.info("NodeList of "+GMD_FILE_IDENTIFIER+" is empty, trying search 'fileIdentifier'"); + fileIdentifierLst = mdMetadata.getElementsByTagName(FILE_IDENTIFIER); + if(fileIdentifierLst==null || fileIdentifierLst.getLength()==0 || fileIdentifierLst.item(0)==null){ + logger.info("Also "+FILE_IDENTIFIER+" is missing, returning no override'"); + return false; + } + } + + Element id = (Element) fileIdentifierLst.item(0); + + NodeList gcoLst = id.getElementsByTagName("gco:CharacterString"); + if(gcoLst==null || gcoLst.getLength()==0 || gcoLst.item(0)==null){ + logger.info("gco:CharacterString is missing, returning no override"); + return false; + } + + Element gco = (Element) gcoLst.item(0); + String idValue = gco.getTextContent(); + logger.trace("gmd:fileIdentifier/fileIdentifier value is: " + idValue); + if (idValue!=null && idValue.equals(identifier)) { + String msg = messageToReplace==null?MESSAGE_TO_REPLACED_ID:messageToReplace; + gco.setTextContent(msg); + logger.debug("Overrided child " + idValue); + return true; + } + } + return false;*/ + } + + /** + * Gets the text from x path expression. + * + * @param context the context + * @param source the source + * @param xpathExpression the xpath expression + * @return the text from x path expression + */ + public static List getTextFromXPathExpression(NamespaceContextMap context, InputStream source, String xpathExpression){ + + List list = new ArrayList(); + try { + + XPath xpath = XPathFactory.newInstance().newXPath(); + xpath.setNamespaceContext(context); + XPathExpression xPathExpression = xpath.compile(xpathExpression); + InputSource inputSource = new InputSource(source); + +// System.out.println(xml); +// System.out.println(xpathExpression); +// System.out.println(inputSource.toString()); + + NodeList nodes = (NodeList) xPathExpression.evaluate(inputSource, XPathConstants.NODESET); + + for (int i = 0; i idsToRemove, String messageToWrite) throws IOException { + public static Document overrideResponseIdsByListIds(Document doc, List idsToRemove, String messageToWrite) throws IOException { try { - Document doc = inputStreamToW3CDocument(getRecordsResponse); + //Document doc = inputStreamToW3CDocument(getRecordsResponse); int override = 0; for (String identifier : idsToRemove) { if(overrideSummaryRecord(doc, identifier, messageToWrite)) override++; + } logger.info("Overrided "+override +" node/s"); + return doc; - //TODO IS IT POSSIBLE TO REMOVE? - /*NodeList nodeList = doc.getElementsByTagName("csw:SearchResults"); - if(nodeList!=null && nodeList.item(0)!=null){ - Node nd = nodeList.item(0); - // update staff attribute - NamedNodeMap attr = nd.getAttributes(); - Node numberOfRecordsMatched = attr.getNamedItem("numberOfRecordsMatched"); - Node numberOfRecordsReturned = attr.getNamedItem("numberOfRecordsReturned"); - logger.trace("Old numberOfRecordsMatched: "+numberOfRecordsMatched.getTextContent()); - logger.trace("Old numberOfRecordsReturned: "+numberOfRecordsReturned.getTextContent()); - try{ - int oldValueM = Integer.parseInt(numberOfRecordsMatched.getTextContent()); - int oldValueR = Integer.parseInt(numberOfRecordsReturned.getTextContent()); - int newValueM = oldValueM-removed; - int newValueR = oldValueR-removed; - logger.trace("Updating numberOfRecordsMatched at: "+newValueM); - logger.trace("Updating numberOfRecordsReturned at: "+newValueR); - numberOfRecordsMatched.setTextContent(newValueM+""); - numberOfRecordsReturned.setTextContent(newValueR+""); - }catch (Exception e) { - logger.warn("An error occurred during attribe numberOfRecordsMatched updating, skipping operation"); - } - }*/ - return w3CDocumentToInputStream(doc); } catch (Exception e) { logger.error("An error occurred during removing IDS by List: ", e); - return getRecordsResponse; + return doc; } } + + +// /** +// * Override response ids by list ids. +// * +// * @param getRecordsResponse the get records response +// * @param idsToRemove the ids to remove +// * @param messageToWrite the message to replace the right ID in the response. +// * @return the input stream +// * @throws IOException Signals that an I/O exception has occurred. +// */ +// public static InputStream overrideResponseIdsByListIds(InputStream getRecordsResponse, List idsToRemove, String messageToWrite) throws IOException { +// +// try { +// Document doc = inputStreamToW3CDocument(getRecordsResponse); +// int override = 0; +// for (String identifier : idsToRemove) { +// getRecordsResponse = overrideSummaryRecord(getRecordsResponse, identifier, messageToWrite); +// +// } +// //logger.info("Overrided "+override +" node/s"); +// return getRecordsResponse; +// } +// catch (Exception e) { +// logger.error("An error occurred during removing IDS by List: ", e); +// return getRecordsResponse; +// } +// } + /** * W3 c document to input stream. * @@ -393,7 +641,7 @@ public class GetResponseRecordFilter { * @param metadataName the metadata name * @return the metadata value by file identifier */ - private static String getMetadataValueByFileIdentifier(String fileIdentifier, String geonetworkURL, String user, String pwd, String metadataName){ + public static String getMetadataValueByFileIdentifier(String fileIdentifier, String geonetworkURL, String user, String pwd, String metadataName){ String response = requestXmlMetadataGet(fileIdentifier, geonetworkURL, user, pwd); @@ -421,6 +669,33 @@ public class GetResponseRecordFilter { } } + /** + * Prints the element. + * + * @param node the node + */ + public static void printElement(Element node){ + TransformerFactory transFactory = TransformerFactory.newInstance(); + Transformer transformer; + try { + transformer = transFactory.newTransformer(); + transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + //transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); + //transformer.transform(new DOMSource(node), new StreamResult(buffer)); + StreamResult result = new StreamResult(new StringWriter()); + DOMSource source = new DOMSource(node); + transformer.transform(source, result); + String xmlString = result.getWriter().toString(); + System.out.println("Element:" +xmlString); +// String str = buffer.toString(); +// System.out.println("Element: "+str); + }catch (TransformerException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + // /** // * The main method. // * diff --git a/src/main/java/org/gcube/datatransfer/resolver/gis/util/NamespaceContextMap.java b/src/main/java/org/gcube/datatransfer/resolver/gis/util/NamespaceContextMap.java new file mode 100644 index 0000000..f71abde --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/gis/util/NamespaceContextMap.java @@ -0,0 +1,195 @@ +/** + * + */ +package org.gcube.datatransfer.resolver.gis.util; + +/** + * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it + * @May 7, 2013 + * + */ +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import javax.xml.XMLConstants; +import javax.xml.namespace.NamespaceContext; + + +/** + * The Class NamespaceContextMap. + * + * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it + * Jan 22, 2016 + */ +public final class NamespaceContextMap implements NamespaceContext { + + private final Map prefixMap; + private final Map> nsMap; + + /** + * Constructor that takes a map of XML prefix-namespaceURI values. A + * defensive copy is made of the map. An IllegalArgumentException will be + * thrown if the map attempts to remap the standard prefixes defined in the + * NamespaceContext contract. + * + * @param prefixMappings + * a map of prefix:namespaceURI values + */ + public NamespaceContextMap(Map prefixMappings) { + prefixMap = createPrefixMap(prefixMappings); + nsMap = createNamespaceMap(prefixMap); + } + + /** + * Convenience constructor. + * + * @param mappingPairs + * pairs of prefix-namespaceURI values + */ + public NamespaceContextMap(String... mappingPairs) { + this(toMap(mappingPairs)); + } + + /** + * To map. + * + * @param mappingPairs the mapping pairs + * @return the map + */ + private static Map toMap(String... mappingPairs) { + Map prefixMappings = new HashMap( + mappingPairs.length / 2); + for (int i = 0; i < mappingPairs.length; i++) { + prefixMappings.put(mappingPairs[i], mappingPairs[++i]); + } + return prefixMappings; + } + + /** + * Creates the prefix map. + * + * @param prefixMappings the prefix mappings + * @return the map + */ + private Map createPrefixMap( + Map prefixMappings) { + Map prefixMap = new HashMap( + prefixMappings); + addConstant(prefixMap, XMLConstants.XML_NS_PREFIX, + XMLConstants.XML_NS_URI); + addConstant(prefixMap, XMLConstants.XMLNS_ATTRIBUTE, + XMLConstants.XMLNS_ATTRIBUTE_NS_URI); + return Collections.unmodifiableMap(prefixMap); + } + + /** + * Adds the constant. + * + * @param prefixMap the prefix map + * @param prefix the prefix + * @param nsURI the ns uri + */ + private void addConstant(Map prefixMap, String prefix, + String nsURI) { + String previous = prefixMap.put(prefix, nsURI); + if (previous != null && !previous.equals(nsURI)) { + throw new IllegalArgumentException(prefix + " -> " + previous + + "; see NamespaceContext contract"); + } + } + + /** + * Creates the namespace map. + * + * @param prefixMap the prefix map + * @return the map + */ + private Map> createNamespaceMap( + Map prefixMap) { + Map> nsMap = new HashMap>(); + for (Map.Entry entry : prefixMap.entrySet()) { + String nsURI = entry.getValue(); + Set prefixes = nsMap.get(nsURI); + if (prefixes == null) { + prefixes = new HashSet(); + nsMap.put(nsURI, prefixes); + } + prefixes.add(entry.getKey()); + } + for (Map.Entry> entry : nsMap.entrySet()) { + Set readOnly = Collections + .unmodifiableSet(entry.getValue()); + entry.setValue(readOnly); + } + return nsMap; + } + + /* (non-Javadoc) + * @see javax.xml.namespace.NamespaceContext#getNamespaceURI(java.lang.String) + */ + @Override + public String getNamespaceURI(String prefix) { + checkNotNull(prefix); + String nsURI = prefixMap.get(prefix); + return nsURI == null ? XMLConstants.NULL_NS_URI : nsURI; + } + + /* (non-Javadoc) + * @see javax.xml.namespace.NamespaceContext#getPrefix(java.lang.String) + */ + @Override + public String getPrefix(String namespaceURI) { + checkNotNull(namespaceURI); + Set set = nsMap.get(namespaceURI); + return set == null ? null : set.iterator().next(); + } + + /* (non-Javadoc) + * @see javax.xml.namespace.NamespaceContext#getPrefixes(java.lang.String) + */ + @Override + public Iterator getPrefixes(String namespaceURI) { + checkNotNull(namespaceURI); + Set set = nsMap.get(namespaceURI); + return set.iterator(); + } + + /** + * Check not null. + * + * @param value the value + */ + private void checkNotNull(String value) { + if (value == null) { + throw new IllegalArgumentException("null"); + } + } + + /** + * Gets the map. + * + * @return an unmodifiable map of the mappings in the form + * prefix-namespaceURI + */ + public Map getMap() { + return prefixMap; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("NamespaceContextMap [prefixMap="); + builder.append(prefixMap); + builder.append(", nsMap="); + builder.append(nsMap); + builder.append("]"); + return builder.toString(); + } +} \ No newline at end of file diff --git a/src/main/java/org/gcube/datatransfer/resolver/gis/util/NamespaceCsw.java b/src/main/java/org/gcube/datatransfer/resolver/gis/util/NamespaceCsw.java index f616391..e663942 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/gis/util/NamespaceCsw.java +++ b/src/main/java/org/gcube/datatransfer/resolver/gis/util/NamespaceCsw.java @@ -51,6 +51,15 @@ public class NamespaceCsw extends NamespaceISO19139 implements NamespaceContext } + /** + * @return the mapPrefix + */ + public Map getMapPrefix() { + + return mapPrefix; + } + + /* (non-Javadoc) * @see javax.xml.namespace.NamespaceContext#getNamespaceURI(java.lang.String) */ diff --git a/src/test/java/GeonetworkQueryTest.java b/src/test/java/GeonetworkQueryTest.java index 5096d05..e7ec5ef 100644 --- a/src/test/java/GeonetworkQueryTest.java +++ b/src/test/java/GeonetworkQueryTest.java @@ -24,28 +24,32 @@ public class GeonetworkQueryTest { private static final String UUID = "8a878105-ef06-4b1f-843f-120fc525b22b"; - //private String[] scopes = {"/gcube/devNext/NextNext"}; + private static String[] scopesProd = {"/gcube/devsec/devVRE"}; - //private String[] scopesProd = {"/d4science.research-infrastructures.eu/gCubeApps/SIASPA"}; + //private static String[] scopesProd = {"/d4science.research-infrastructures.eu/gCubeApps/SIASPA"}; //private String[] scopesProd = {"/d4science.research-infrastructures.eu/gCubeApps/fisheriesandecosystematmii"}; //private String[] scopesProd = {"/d4science.research-infrastructures.eu/D4Research"}; - private String[] scopesProd = {"/d4science.research-infrastructures.eu"}; + //private String[] scopesProd = {"/d4science.research-infrastructures.eu"}; //private String[] scopesProd = {"/d4science.research-infrastructures.eu/gCubeApps/FAO_TunaAtlas"}; //private String[] scopesProd = {"/d4science.research-infrastructures.eu/D4Research/Blue-Datathon"}; - private LoginLevel loginLevel = LoginLevel.CKAN; + private static LoginLevel loginLevel = LoginLevel.CKAN; - private Type accountType = Type.SCOPE; + //private static String[] scopesProd = {"/d4science.research-infrastructures.eu/gCubeApps/ICCAT_BFT-E"}; - private String textToSearch = "geo_fea"; - @Test - public void getCount() throws Exception{ + private static Type accountType = Type.SCOPE; + + private static String textToSearch = "geo_fea"; + + + //@Test + public static void getCount() throws Exception{ try{ for(String scope:scopesProd){ ScopeProvider.instance.set(scope); @@ -91,7 +95,7 @@ public class GeonetworkQueryTest { } } - //@Test + @Test public void getLayerByUUID() throws Exception{ try{ for(String scope:scopesProd){ @@ -228,4 +232,15 @@ public class GeonetworkQueryTest { e.printStackTrace(); } } + + public static void main(String[] args) { + try { + getCount(); + } + catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } } diff --git a/src/test/java/GeonetworkResolverTest.java b/src/test/java/GeonetworkResolverTest.java index 5991c81..97adb26 100644 --- a/src/test/java/GeonetworkResolverTest.java +++ b/src/test/java/GeonetworkResolverTest.java @@ -1,17 +1,23 @@ -import java.io.ByteArrayInputStream; +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.FileReader; import java.io.IOException; import java.io.InputStream; +import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; +import org.apache.commons.io.IOUtils; import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.datatransfer.resolver.gis.geonetwork.FilterGetRecords; import org.gcube.datatransfer.resolver.gis.geonetwork.GeonetworkResolver; import org.gcube.datatransfer.resolver.gis.geonetwork.HTTPCallsUtils; +import org.gcube.datatransfer.resolver.gis.geonetwork.ReusableInputStream; import org.gcube.datatransfer.resolver.gis.util.GetResponseRecordFilter; import org.gcube.spatial.data.geonetwork.GeoNetwork; import org.gcube.spatial.data.geonetwork.GeoNetworkPublisher; @@ -19,29 +25,62 @@ import org.gcube.spatial.data.geonetwork.LoginLevel; import org.gcube.spatial.data.geonetwork.configuration.Configuration; import org.gcube.spatial.data.geonetwork.model.Account; import org.gcube.spatial.data.geonetwork.model.Account.Type; - +import org.w3c.dom.Document; /** * */ /** - * - * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it - * Sep 8, 2016 + * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it Sep 8, 2016 */ public class GeonetworkResolverTest { private static String scope = "/d4science.research-infrastructures.eu"; - private static LoginLevel loginLevel = LoginLevel.SCOPE; - private static Type accountType = Type.CKAN; + + public static String readFile(String cswQueyrFileName) throws FileNotFoundException{ + + String fileName = cswQueyrFileName; + +// //read file into stream, try-with-resources +// try (Stream stream = Files.lines(Paths.get(fileName))) { +// +// stream.forEach(System.out::println); +// +// } catch (IOException e) { +// e.printStackTrace(); +// } + + FileReader reportReader = new FileReader(fileName); + //Stream stream = reportBW.lines(); + StringWriter reader = new StringWriter(); + List list; + try (BufferedReader reportBW = new BufferedReader(reportReader)){ + + String line; + while ((line = reportBW.readLine()) != null) { + reader.append(line); + } + + }catch (Exception e) { + e.printStackTrace(); + } + + return reader.toString(); + } + + + + /** * The main method. * - * @param args the arguments - * @throws UnsupportedEncodingException the unsupported encoding exception + * @param args + * the arguments + * @throws UnsupportedEncodingException + * the unsupported encoding exception */ public static void main(String[] args) throws UnsupportedEncodingException { @@ -63,7 +102,7 @@ public class GeonetworkResolverTest { try{ HTTPCallsUtils httpUtils = new HTTPCallsUtils(); - String data =""; + //String data =""; ScopeProvider.instance.set(scope); GeoNetworkPublisher reader=GeoNetwork.get(); @@ -88,25 +127,45 @@ public class GeonetworkResolverTest { map.put(GeonetworkResolver.UUID, value); // data = ""+uuid+""; - data = "" + + /*data = "" + ""+ ""+uuid+"" + "full" + - ""; + "";*/ - byte[] byteArray = data.getBytes(); - InputStream response = httpUtils.post(gnCSWlURL, new ByteArrayInputStream(byteArray), contentType, map); + String cswQueryString = readFile("query_csw.xml"); + + System.out.println(cswQueryString); + + byte[] byteArray = cswQueryString.getBytes(); + //InputStream response = httpUtils.post(gnCSWlURL, new ByteArrayInputStream(byteArray), contentType, map); + + String resp = readFile("csw_response.xml"); + InputStream response = IOUtils.toInputStream(resp); // String respToString = IOUtils.toString(response); // System.out.println("Response returned by request: \n"+respToString); // InputStream responseToIs = IOUtils.toInputStream(respToString); - if(response!=null){ + + ReusableInputStream resResponse = new ReusableInputStream(response); + System.out.println("Get Records Response: "+IOUtils.toString(resResponse)); + + if(resResponse!=null){ try { - InputStream re = GetResponseRecordFilter.overrideResponseIdsByListIds(response, new ArrayList(), "Replaced UUID"); +// List publicIDS = new ArrayList(); + FilterGetRecords filterGetRecords = FilterGetRecords.getInstance(); +// publicIDS.add("000b8da6-eae6-4d91-808d-abbffdd12922"); +// publicIDS.add("0652120c0f5562c8805c03c12cc971fbf14b3d05"); +// publicIDS.add("fao-species-map-ojg"); +// publicIDS.add("fao-species-map-sip"); + + Document doc = GetResponseRecordFilter.inputStreamToW3CDocument(resResponse); + doc = GetResponseRecordFilter.overrideResponseIdsByListIds(doc, filterGetRecords.getFoundPublicIds(), "Replaced UUID"); + InputStream re = GetResponseRecordFilter.w3CDocumentToInputStream(doc); // String theString = IOUtils.toString(re); // System.out.println("Response returned after overriding: \n"+theString); @@ -123,6 +182,5 @@ public class GeonetworkResolverTest { // TODO Auto-generated catch block e1.printStackTrace(); } - } } diff --git a/test.xml b/test.xml deleted file mode 100644 index 3a516a6..0000000 --- a/test.xml +++ /dev/null @@ -1,514 +0,0 @@ - - - - - c15ae8e5-71c0-4b8b-aa29-304cc4e97238 - - - English - - - UTF-8 - - - Dataset - - - - - fabio.sinibaldi - - - iMarine Consortium - - - Author - - - - - - - iMarine Consortium - - - iMarine.eu - - - - - - - info@i-marine.eu - - - - - - - http://www.i-marine.eu - - - WWW:LINK-1.0-http--link - - - - - - - Distributor - - - - - - - iMarine Consortium Technical Support - - - iMarine.eu - - - - - - - support@i-marine.eu - - - - - - - http://www.i-marine.eu - - - WWW:LINK-1.0-http--link - - - - - - - Resource provider - - - - - 2013-06-19T06:28:12.340+02:00 - - - - - Geometry only - - - - - Surface - - - 130 - - - - - - - - - - - Farfantepenaeus paulensis - - - - - 2012-12-21T19:30:57.139+01:00 - - - Creation - - - - - Map digital - - - - - This Farfantepenaeus paulensis Species Distribution Map has been generated with the AquaMaps methodology by exploiting the technology and the computational resources provided by iMarine. In particular, this map has been produced using the HSPEC 2050 Native Range dataset, generated using AquaMaps NativeRange2050 algorithm. - - - The aim of this Species Distribution map is to provide its users with a model-based map displaying prediction of species distributions based on occurrence records. - - - This layer has been produced by iMarine (www.i-marine.eu). iMarine (283644) is funded by the European Commission under Framework Programme 7 - - - Kaschner, K., J. S. Ready, E. Agbayani, J. Rius, K. Kesner-Reyes, P. D. Eastwood, A. B. South, S. O. Kullander, T. Rees, C. H. Close, R. Watson, D. Pauly, and R. Froese. 2008 AquaMaps: Predicted range maps for aquatic species. World wide web electronic publication, www.aquamaps.org, Version 10/2008. - - - - - As needed - - - - - - - http://node49.p.d4science.research-infrastructures.eu:9003/83/Animalia/Arthropoda/Malacostraca/Decapoda/Penaeidae/ITS-551576/Earth.jpg - - - - - - - São Paulo shrimp - - - Theme - - - - - FISHBASE - - - - - 2013-06-18T18:06:55.662+02:00 - - - Creation - - - - - - - FISHBASE - - - IFM-GEOMAR - - - - - - - http://www.fishbase.org/search.php - - - - - - - Point of contact - - - - - FishBase is a global species database of fish species (specifically finfish). - - - - - - - - - Farfantepenaeus paulensis - - - Theme - - - - - OBIS - - - - - 2013-06-18T18:06:55.662+02:00 - - - Creation - - - - - - - OBIS - - - UNESCO - - - - - - - http://www.iobis.org - - - - - - - Point of contact - - - - - Intergovernmental Oceanographic Commission (IOC) of UNESCO. The Ocean Biogeographic Information System. Web. http://www.iobis.org. (Consulted on DATE) - - - - - - - - - Ecological niche modelling - - - AquaMaps - - - SpeciesDistribution - - - iMarine - - - Theme - - - - - General - - - - - 2013-06-19T06:28:12.340+02:00 - - - Creation - - - - - - - - - - - 0.5 - - - - - English - - - biota - - - - - - - true - - - -180.0 - - - 180.0 - - - -90.0 - - - 90.0 - - - - - - - - - - - - - WMS - - - 1.1.0 - - - - - - - WFS - - - 1.1.0 - - - - - - - WCS - - - 1.0.0 - - - - - - - - - http://geoserver4.d4science.research-infrastructures.eu/geoserver/wms?service=wms&version=1.1.0&request=GetMap&layers=lfarfantepenaeuspaulensis20121221193002924cet&styles=&bbox=-180,-90,180,90&width=676&height=330&srs=EPSG:4326&crs=EPSG:4326&format=application/openlayers - - - OGC:WMS-1.3.0-http-get-map - - - lfarfantepenaeuspaulensis20121221193002924cet - - - - - - - http://geoserver4.d4science.research-infrastructures.eu/geoserver/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=lfarfantepenaeuspaulensis20121221193002924cet&format=json - - - OGC:WFS-1.0.0-http-get-feature - - - lfarfantepenaeuspaulensis20121221193002924cet - - - - - - - http://geoserver4.d4science.research-infrastructures.eu/geoserver/wms?service=wms&version=1.1.0&request=GetMap&layers=lfarfantepenaeuspaulensis20121221193002924cet&styles=&bbox=-180,-90,180,90&width=676&height=330&srs=EPSG:4326&crs=EPSG:4326&format=application/openlayers - - - OGC:WMS-1.3.0-http-get-map - - - lfarfantepenaeuspaulensis20121221193002924cet - - - - - - - - - - - - - Dataset - - - - - - - Kaschner, K., J. S. Ready, E. Agbayani, J. Rius, K. Kesner-Reyes, P. D. Eastwood, A. B. South, S. O. Kullander, T. Rees, C. H. Close, R. Watson, D. Pauly, and R. Froese. 2008 AquaMaps: Predicted range maps for aquatic species. World wide web electronic publication, www.aquamaps.org, Version 10/2008. - - - - - AquaMaps Ecological Niche Modelling - - - - - - - - - HSPEC 2050 Native Range - - - - - 2011-10-05T00:39:17.101+02:00 - - - Creation - - - - - - - hspec2011_10_04_21_00_23_274 - - - - - - - - - - - true - - - -180.0 - - - 180.0 - - - -90.0 - - - 90.0 - - - - - - - - - - - - - - - CC-BY-SA - - - License - - - License - - - - -