Reputation: 23
I have successfully created a dataStore using Rest API. There are no issues when I create a layer using GeoServer web panel. But I am unable to create the same layer using Rest API.
Workspace and store name is "test" and "gis_osm_adminareas_a_07_1" respectively.
Store is of type "Shapefile" and points to a ".shp" file. There are also ".dbf", ".prj" and ".shx" files sharing the same base name at the same location with said ".shp" file. ogrinfo -al -so gis_osm_adminareas_a_07_1.shp
command correctly analyzes and gives shapefile related information.
Here is the URL and post body I am using:
URL: {{host}}/geoserver/rest/workspaces/test/datastores/gis_osm_adminareas_a_07_1/featuretypes
Body:
{
"featureType":
{
"name": "gis_osm_adminareas_a_07_1",
"title": "gis_osm_adminareas_a_07_1",
"enabled": true,
"store":
{
"@class": "dataStore",
"name": "test:gis_osm_adminareas_a_07_1"
},
"attributes":
{
"attribute":
[
{
"name": "the_geom",
"minOccurs": 0,
"maxOccurs": 1,
"nillable": true,
"binding": "org.locationtech.jts.geom.MultiPolygon" // also tried "org.locationtech.jts.geom.Polygon" here
},
{
"name": "osm_id",
"minOccurs": 0,
"maxOccurs": 1,
"nillable": true,
"binding": "java.lang.String",
"length": 10
},
{
"name": "lastchange",
"minOccurs": 0,
"maxOccurs": 1,
"nillable": true,
"binding": "java.lang.String",
"length": 20
},
{
"name": "code",
"minOccurs": 0,
"maxOccurs": 1,
"nillable": true,
"binding": "java.lang.Integer",
"length": 4
},
{
"name": "fclass",
"minOccurs": 0,
"maxOccurs": 1,
"nillable": true,
"binding": "java.lang.String",
"length": 28
},
{
"name": "geomtype",
"minOccurs": 0,
"maxOccurs": 1,
"nillable": true,
"binding": "java.lang.String",
"length": 10
},
{
"name": "postalcode",
"minOccurs": 0,
"maxOccurs": 1,
"nillable": true,
"binding": "java.lang.String",
"length": 10
},
{
"name": "name",
"minOccurs": 0,
"maxOccurs": 1,
"nillable": true,
"binding": "java.lang.String",
"length": 100
}
]
}
}
}
Operation fails with a 500 internal server error with no error information sent back in response body. But the stack trace appears in the logs. Here is the relevant part of the error log:
ERROR [geoserver.rest] -
java.lang.NullPointerException
at org.geoserver.catalog.impl.FeatureTypeValidator.validate(FeatureTypeValidator.java:40)
at org.geoserver.catalog.impl.CatalogImpl.validate(CatalogImpl.java:515)
at org.geoserver.security.SecureCatalogImpl.validate(SecureCatalogImpl.java:1320)
at org.geoserver.catalog.impl.AbstractFilteredCatalog.validate(AbstractFilteredCatalog.java:633)
at org.geoserver.catalog.impl.AbstractCatalogDecorator.validate(AbstractCatalogDecorator.java:274)
at org.geoserver.rest.catalog.FeatureTypeController.featureTypePost(FeatureTypeController.java:280)
I have tried many different combinations of post body to no success. I have also tried copying the "resource.json" created when layer is created using the web panel and sending it to featureType endpoint which did not work either.
Any help is appreciated. Thanks!
Update
Store was created using the following URL and post body
URL: POST {{host}}/workspaces/test/datastores
Body:
{
"dataStore":
{
"workspace": "test",
"enabled": true,
"name": "gis_osm_adminareas_a_07_1",
"nativeName": "gis_osm_adminareas_a_07_1.shp",
"connectionParameters":
{
"entry":
[
{
"@key": "filetype",
"$": "shapefile"
},
{
"@key": "create spatial index",
"$": "true"
},
{
"@key": "url",
"$": "file:///geoserver/uploads/6b82db8f-427c-4f07-9c89-e95ae6413732/gis_osm_adminareas_a_07_1.shp"
},
{
"@key": "enable spatial index",
"$": "true"
},
{
"@key": "charset",
"$": "ISO-8859-1"
},
{
"@key": "memory mapped buffer",
"$": "false"
},
{
"@key": "timezone",
"$": "GMT"
},
{
"@key": "namespace",
"$": "http://test"
},
{
"@key": "cache and reuse memory maps",
"$": "false"
},
{
"@key": "fstype",
"$": "shape"
}
]
},
"type": "Shapefile"
}
}
Upvotes: 0
Views: 841
Reputation: 23
Adding an empty "metadata.entry" array to request body seems to fix the issue. Here is the offending line of code in GeoServer:
fti.getMetadata().get(FeatureTypeInfo.JDBC_VIRTUAL_TABLE, VirtualTable.class);
I believe the get
method fails because getMetadata
method of fti
(which corresponds to featureType
field sent with request) returns a null pointer. Hence the java.lang.NullPointerException
mentioned in the question is raised.
Issue occurs when dataStore and featureType is created using two different requests
POST workspaces/{workspace}/datastores
POST workspaces/{workspace}/datastores/{datastore}/featuretypes
PUT workspaces/{workspace}/datastores/{datastore}/file.shp?filename={datastore}&update=overwrite
PUT
method.If using a single request is out of question, here is the steps taken to create the layer with pieces of related PHP code:
Let's assume you somehow managed to copy the shapefile to /opt/geoserver/data_dir/data/{workspace}/gis_osm_adminareas_a_07_1/gis_osm_adminareas_a_07_1.shp
with associated ".dbf", ".shx" and ".prj" files.
# HTTP request is made using Guzzle [https://github.com/guzzle/guzzle]
$this->client->post("workspaces/$this->workspace/datastores", [
'json' => [
'dataStore' => [
'name' => $name,
'connectionParameters' => [
'entry' => [
[
'@key' => 'url',
'$' => "file://$resource_path"
]
]
],
'type' => 'Shapefile'
]
]
]);
# HTTP request is made using Guzzle [https://github.com/guzzle/guzzle]
$this->client->post("workspaces/$this->workspace/datastores/$store/featuretypes", [
'json' => [
'featureType' => [
'name' => $store,
'title' => $name,
"metadata" => [
"entry" => []
],
'attributes' => [
'attribute' => [
[
"name" => "the_geom",
"minOccurs" => 0,
"maxOccurs" => 1,
"nillable" => true,
"binding" => "org.locationtech.jts.geom.MultiPolygon"
]
]
]
]
]
]);
Upvotes: 0