Package: geoserver-restconfig
geoserver-restconfiggeoserver-restconfigis a python library for manipulating a GeoServer instance via the GeoServer RESTConfig API.Note:geoserver-restconfig is a fork of the oldhttps://travis-ci.org/boundlessgeo/gsconfigThe project is distributed under aMIT License.Installingpipinstallgeoserver-restconfigFor developers:gitclonegit@github.com:geosolutions-it/geoserver-restconfig.gitcdgeoserver-restconfigpythonsetup.pydevelopGetting HelpThere is a brief manual athttp://geonode.org/geoserver-restconfig/.
If you have questions, please ask them on the GeoServer Users mailing list:http://geoserver.org/.Please use the Github project athttp://github.com/geosolutions-it/geoserver-restconfigfor any bug reports (and pull requests are welcome, but please include tests where possible.)Sample Layer Creation Codefromgeoserver.catalogimportCatalogcat=Catalog("http://localhost:8080/geoserver/rest")topp=cat.get_workspace("topp")shapefile_plus_sidecars=shapefile_and_friends("states")# shapefile_and_friends should look on the filesystem to find a shapefile# and related files based on the base path passed in## shapefile_plus_sidecars == {#    'shp': 'states.shp',#    'shx': 'states.shx',#    'prj': 'states.prj',#    'dbf': 'states.dbf'# }# 'data' is required (there may be a 'schema' alternative later, for creating empty featuretypes)# 'workspace' is optional (GeoServer's default workspace is used by... default)# 'name' is requiredft=cat.create_featurestore(name,workspace=topp,data=shapefile_plus_sidecars)Running TestsSince the entire purpose of this module is to interact with GeoServer, the test suite is mostly composed ofintegration tests.
These tests necessarily rely on a running copy of GeoServer, and expect that this GeoServer instance will be using the default data directory that is included with GeoServer.
This data is also included in the GeoServer source repository as/data/release/.
In addition, it is expected that there will be a postgres database available atpostgres:password@localhost:5432/db.
You can test connecting to this database with thepsqlcommand line client by running$ psql-ddb-Upostgres-hlocalhost-p5432(you will be prompted interactively for the password.)To override the assumed database connection parameters, the following environment variables are supported:DATABASEDBUSERDBPASSIf present, psycopg will be used to verify the database connection prior to running the tests.If provided, the following environment variables will be used to reset the data directory:GEOSERVER_HOMELocation of git repository to read the clean data from. If only this option is providedgit cleanwill be used to reset the data.GEOSERVER_DATA_DIROptional location of the data dir geoserver will be running with. If provided,rsyncwill be used to reset the data.GS_VERSIONOptional environment variable allowing the catalog test cases to automatically download
and start a vanilla GeoServer WAR form the web.
Be sure that there are no running services on HTTP port 8080.Here are the commands that I use to reset before running the geoserver-restconfig tests:$cd~/geoserver/src/web/app/$PGUSER=postgresdropdbdb$PGUSER=postgrescreatedbdb-Ttemplate_postgis$gitclean-dxff--../../../data/release/$gitcheckout-f$MAVEN_OPTS="-XX:PermSize=128M -Xmx1024M"\GEOSERVER_DATA_DIR=../../../data/release\mvnjetty:runAt this point, GeoServer will be running foregrounded, but it will take a few seconds to actually begin listening for http requests.
You can stop it withCTRL-C(but don’t do that until you’ve run the tests!)
You can run the geoserver-restconfig tests with the following command:$pythonsetup.pytestInstead of restarting GeoServer after each run to reset the data, the following should allow re-running the tests:$gitclean-dxff--../../../data/release/$curl-XPOST--useradmin:geoserverhttp://localhost:8080/geoserver/rest/reloadMore Examples - Updated for GeoServer 2.4+Loading the GeoServercatalogusinggeoserver-restconfigis quite easy. The example below allows you to connect to GeoServer by specifying custom credentials.fromgeoserver.catalogimportCatalogcat=Catalog("http://localhost:8080/geoserver/rest/","admin","geoserver")The code below allows you to filter which workspaces to returncat.get_workspaces(names="geosolutions,topp")You may also specify the workspaces as a proper listcat.get_workspaces(names=["geosolutions","topp"])The code below allows you to filter which stores to returncat.get_stores(names=["sf","mosaic"],workspaces=["nurc","topp","sf"])namesandworkspacescan either be a comma delimited string or a list.
This is true for theget_workspaces,get_stores,get_resources,get_layergroupsandget_styles.The code below allows you to create a FeatureType from a Shapefilegeosolutions=cat.get_workspace("geosolutions")importgeoserver.utilshapefile_plus_sidecars=geoserver.util.shapefile_and_friends("C:/work/geoserver-restconfig/test/data/states")# shapefile_and_friends should look on the filesystem to find a shapefile# and related files based on the base path passed in## shapefile_plus_sidecars == {#    'shp': 'states.shp',#    'shx': 'states.shx',#    'prj': 'states.prj',#    'dbf': 'states.dbf'# }# 'data' is required (there may be a 'schema' alternative later, for creating empty featuretypes)# 'workspace' is optional (GeoServer's default workspace is used by... default)# 'name' is requiredft=cat.create_featurestore("test",shapefile_plus_sidecars,geosolutions)It is possible to create JDBC Virtual Layers too. The code below allow to create a new SQL View calledmy_jdbc_vt_testdefined by a customsql.fromgeoserver.catalogimportCatalogfromgeoserver.supportimportJDBCVirtualTable,JDBCVirtualTableGeometry,JDBCVirtualTableParamcat=Catalog('http://localhost:8080/geoserver/rest/','admin','****')store=cat.get_store('postgis-geoserver')geom=JDBCVirtualTableGeometry('newgeom','LineString','4326')ft_name='my_jdbc_vt_test'epsg_code='EPSG:4326'sql='select ST_MakeLine(wkb_geometry ORDER BY waypoint) As newgeom, assetid, runtime from waypoints group by assetid,runtime'keyColumn=Noneparameters=Nonejdbc_vt=JDBCVirtualTable(ft_name,sql,'false',geom,keyColumn,parameters)ft=cat.publish_featuretype(ft_name,store,epsg_code,jdbc_virtual_table=jdbc_vt)The next example shows how to create aPostGIS JNDIdatastore (connection_parameters come from another example.
Settings might be different depending on your needs):cat=Catalog('http://localhost:8080/geoserver/rest/','admin','****')datastore_name='sample_jndi_store'dstore=cat.get_store(name=datastore_name,workspace=metadata[WS])# Let's check that the store doesn't already existifds_storeisNone:ws='my_workspace'dstore=cat.create_datastore(workspace=ws,name=datastore_name)connection_parameters={'type':'PostGIS (JNDI)','schema':'my_schema','Estimated extends':'true','fetch size':'1000','encode functions':'true','Expose primary keys':'false','Support on the fly geometry simplification':'true','Batch insert size':'1','preparedStatements':'false','Support on the fly geometry simplification, preserving topology':'true','jndiReferenceName':'java:comp/env/jdbc/geodb','dbtype':'postgis','namespace':'my_workspace','Loose bbox':'true'}dstore.connection_parameters.update(connection_parameters)cat.save(dstore)assertdstore.enabledreturndstoreThis example shows how to easily update alayerproperty. The same approach may be used with everycatalogresourcene_shaded=cat.get_layer("ne_shaded")ne_shaded.enabled=Truecat.save(ne_shaded)cat.reload()Deleting astorefrom thecatalogrequires to purge all the associatedlayersfirst. This can be done by doing something like this:st=cat.get_store("ne_shaded")cat.delete(ne_shaded)cat.reload()cat.delete(st)cat.reload()Alternatively, you can delete astoreas well as all the underlyinglayersin one shot, like this:store=cat.get_store("ne_shaded")cat.delete(store,purge=True,recurse=True)There are some functionalities allowing to manage theImageMosaiccoverages. It is possible to create new ImageMosaics, add granules to them,
and also read the coverages metadata, modify the mosaicDimensionsand finally query the mosaicgranulesand list their properties.The geoserver-restconfig methods map theREST APIs for ImageMosaicIn order to create a new ImageMosaic layer, you can prepare a zip file containing the properties files for the mosaic configuration. Refer to the GeoTools ImageMosaic Plugin guide
in order to get details on the mosaic configuration. The package contains an already configured zip file with two granules.
You need to update or remove thedatastore.propertiesfile before creating the mosaic otherwise you will get an exception.fromgeoserver.catalogimportCatalogcat=Catalog("http://localhost:8180/geoserver/rest")cat.create_imagemosaic("NOAAWW3_NCOMultiGrid_WIND_test","NOAAWW3_NCOMultiGrid_WIND_test.zip")By defualt thecat.create_imagemosaictries to configure the layer too. If you want to create the store only, you can specify the following parametercat.create_imagemosaic("NOAAWW3_NCOMultiGrid_WIND_test","NOAAWW3_NCOMultiGrid_WIND_test.zip","none")In order to retrieve from the catalog the ImageMosaic coverage store you can do thisstore=cat.get_store("NOAAWW3_NCOMultiGrid_WIND_test")It is possible to add more granules to the mosaic at runtime.
With the following method you can add granules already present on the machine local path.cat.add_granule("file://D:/Work/apache-tomcat-6.0.16/instances/data/data/MetOc/NOAAWW3/20131001/WIND/NOAAWW3_NCOMultiGrid__WIND_000_20131001T000000.tif",store.name,store.workspace.name)The method below allows to send granules remotely via POST to the ImageMosaic.
The granules will be uploaded and stored on the ImageMosaic index folder.cat.add_granule("NOAAWW3_NCOMultiGrid__WIND_000_20131002T000000.zip",store.name,store.workspace.name)To delete an ImageMosaic store, you can follow the standard approach, by deleting the layers first.ATTENTION: at this time you need to manually cleanup the data dir from the mosaic granules and, in case you used a DB datastore, you must also drop the mosaic tables.layer=cat.get_layer("NOAAWW3_NCOMultiGrid_WIND_test")cat.delete(layer)cat.reload()cat.delete(store)cat.reload()By default the ImageMosaic layer has not the coverage dimensions configured. It is possible using the coverage metadata to update and manage the coverage dimensions.ATTENTION: notice that thepresentationparameters accepts only one among the following values {‘LIST’, ‘DISCRETE_INTERVAL’, ‘CONTINUOUS_INTERVAL’}fromgeoserver.supportimportDimensionInfotimeInfo=DimensionInfo("time","true","LIST",None,"ISO8601",None)coverage.metadata=({'dirName':'NOAAWW3_NCOMultiGrid_WIND_test_NOAAWW3_NCOMultiGrid_WIND_test','time':timeInfo})cat.save(coverage)Once the ImageMosaic has been configured, it is possible to read the coverages along with their granule schema and granule info.fromgeoserver.catalogimportCatalogcat=Catalog("http://localhost:8180/geoserver/rest")store=cat.get_store("NOAAWW3_NCOMultiGrid_WIND_test")coverages=cat.mosaic_coverages(store)schema=cat.mosaic_coverage_schema(coverages['coverages']['coverage'][0]['name'],store)granules=cat.list_granules(coverages['coverages']['coverage'][0]['name'],store)The granules details can be easily read by doing something like this:granules['crs']['properties']['name']granules['features']granules['features'][0]['properties']['time']granules['features'][0]['properties']['location']granules['features'][0]['properties']['run']When the mosaic grows up and starts having a huge set of granules, you may need to filter the granules query through a CQL filter on the coverage schema attributes.granules=cat.list_granules(coverages['coverages']['coverage'][0]['name'],store,"time >= '2013-10-01T03:00:00.000Z'")granules=cat.list_granules(coverages['coverages']['coverage'][0]['name'],store,"time >= '2013-10-01T03:00:00.000Z' AND run = 0")granules=cat.list_granules(coverages['coverages']['coverage'][0]['name'],store,"location LIKE '%20131002T000000.tif'")Creating layergroupsA layergroup can be setup by providing a list of layers and the related styles to the catalog.
In the next example, a layergroup with 3 layers and their associated styles get created.workspace='my_workspace'layers_in_group=['my_workspace:layer_1','my_workspace:layer_2','my_workspace:layer_3']styles=['my_workspace:style_1','my_workspace:style_2','my_workspace:style_3']layergroup_name='test_layergroup'layergroup=cat.create_layergroup(layergroup_name,layers_in_group,styles,workspace)# Note that if no bounds are provided, GeoServer will automatically compute the layergroup bounding boxcat.save(layergroup)Nesting layergroupsA Layergroup can internally contain layergroups too. In the next example an additional layergroup containing
alayer_4simple layer plus the previously createdtest_layegroupwill be created.
This time, layer attributes need to be specified.workspace='my_workspace'layers=[]layers.append({'name':'my_workspace:layer_4','attributes':{'type':'layer'}})layers.append({'name':'my_workspace:test_layergroup','attributes':{'type':'layerGroup'}})# Not specifying the style for the nested layergroupstyles=[]styles.append('my_workspace:style_4')styles.append(None)layergroup_name='outer_layergroup'outer_layergroup=cat.create_layergroup(layergroup_name,layers,styles,workspace)cat.save(outer_layergroup)