Skip to content

Commit

Permalink
[Fixes #232] Cannot overwrite raster files (#238)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattiagiupponi committed May 3, 2024
1 parent 658a825 commit a9d74ee
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 13 deletions.
1 change: 0 additions & 1 deletion importer/celery_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,6 @@ def publish_resource(
_files = _exec.input_params.get("files")
_overwrite = _exec.input_params.get("overwrite_existing_layer")

# for now we dont heve the overwrite option in GS, skipping will we talk with the GS team
_publisher = DataPublisher(handler_module_path)

# extracting the crs and the resource name, are needed for publish the resource
Expand Down
17 changes: 14 additions & 3 deletions importer/handlers/common/raster.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ def default_geometry_column_name(self):
def supported_file_extension_config(self):
return NotImplementedError

@staticmethod
def get_geoserver_store_name(default=None):
"""
Method that return the base store name where to save the data in geoserver
and a boolean to know if the store should be created.
For raster, the store is created during the geoserver publishing
so we dont want to created it upfront
"""
return default, False

@staticmethod
def is_valid(files, user):
"""
Expand Down Expand Up @@ -195,8 +205,6 @@ def perform_last_step(execution_id):

_exec = orchestrator.get_execution_object(execution_id)



_exec.output_params.update(
**{
"detail_url": [
Expand Down Expand Up @@ -299,7 +307,10 @@ def import_resource(self, files: dict, execution_id: str, **kwargs) -> str:
dataset_exists = user_datasets.exists()

if dataset_exists and should_be_overwritten:
layer_name, alternate = layer_name, user_datasets.first().alternate
layer_name, alternate = (
layer_name,
user_datasets.first().alternate.split(":")[-1],
)
elif not dataset_exists:
alternate = layer_name
else:
Expand Down
9 changes: 9 additions & 0 deletions importer/handlers/common/vector.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ def default_geometry_column_name(self):
def supported_file_extension_config(self):
return NotImplementedError

@staticmethod
def get_geoserver_store_name(default=None):
"""
Method that return the base store name where to save the data in geoserver
and a boolean to know if the store should be created.
For vector, the store must be created
"""
return os.environ.get("GEONODE_GEODATABASE", "geonode_data"), True

@staticmethod
def is_valid(files, user):
"""
Expand Down
35 changes: 26 additions & 9 deletions importer/publisher.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ def __init__(self, handler_module_path) -> None:
)
self.workspace = self._get_default_workspace(create=True)

self.store = None

if handler_module_path is not None:
self.handler = import_string(handler_module_path)()

Expand All @@ -50,7 +52,7 @@ def extract_resource_to_publish(
)

def get_resource(self, resource_name, return_bool=True) -> bool:
self.get_or_create_store()
self.get_or_create_store(default=resource_name)
_res = self.cat.get_resource(
resource_name, store=self.store, workspace=self.workspace
)
Expand All @@ -63,7 +65,7 @@ def publish_resources(self, resources: List[str]):
Given a list of strings (which rappresent the table on geoserver)
Will publish the resorces on geoserver
"""
self.get_or_create_store()
self.get_or_create_store(default=resources[0]["name"])
result = self.handler.publish_resources(
resources=resources,
catalog=self.cat,
Expand All @@ -77,8 +79,8 @@ def overwrite_resources(self, resources: List[str]):
"""
We dont need to do anything for now. The data is replaced via ogr2ogr
"""
self.get_or_create_store()
for _resource in resources:
self.get_or_create_store(default=_resource["name"])
result = self.handler.overwrite_geoserver_resource(
resource=_resource,
catalog=self.cat,
Expand Down Expand Up @@ -108,16 +110,31 @@ def delete_resource(self, resource_name):
if store:
self.cat.delete(store, purge="all", recurse=True)

def get_or_create_store(self):
def get_or_create_store(self, default=None):
"""
Evaluate if the store exists. if not is created
"""
geodatabase = os.environ.get("GEONODE_GEODATABASE", "geonode_data")
self.store = self.cat.get_store(name=geodatabase, workspace=self.workspace)
store_name, to_be_created = self.handler.get_geoserver_store_name(
default=default
)

if self.store and self.store.name == store_name:
# if we already initialize the store, we can skip the checks
return self.store

if store_name is not None and not to_be_created:
# If the store name is provided by the handler, we retrieve the store
# from geoserver. This is usually used for raster layers
# for raster we dont want to create the store upfront since the pulishing
# is going to create it
self.store = self.cat.get_store(name=store_name, workspace=self.workspace)
return

self.store = self.cat.get_store(name=store_name, workspace=self.workspace)
if not self.store:
logger.warning(f"The store does not exists: {geodatabase} creating...")
logger.warning(f"The store does not exists: {store_name} creating...")
self.store = create_geoserver_db_featurestore(
store_name=geodatabase, workspace=self.workspace.name
store_name=store_name, workspace=self.workspace.name
)

def publish_geoserver_view(
Expand All @@ -126,7 +143,7 @@ def publish_geoserver_view(
"""
Let the handler create a geoserver view given the input parameters
"""
self.get_or_create_store()
self.get_or_create_store(default=layer_name)

return self.handler.publish_geoserver_view(
catalog=self.cat,
Expand Down
43 changes: 43 additions & 0 deletions importer/tests/end2end/test_end2end.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def setUpClass(cls) -> None:
"shx_file": f"{file_path}/san_andres_y_providencia_highway.shx",
}
cls.valid_kml = f"{project_dir}/tests/fixture/valid.kml"
cls.valid_tif = f"{project_dir}/tests/fixture/test_grid.tif"

cls.url = reverse("importer_upload")
ogc_server_settings = OGC_Servers_Handler(settings.OGC_SERVER)["default"]
Expand Down Expand Up @@ -338,3 +339,45 @@ def test_import_shapefile_overwrite(self):
layer = self.cat.get_layer("geonode:san_andres_y_providencia_highway")
if layer:
self.cat.delete(layer)


class ImporterRasterImportTest(BaseImporterEndToEndTest):
@mock.patch.dict(os.environ, {"GEONODE_GEODATABASE": "test_geonode_data"})
@override_settings(
GEODATABASE_URL=f"{geourl.split('/geonode_data')[0]}/test_geonode_data"
)
def test_import_raster(self):
layer = self.cat.get_layer("test_grid")
if layer:
self.cat.delete(layer)

payload = {
"base_file": open(self.valid_tif, "rb"),
}
initial_name = "test_grid"
self._assertimport(payload, initial_name)
layer = self.cat.get_layer("test_grid")
if layer:
self.cat.delete(layer)

@mock.patch.dict(os.environ, {"GEONODE_GEODATABASE": "test_geonode_data"})
@override_settings(
GEODATABASE_URL=f"{geourl.split('/geonode_data')[0]}/test_geonode_data"
)
def test_import_raster_overwrite(self):
prev_dataset = create_single_dataset(name="test_grid")

layer = self.cat.get_layer("test_grid")
if layer:
self.cat.delete(layer)
payload = {
"base_file": open(self.valid_tif, "rb"),
}
initial_name = "test_grid"
payload["overwrite_existing_layer"] = True
self._assertimport(
payload, initial_name, overwrite=True, last_update=prev_dataset.last_updated
)
layer = self.cat.get_layer("test_grid")
if layer:
self.cat.delete(layer)

0 comments on commit a9d74ee

Please sign in to comment.