-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace Layer for raster creates a new dataset intead of replace the previous one #329
Comments
@aaime is gs_importer's REPLACE method supposed to work the same for feature types and coverages? The documentation doesn't tell anything in this regard. |
I just want to add that this could be useful. |
As a summary:
I'm guessing it's somewhere between 1 and 2 days of work. |
@aaime given the estimate I would do it. Could you open an issue for the implementation? |
@giohappy whoever implements the code will open a Jira ticket for it. About the cleanup, it should be optional. A few thoughts about it:
|
fine @nmco thanks |
My apologizes for the delay on this @giohappy.
Implementation aspect:
I'm not that match expert neither of raster data neither of the importer so If I've to do the task I would need around 2,5 days to be on safe side. |
ok @taba90 let's do it. Esitmated delivery? |
@dromagnoli will work on this, ETA 1st of APRIL, wors case 6th of April. We are targeting GeoServer 2.20.x, branch we need to check where this would land. |
Hi @mattiagiupponi, @giohappy Could you please provide me some steps (and eventually a few samples) to replicate the issue?
So I can start full speed on Monday. Thanks |
Hi @dromagnoli |
Hi @giohappy. any comment on this? |
@dromagnoli as we spoke on the chat the way GeoNode executes the import is:
|
Hi @giohappy. Thanks i.e. |
@dromagnoli I suppose yes. This was the proposal from @aaime and @taba90 |
Hi @giohappy, after some sync up with Andrea it turned out that the javadoc for class UpdateMode.REPLACE says: The target DataStore will be removed and replaced with the specified input. And REST documentation states that again: Changing it to “REPLACE” instead will preserve the layer, but remove the old contents and replace them with the newly uploaded ones So we were wondering if we actually need the purge parameter or we can just remove the old content for consistency. Also note that the nativeName of a layer is based on the file name itself so in order to have same names for the layer we also need to have same file in input. When replacing a file in a store, we are going to send the same file name of the original store right? (eventually with a different content... i.e. the previous file has been badly preprocessed and we want just to update the content) |
@dromagnoli I agree that purge is redundant. Regarding the file name let's hear @mattiagiupponi, but I think it's ok to assume the same name. |
It's ok, already from UI we force the user to use the same filename |
Hi guys. reading the documentation: However, I think that for rasters, when dealing with the Structured GridCoverageReader (i.e. ImageMosaic) the behaviour should keep using the harvesting path. So that when sending a new file (even using a REPLACE) only that file will affect the ImageMosaic update. I think that it could be very dangerous and unexpected if a REPLACE of a data file into an ImageMosaic layer would do the remove of everything else but the new data. Do you agree? |
Definetely @dromagnoli. The full replace is meant only for single coverages. |
@giohappy, @mattiagiupponi while waiting for the PR review, here, a testing jar based on GS 2.19.x to early testing of the functionality |
@dromagnoli as agreed with @simboss we want to backport this to 2.18.x. |
The PR has been merged to main. |
@dromagnoli @giohappy The importer session is the following: {
"task": {
"id": 0,
"href": "http://localhost:8080/geoserver/rest/imports/379/tasks/0",
"state": "ERROR",
"updateMode": "REPLACE",
"data": {
"type": "file",
"format": "GeoTIFF",
"file": "csdi_r1_p1.tif"
},
"target": {
"href": "http://localhost:8080/geoserver/rest/imports/379/tasks/0/target",
"coverageStore": {
"name": "csdi_r1_p1",
"type": "GeoTIFF"
}
},
"progress": "http://localhost:8080/geoserver/rest/imports/379/tasks/0/progress",
"layer": {
"name": "csdi_r1_p1",
"href": "http://localhost:8080/geoserver/rest/imports/379/tasks/0/layer"
},
"errorMessage": "java.io.FileNotFoundException: /opt/data/geoserver_data/geonode/importer_data/tmp6134601418283653642/csdi_r1_p1.tif (No such file or directory)\n/opt/data/geoserver_data/geonode/importer_data/tmp6134601418283653642/csdi_r1_p1.tif (No such file or directory)",
"transformChain": {
"type": "raster",
"transforms": [
]
}
}
} Attach the geoserver.log with the error raised. This is the XML provided by the WMS service when clicking on the Layer Preview: <?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE ServiceExceptionReport SYSTEM "http://localhost:8080/geoserver/schemas/wms/1.1.1/WMS_exception_1_1_1.dtd">
<ServiceExceptionReport version="1.1.1" >
<ServiceException>
java.lang.IllegalArgumentException: java.io.FileNotFoundException: /opt/data/geoserver_data/geonode/importer_data/tmp6134601418283653642/csdi_r1_p1.tif (No such file or directory)
java.io.FileNotFoundException: /opt/data/geoserver_data/geonode/importer_data/tmp6134601418283653642/csdi_r1_p1.tif (No such file or directory)
/opt/data/geoserver_data/geonode/importer_data/tmp6134601418283653642/csdi_r1_p1.tif (No such file or directory)
</ServiceException>
</ServiceExceptionReport> |
I made another test, it looks like that GeoServer keeps the file path as a new source for the Tiff image, if deleted it raises an error. Test: {
"task": {
"id": 0,
"href": "http://localhost:8080/geoserver/rest/imports/380/tasks/0",
"state": "COMPLETE",
"updateMode": "CREATE",
"data": {
"type": "file",
"format": "GeoTIFF",
"file": "cwd_r1_p1.tif"
},
"target": {
"href": "http://localhost:8080/geoserver/rest/imports/380/tasks/0/target",
"coverageStore": {
"name": "cwd_r1_p1",
"type": "GeoTIFF"
}
},
"progress": "http://localhost:8080/geoserver/rest/imports/380/tasks/0/progress",
"layer": {
"name": "cwd_r1_p1",
"href": "http://localhost:8080/geoserver/rest/imports/380/tasks/0/layer"
},
"transformChain": {
"type": "raster",
"transforms": [
]
}
}
} On the GeoServer data dir, the tiff file is present:
Step 2 - Replace Layer GeoServer importer say that everything is fine {
"task": {
"id": 0,
"href": "http://localhost:8080/geoserver/rest/imports/381/tasks/0",
"state": "COMPLETE",
"updateMode": "REPLACE",
"data": {
"type": "file",
"format": "GeoTIFF",
"file": "cwd_r1_p1.tif"
},
"target": {
"href": "http://localhost:8080/geoserver/rest/imports/381/tasks/0/target",
"coverageStore": {
"name": "cwd_r1_p1",
"type": "GeoTIFF"
}
},
"progress": "http://localhost:8080/geoserver/rest/imports/381/tasks/0/progress",
"layer": {
"name": "cwd_r1_p1",
"href": "http://localhost:8080/geoserver/rest/imports/381/tasks/0/layer"
},
"transformChain": {
"type": "raster",
"transforms": [
]
}
}
} The Image is deleted from the geoserver data_dir
|
@mattiagiupponi I asked @aaime to double check this as @dromagnoli is busy with a training. @aaime might check with you to make sure the expectations are right. |
@dromagnoli as requested follows the call made by GeoNode as
Follows a python example to upload a file: import requests
url = 'http://localhost:8080/geoserver/rest/imports/387/tasks?expand=3'
data = '------------ThIs_Is_tHe_bouNdaRY_$\r\nContent-Disposition: form-data; name="/opt/core/geonode/geonode/uploaded/tmp14_mbefq/test_grid.tif"; filename="test_grid.tif"\r\nContent-Type: image/tiff\r\n\r\nII*\x00\x08\x00\x00\x00\x10\x00\x00\x01\x03\x00\x01\x00\x00\x00\x05\x00\x00\x00\x01\x01\x03\x00\x01\x00\x00\x00\x07\x00\x00\x00\x02\x01\x03\x00\x01\x00\x00\x00@\x00\x00\x00\x03\x01\x03\x00\x01\x00\x00\x00\x01\x00\x00\x00\x06\x01\x03\x00\x01\x00\x00\x00\x01\x00\x00\x00\x11\x01\x04\x00\x01\x00\x00\x00t\x01\x00\x00\x15\x01\x03\x00\x01\x00\x00\x00\x01\x00\x00\x00\x16\x01\x03\x00\x01\x00\x00\x00\x07\x00\x00\x00\x17\x01\x04\x00\x01\x00\x00\x00\x18\x01\x00\x00\x1c\x01\x03\x00\x01\x00\x00\x00\x01\x00\x00\x00S\x01\x03\x00\x01\x00\x00\x00\x03\x00\x00\x00\x0e\x83\x0c\x00\x03\x00\x00\x00Î\x00\x00\x00\x82\x84\x0c\x00\x06\x00\x00\x00æ\x00\x00\x00¯\x87\x03\x00 \x00\x00\x00\x16\x01\x00\x00°\x87\x0c\x00\x02\x00\x00\x00V\x01\x00\x00±\x87\x02\x00\x0e\x00\x00\x00f\x01\x00\x00\x00\x00\x00\x00$Ó\x18â\x95z\x9f?$Ó\x18â\x95z\x9f?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00w¾\x9f\x1a/=X@L¾*¥Ô6\x15À\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x00\x00\x00\x07\x00\x00\x04\x00\x00\x01\x00\x02\x00\x01\x04\x00\x00\x01\x00\x01\x00\x00\x08\x00\x00\x01\x00æ\x10\x01\x08±\x87\r\x00\x00\x00\x06\x08\x00\x00\x01\x00\x8e#\t\x08°\x87\x01\x00\x01\x00\x0b\x08°\x87\x01\x00\x00\x00\x88mt\x96\x1d¤r@\x00\x00\x00@¦TXAGCS_WGS_1984|\x00\x00\x00\x00àHhI@\x00\x00\x00@\x94>I@\x00\x00\x00\x00_=I@\x00\x00\x00ÀY\nI@\x00\x00\x00 £\x16I@\x00\x00\x00\x00\x00\x00\x08@\x00\x00\x00\x00\x80\x87ÃÀ\x00\x00\x00\x00\x80\x87ÃÀ\x00\x00\x00\x00\x80\x87ÃÀ\x00\x00\x00\x80\x8bzI@\x00\x00\x00 A\x10I@\x00\x00\x00@ùLIÀ\x00\x00\x00@¹EI@\x00\x00\x00\x80ÛsI@\x00\x00\x00 ö!I@\x00\x00\x00\x80étI@\x00\x00\x00\x00\x00\x00.À\x00\x00\x00 ÛRI@\x00\x00\x00\xa0RDI@\x00\x00\x00\xa0XvI@\x00\x00\x00 ñPI@\x00\x00\x00 \x08/I@\x00\x00\x00\x00\x9eEI@\x00\x00\x00\x00\x80\x87ÃÀ\x00\x00\x00\x80¤\x1cI@\x00\x00\x00\x00\x80\x87ÃÀ\x00\x00\x00@v~I@\x00\x00\x00@K\\I@\x00\x00\x00 ´iI@\x00\x00\x00\x00Ñ/I@\x00\x00\x00à¥#I@\x00\x00\x00\xa0Ô\x04I@\x00\x00\x00 áBI@\x00\x00\x00ÀF+I@\x00\x00\x00@3\x0bI@\r\n------------ThIs_Is_tHe_bouNdaRY_$--\r\n'
headers = {'Content-Type': 'multipart/form-data; boundary=----------ThIs_Is_tHe_bouNdaRY_$'}
response = requests.post(url, data=data, headers=headers, auth=('admin', 'geoserver'))
print(response.status_code) |
Tentative fix doing a copy of the data file so that the replacing file is internally stored in the dedicated GeoServer datadir/importer uploads folder. If it's still not working as you expect, please make sure to provide sample calls to be sent via POST against GeoServer to exactly simulate the rest calls made by GeoNode / python scripts. Calls including import creation, data upload and data replace. |
@dromagnoli @giohappy @etj
Example:
When running the "Replace", a new file is uploaded and the one created during the upload phase is persisted:
NB: if I run another replace, the file is correctly substituted |
After final internal sync up on Friday, it looks like it's working as expected. Starting backports |
@dromagnoli @mattiagiupponi what about the replace not removing the original file? Did you solve it somehow? |
was an issue related to my local environment. I clean-up my local env, retry the replace, and worked as expected |
I'm trying to use the GeoServer importer to replace an existing raster layer.
![image](https://user-images.githubusercontent.com/51856725/157706016-3c9418c4-342a-41eb-a509-7bccd8b0e2a6.png)
GeoServer UI:
The importer session is correctly created:
But when the import is completed, I'm expecting to have my current layer replaced, instead a new one is added:
![image](https://user-images.githubusercontent.com/51856725/157706170-ed002c01-7101-4f85-9ebe-1e8f5e333c75.png)
Note the store and the layer name
Geoserver UI:
importer:
The only information that I have from the logs is an error related to the
SecuredLayerInfo
NOTE: Instead, the same approach works smoothly with vector datasets
cc: @afabiani @giohappy
The text was updated successfully, but these errors were encountered: