def cleanupProjects(ignore): """[Deleting workspaces at geoserver, which haven't a frontend Directory with the same name] Returns: [array] -- [List of projects that do exist] """ error, geoserver_url = checkConnection(cfg['geoserver']['url'] + "/rest/", cfg['geoserver']['user'], cfg['geoserver']['password']) projects = [] if error: logging.warning( "Could not establish connection to Geoserver, projectHandling may not working" ) return projects cat = Catalog(geoserver_url, "admin", "geoserver") workspaces = [o.name for o in cat.get_workspaces()] dirs = getFrontendDirs() for d in dirs: if d not in workspaces and d not in ignore: shutil.rmtree(cfg['frontend']['path'] + '/projects/' + d) logging.info("Deleted Frontend Folder for Project " + d) else: projects.append(d) return projects
def __init__(self, gs_axx, dico_gs, tipo, txt=''): u""" Uses OGR functions to extract basic informations about geographic Web Features Services. gs_axx = tuple like {url of a geoserver, user, password) dico_gs = dictionary to store tipo = format text = dictionary of text in the selected language """ # connection cat = Catalog(gs_axx[0], gs_axx[1], gs_axx[2]) # print(dir(cat)) # workspaces workspaces = cat.get_workspaces() for wk in workspaces: # print(wk.name, wk.enabled, , wk.resource_type, wk.wmsstore_url) dico_gs[wk.name] = wk.href # print(dir(wk)) # stores stores = cat.get_stores() for st in stores: # print(st.name, st.enabled, st.href, st.resource_type) dico_gs[st.name] = st.href print(dir(st)) dico_stores = OrderedDict() # layers layers = cat.get_layers() dico_layers = OrderedDict() for layer in layers: # print(layer.name, layer.enabled, layer.resource._store.name, layer.resource._workspace.name) title = layer.resource.title print( (layer.resource._workspace.name + "/wms?layers={}:{};".format( layer.resource._workspace.name, layer.name), title.encode("utf8"))) # print(title.encode("utf8")) # dico_layers[layer.name] = layer.enabled, layer.resource.title, layer.resource.abstract, layer.resource.keywords # dico_stores[layer.resource._store.name] = dico_layers # dico_gs[layer.resource._workspace] = dico_stores print(dir(layer.resource))
def __init__(self, gs_axx, dico_gs, tipo, txt=''): u""" Uses OGR functions to extract basic informations about geographic Web Features Services. gs_axx = tuple like {url of a geoserver, user, password) dico_gs = dictionary to store tipo = format text = dictionary of text in the selected language """ # connection cat = Catalog(gs_axx[0], gs_axx[1], gs_axx[2]) # print(dir(cat)) # workspaces workspaces = cat.get_workspaces() for wk in workspaces: # print(wk.name, wk.enabled, , wk.resource_type, wk.wmsstore_url) dico_gs[wk.name] = wk.href # print(dir(wk)) # stores stores = cat.get_stores() for st in stores: # print(st.name, st.enabled, st.href, st.resource_type) dico_gs[st.name] = st.href print(dir(st)) dico_stores = OrderedDict() # layers layers = cat.get_layers() dico_layers = OrderedDict() for layer in layers: # print(layer.name, layer.enabled, layer.resource._store.name, layer.resource._workspace.name) title = layer.resource.title print((layer.resource._workspace.name + "/wms?layers={}:{};".format(layer.resource._workspace.name, layer.name), title.encode("utf8"))) # print(title.encode("utf8")) # dico_layers[layer.name] = layer.enabled, layer.resource.title, layer.resource.abstract, layer.resource.keywords # dico_stores[layer.resource._store.name] = dico_layers # dico_gs[layer.resource._workspace] = dico_stores print(dir(layer.resource))
def conectar_geoserver(stdscr,user,pw): """Probar la conexión a GeoServer (de dev) y crear el objeto Catalogo. Args: * stdscr: Objeto ventana del módulo curses. * user: Nombre de usuario para la conexión a GeoServer. * pw: Password para la conexión a GeoServer. Returns: Un objeto Catalogo del módulo gsconfig para manejar la conexión al GeoServer de dev de GeoBolivia. Raises: Cualquier excepción mandada por la función gsconfig.get_workspaces() esta transmitida. """ # Datos para la conexion a GeoServer url_geoserver = "http://www-dev.geo.gob.bo/geoserver/rest" # Especificación de la conexion a GeoServer cat = Catalog(url_geoserver, user, pw) # Probar la conexion con una consulta simple try: # Recuperación de los workspaces all_workspaces = cat.get_workspaces() except Exception as e: # Salio una excepcion: # la mostramos stdscr.addstr("Error durante la conexion al GeoServer:\n%s\n" % e) # y la relanzamos raise # Devolvemos el objeto catalogo return cat
class wrap_geoserver: """ Geoserver (gsconfig) wrapper """ def __init__(self, geoserver_name, username=username, password=password, easy=False): if geoserver_name in list(REST.keys()): self.path = REST[geoserver_name] else: self.path = geoserver_name self.wms = self.path.replace("rest/", "wms") self.name = geoserver_name self.catalog = Catalog(self.path, username, password) if not easy: self.layers = [] self.layer_names = [] for layer in self.catalog.get_layers(): self.layers.append(layer) self.layer_names.append(layer.name) self.stores = [store for store in self.catalog.get_stores()] self.store_names = [store.name for store in self.stores] styles = [] self.workspaces = [] self.workspace_names = [] for workspace in self.catalog.get_workspaces(): styles = styles + self.catalog.get_styles(workspace) self.workspace_names.append(workspace._name) self.workspaces.append(workspace) self.styles = styles + [ style for style in self.catalog.get_styles() ] self.style_names = [style.name for style in self.styles] def unpack(self, workspace_name, store_type="datastore"): layers_and_styles = {} features = [] workspace = self.get_workspace(workspace_name) if store_type == "datastore": store_url = workspace.datastore_url elif store_type == "coveragestore": store_url = workspace.coveragestore_url else: print("No correct store given") for datastore in tqdm(get(store_url, "name")): url = "{}workspaces/{}/datastores/{}".format( self.path, workspace.name, datastore) features = features + get(url, between_quotes=True) for feature in features: layer_name = os.path.basename(feature).split(".")[0] self.get_layer(self.get_slug(workspace.name, layer_name)) layers_and_styles[layer_name] = self.layer.default_style setattr(self, workspace_name + "_data", layers_and_styles) return layers_and_styles def get_layer(self, layer, easy=False): self.layer = self.catalog.get_layer(layer) if not easy: self.resource = self.layer.resource self.layer_name = self.layer.resource.name self.sld_name = self.layer.default_style.name self.sld_body = self.layer.default_style.sld_body self.layer_latlon_bbox = self.layer.resource.latlon_bbox self.layer_title = self.layer.resource.title self.layer_abstract = self.layer.resource.abstract def get_store(self, layer): self.store = self.layer.resource._store def get_resource(self): self.resource = self.catalog.get_resource(self.layer.name, self.store) def get_workspace(self, workspace_name): self.workspace = self.catalog.get_workspace(workspace_name) self.workspace_name = self.workspace._name return self.workspace def write_abstract(self, data, load_resource=True): if load_resource: self.get_resource() self.resource.abstract = data self.catalog.save(self.resource) def write_title(self, title): self.resource.title = title self.catalog.save(self.resource) def get_connection_parameters(self): self.get_resource() return self.resource.store.connection_parameters def create_workspace(self, workspace_name): workspace_exists = workspace_name in self.workspace_names if not workspace_exists: self.workspace = self.catalog.create_workspace(workspace_name) else: print("workspace already exists, using existing workspace") self.workspace = self.catalog.get_workspace(workspace_name) self.workspace_name = workspace_name def create_postgis_datastore(self, store_name, workspace_name, pg_data): try: self.store = self.catalog.get_store(store_name, self.workspace_name) print("store within workspace exists, using existing store") except Exception as e: print(e) ds = self.catalog.create_datastore(store_name, workspace_name) ds.connection_parameters.update( host=pg_data["host"], port=pg_data["port"], database=pg_data["database"], user=pg_data["username"], passwd=pg_data["password"], dbtype="postgis", schema="public", ) self.save(ds) self.store = self.catalog.get_store(store_name, self.workspace_name) self.store_name = store_name def publish_layer(self, layer_name, workspace_name, overwrite=False, epsg="3857", reload=False): layer_exists = layer_name in self.layer_names # if layer_name in self.workspace_layers[workspace_name]: slug = self.get_slug(workspace_name, layer_name) if overwrite and layer_exists: print("Layer exists, deleting layer") try: self.layer = self.catalog.get_layer(slug) self.delete(self.layer) self.reload() layer_exists = False except Exception as e: print(e) print("Layer does not exist in workspace") layer_exists = False if not layer_exists: feature_type = self.catalog.publish_featuretype( layer_name, self.store, "EPSG:{}".format(str(epsg)), srs="EPSG:{}".format(str(epsg)), ) self.save(feature_type) self.feature_type = feature_type else: print("layer already exists, using existing layer") if reload: self.get_layer(slug) self.layer_name = layer_name def publish_layergroup(self, name, layers, styles=(), bounds=None, workspace=None): layer_group = self.catalog.create_layergroup(name, layers, styles, bounds, workspace) self.save(layer_group) def save(self, save_object): return self.catalog.save(save_object) def close(self): self.catalog = None def delete(self, delete_object): self.catalog.delete(delete_object) def reload(self): self.catalog.reload() def upload_shapefile(self, layer_name, shapefile_path): path = shapefile_path.split(".shp")[0] shapefile = shapefile_and_friends(path) ft = self.catalog.create_featurestore(layer_name, shapefile, self.workspace) self.save(ft) def upload_sld(self, sld_name, workspace_name, sld, overwrite=True): style_exists = sld_name in self.style_names if overwrite and style_exists: print("Overwriting style") style = self.catalog.get_style(sld_name, workspace_name) self.delete(style) self.reload() style_exists = False if not style_exists: try: self.catalog.create_style(sld_name, sld, False, workspace_name, "sld11") except Exception as e: print(e) style = self.catalog.get_style(sld_name, workspace_name) self.delete(style) self.reload() self.catalog.create_style(sld_name, sld, False, workspace_name, "sld10") self.style_name = sld_name else: if style_exists: print("Style already exists, using current style") self.style_name = sld_name def set_sld_for_layer(self, workspace_name=None, style_name=None, use_custom=False): if not use_custom: workspace_name = self.workspace_name style_name = self.style_name self.style_slug = self.get_slug(workspace_name, style_name) else: if workspace_name is None: self.style_slug = style_name else: self.style_slug = self.get_slug(workspace_name, style_name) self.style = self.catalog.get_style(self.style_slug) print("Setting {} for {}".format(self.style.name, self.layer.name)) self.layer.default_style = self.style self.save(self.layer) def get_slug(self, workspace, name): return "{}:{}".format(workspace, name) def get_slug_data(self, slug): workspace_name = slug.split(":")[0] layer_name = slug.split(":")[1] return workspace_name, layer_name def get_sld(self, layer_slug=None): if layer_slug is None: self.style = self.catalog.get_style(self.layer_slug) else: self.style = self.catalog.get_style(layer_slug) self.sld_body = self.style.sld_body return self.sld_body def get_layer_workspace(self, layer_name): return self.catalog.get_layer(layer_name).resource.workspace.name
''' Created on Mar 21, 2014 @author: lanalfa ''' from geoserver.catalog import Catalog import pprint cat = Catalog("http://localhost:8080/geoserver/rest") resources = cat.get_resources() gliStores = cat.get_stores() iWorkspaces = cat.get_workspaces() for loWorkspace in iWorkspaces: print loWorkspace.name print for loStore in gliStores: print loStore.name print iLayers = cat.get_layers() for ilLayer in iLayers: ilNomeLayer = ilLayer.name print ilNomeLayer print
def __init__(self, gs_axx, dico_gs, tipo, txt=''): """Use OGR functions to extract basic informations about geoserver. gs_axx = tuple like {url of a geoserver, user, password) dico_gs = dictionary to store tipo = format text = dictionary of text in the selected language """ # connection cat = Catalog(gs_axx[0], gs_axx[1], gs_axx[2], disable_ssl_certificate_validation=gs_axx[3]) # print(dir(cat)) # -- WORKSPACES ------------------------------------------------------- workspaces = cat.get_workspaces() for wk in workspaces: # print(wk.name, wk.enabled, wk.resource_type, wk.wmsstore_url) dico_gs[wk.name] = wk.href, {} # print(dir(wk)) # -- STORES ----------------------------------------------------------- # stores = cat.get_stores() # for st in stores: # # print(st.name, st.enabled, st.href, st.resource_type) # if hasattr(st, 'url'): # url = st.url # elif hasattr(st, 'resource_url'): # url = st.resource_url # else: # print(dir(st)) # dico_gs.get(st.workspace.name)[1][st.name] = {"ds_type": st.type, # "ds_url": url} # print(dir(st)) # print(st.url) # print(st.workspace) # print(dir(st.workspace)) # print(st.workspace.name) # -- LAYERS ----------------------------------------------------------- # resources_target = cat.get_resources(workspace='ayants-droits') layers = cat.get_layers() logging.info("{} layers found".format(len(layers))) dico_layers = OrderedDict() for layer in layers: # print(layer.resource_type) lyr_title = layer.resource.title lyr_name = layer.name lyr_wkspace = layer.resource._workspace.name if type(layer.resource) is Coverage: lyr_type = "coverage" elif type(layer.resource) is FeatureType: lyr_type = "vector" else: lyr_type = type(layer.resource) # a log handshake logging.info("{} | {} | {} | {}".format(layers.index(layer), lyr_type, lyr_name, lyr_title)) # # METADATA LINKS # # download link md_link_dl = "{0}/geoserver/{1}/ows?request=GetFeature"\ "&service=WFS&typeName={1}%3A{2}&version=2.0.0"\ "&outputFormat=SHAPE-ZIP"\ .format(url_base, lyr_wkspace, lyr_name) # mapfish links md_link_mapfish_wms = "{0}/mapfishapp/?layername={1}"\ "&owstype=WMSLayer&owsurl={0}/"\ "geoserver/{2}/ows"\ .format(url_base, lyr_name, lyr_wkspace) md_link_mapfish_wfs = "{0}/mapfishapp/?layername={1}"\ "&owstype=WFSLayer&owsurl={0}/"\ "geoserver/{2}/ows"\ .format(url_base, lyr_name, lyr_wkspace) md_link_mapfish_wcs = "{0}/mapfishapp/?cache=PreferNetwork"\ "&crs=EPSG:2154&format=GeoTIFF"\ "&identifier={1}:{2}"\ "&url={0}/geoserver/ows?"\ .format(url_base, lyr_wkspace, lyr_name) # OC links md_link_oc_wms = "{0}/geoserver/{1}/wms?layers={1}:{2}"\ .format(url_base, lyr_wkspace, lyr_name) md_link_oc_wfs = "{0}/geoserver/{1}/ows?typeName={1}:{2}"\ .format(url_base, lyr_wkspace, lyr_name) md_link_oc_wcs = "{0}/geoserver/{1}/ows?typeName={1}:{2}"\ .format(url_base, lyr_wkspace, lyr_name) # CSW Querier links md_link_csw_wms = "{0}/geoserver/ows?service=wms&version=1.3.0"\ "&request=GetCapabilities".format(url_base) md_link_csw_wfs = "{0}/geoserver/ows?service=wfs&version=2.0.0"\ "&request=GetCapabilities".format(url_base) # # # SERVICE LINKS # # GeoServer Edit links gs_link_edit = "{}/geoserver/web/?wicket:bookmarkablePage="\ ":org.geoserver.web.data.resource."\ "ResourceConfigurationPage"\ "&name={}"\ "&wsName={}".format(url_base, lyr_wkspace, lyr_name) # Metadata links (service => metadata) if is_uuid(dict_match_gs_md.get(lyr_name)): # HTML metadata md_uuid_pure = dict_match_gs_md.get(lyr_name) srv_link_html = "{}/portail/geocatalogue?uuid={}"\ .format(url_base, md_uuid_pure) # XML metadata md_uuid_formatted = "{}-{}-{}-{}-{}".format( md_uuid_pure[:8], md_uuid_pure[8:12], md_uuid_pure[12:16], md_uuid_pure[16:20], md_uuid_pure[20:]) srv_link_xml = "http://services.api.isogeo.com/ows/s/"\ "{1}/{2}?"\ "service=CSW&version=2.0.2&request=GetRecordById"\ "&id=urn:isogeo:metadata:uuid:{0}&"\ "elementsetname=full&outputSchema="\ "http://www.isotc211.org/2005/gmd"\ .format(md_uuid_formatted, csw_share_id, csw_share_token) # add to GeoServer layer rzourc = cat.get_resource(lyr_name, store=layer.resource._store.name) rzourc.metadata_links = [ ('text/html', 'ISO19115:2003', srv_link_html), ('text/xml', 'ISO19115:2003', srv_link_xml), ('text/html', 'TC211', srv_link_html), ('text/xml', 'TC211', srv_link_xml) ] # rzourc.metadata_links.append(('text/html', 'other', 'hohoho')) cat.save(rzourc) else: logging.info("Service without metadata: {} ({})".format( lyr_name, dict_match_gs_md.get(lyr_name))) pass dico_layers[layer.name] = { "title": lyr_title, "workspace": lyr_wkspace, "store_name": layer.resource._store.name, "store_type": layer.resource._store.type, "lyr_type": lyr_type, "md_link_dl": md_link_dl, "md_link_mapfish": md_link_mapfish_wms, "md_link_mapfish_wms": md_link_mapfish_wms, "md_link_mapfish_wfs": md_link_mapfish_wfs, "md_link_mapfish_wcs": md_link_mapfish_wcs, "md_link_oc_wms": md_link_oc_wms, "md_link_oc_wfs": md_link_oc_wfs, "md_link_oc_wcs": md_link_oc_wcs, "md_link_csw_wms": md_link_csw_wms, "md_link_csw_wfs": md_link_csw_wfs, "gs_link_edit": gs_link_edit, "srv_link_html": srv_link_html, "srv_link_xml": srv_link_xml, "md_id_matching": md_uuid_pure } # mem clean up # del dico_layer # print(dico_gs.get(layer.resource._workspace.name)[1][layer.resource._store.name]) # print(dir(layer.resource)) # print(dir(layer.resource.writers)) # print(dir(layer.resource.writers.get("metadataLinks").func_dict)) # print(layer.resource.metadata) # print(layer.resource.metadata_links) dico_gs["layers"] = dico_layers
def create_workspace(server, username, password, workspace): cat = Catalog(server, username, password) if not workspace in [w.name for w in cat.get_workspaces()]: print 'Creating workspace: %s' %workspace cat.create_workspace(workspace, 'api.npolar.no/' + workspace)
#! /usr/bin/env python from geoserver.catalog import Catalog cat = Catalog('http://host/geoserver/rest', 'user', 'password') def internal_name(s): return s.startswith("__") and s.endswith("__") def check(x): if hasattr(x, 'name'): print "NAME:", x.name, " TYPE:", type(x) for name in dir(x): if not internal_name(name) and getattr(x, name) is None: print x, name, "IS NONE" for ws in cat.get_workspaces(): check(ws) for st in cat.get_stores(): check(st) for rs in cat.get_resources(st): check(rs)
class GsConn(): def __init__(self, host, login, password, debug=False): """ Geoserver connection """ self.host = host self.login = login self.password = password self.debug = debug # Connect to server self.cat = Catalog("http://%s/geoserver/rest" % host, login, password) if self.debug is True: print "Connected to geoserver" def crate_workspace(self, name, uri, overwrite=False): """ Creates a workspace :param name: Workspace name. :param overwrite: If True, delete existing workspace. :return: None """ workspaces = [ workspace.name for workspace in self.cat.get_workspaces() ] if name in workspaces and overwrite is True: # ws2del = self.cat.get_workspace(name) # self.cat.delete(ws2del, purge=True, recurse=True) return None # NOTE: If we delete the workspace then all associated layers are lost. elif name in workspaces and overwrite is False: print "ERROR: Workspace %s already exists (use overwrite=True)." % name self.cat.create_workspace(name, uri) if self.debug is True: print "Workspace %s available." % name ws = self.cat.get_workspace(name) ws.enabled = True def create_pg_store(self, name, workspace, host, port, login, password, dbname, schema, overwrite=False): """ Creates datastore. :param name: Name of the datastore. :param workspace: Name of the workspace to use. :param overwrite: If True replace datastore. :return: None """ stores = [store.name for store in self.cat.get_stores()] if name in stores and overwrite is True: # st2del = self.cat.get_store(name) # self.cat.delete(st2del, purge=True, recurse=True) # self.cat.reload() return None # NOTE: If we delete store, every layers associated with are lost. elif name in stores and overwrite is False: print "ERROR: Store %s already exists (use overwrite=True)." % name ds = self.cat.create_datastore(name, workspace) ds.connection_parameters.update(host=host, port=port, user=login, passwd=password, dbtype='postgis', database=dbname, schema=schema) self.cat.save(ds) ds = self.cat.get_store(name) if ds.enabled is False: print "ERROR: Geoserver store %s not enabled" % name if self.debug is True: print "Datastore %s created." % name def publish_pg_layer(self, layer_table, layer_name, store, srid, overwrite=True): """ """ existing_lyr = self.cat.get_layer("participatubes:%s" % layer_table) if existing_lyr is not None: print "Layer participatubes:%s already exists, deleting it." % layer_table self.cat.delete(existing_lyr) self.cat.reload() ds = self.cat.get_store(store) ft = self.cat.publish_featuretype(layer_table, ds, 'EPSG:%s' % srid, srs='EPSG:4326') ft.projection_policy = "REPROJECT_TO_DECLARED" ft.title = layer_name self.cat.save(ft) if ft.enabled is False: print "ERROR: Layer %s %s %s is not enabled." (ft.workspace.name, ft.store.name, ft.title) if self.debug is True: print "Layer %s>%s>%s published." % (ft.workspace.name, ft.store.name, ft.title) def create_style_from_sld(self, style_name, sld_file, workspace, overwrite=True): """ """ if self.cat.get_style(style_name) is not None: print "Style %s already exists, deleting it." % style_name style2del = self.cat.get_style(style_name) self.cat.delete(style2del) self.cat.create_style( style_name, open(sld_file).read(), overwrite=overwrite ) # FIXME: if ", workspace=workspace" specified can't delete style if self.debug is True: print "Style %s created in Geoserver" % style_name def apply_style_to_layer(self, layer_name, style_name): """ Apply a geoserver styler to a layer """ gs_layer = self.cat.get_layer(layer_name) gs_style = self.cat.get_style(style_name) # FIXME: Which works better? # gs_layer.default_style = gs_style / gs_layer._set_default_style(gs_style) # FIXME: Maybe indicate workspace when saving style then name the style as "workspace:style" gs_layer._set_default_style(gs_style) self.cat.save(gs_layer) if self.debug is True: print "Style applied to %s" % layer_name
class CatalogTests(unittest.TestCase): def setUp(self): self.cat = Catalog("http://localhost:8080/geoserver/rest") def testAbout(self): about_html = self.cat.about() self.assertTrue('<html xmlns="http://www.w3.org/1999/xhtml"' in about_html) def testGSVersion(self): version = self.cat.gsversion() pat = re.compile('\d\.\d(\.[\dx]|-SNAPSHOT)') self.assertTrue(pat.match('2.2.x')) self.assertTrue(pat.match('2.3.2')) self.assertTrue(pat.match('2.3-SNAPSHOT')) self.assertFalse(pat.match('2.3.y')) self.assertFalse(pat.match('233')) self.assertTrue(pat.match(version)) def testWorkspaces(self): self.assertEqual(7, len(self.cat.get_workspaces())) # marking out test since geoserver default workspace is not consistent # self.assertEqual("cite", self.cat.get_default_workspace().name) self.assertEqual("topp", self.cat.get_workspace("topp").name) def testStores(self): topp = self.cat.get_workspace("topp") sf = self.cat.get_workspace("sf") self.assertEqual(9, len(self.cat.get_stores())) self.assertEqual(2, len(self.cat.get_stores(topp))) self.assertEqual(2, len(self.cat.get_stores(sf))) self.assertEqual("states_shapefile", self.cat.get_store("states_shapefile", topp).name) self.assertEqual("states_shapefile", self.cat.get_store("states_shapefile").name) self.assertEqual("states_shapefile", self.cat.get_store("states_shapefile").name) self.assertEqual("sfdem", self.cat.get_store("sfdem", sf).name) self.assertEqual("sfdem", self.cat.get_store("sfdem").name) def testResources(self): topp = self.cat.get_workspace("topp") sf = self.cat.get_workspace("sf") states = self.cat.get_store("states_shapefile", topp) sfdem = self.cat.get_store("sfdem", sf) self.assertEqual(19, len(self.cat.get_resources())) self.assertEqual(1, len(self.cat.get_resources(states))) self.assertEqual(5, len(self.cat.get_resources(workspace=topp))) self.assertEqual(1, len(self.cat.get_resources(sfdem))) self.assertEqual(6, len(self.cat.get_resources(workspace=sf))) self.assertEqual("states", self.cat.get_resource("states", states).name) self.assertEqual("states", self.cat.get_resource("states", workspace=topp).name) self.assertEqual("states", self.cat.get_resource("states").name) states = self.cat.get_resource("states") fields = [ states.title, states.abstract, states.native_bbox, states.latlon_bbox, states.projection, states.projection_policy ] self.assertFalse(None in fields, str(fields)) self.assertFalse(len(states.keywords) == 0) self.assertFalse(len(states.attributes) == 0) self.assertTrue(states.enabled) self.assertEqual("sfdem", self.cat.get_resource("sfdem", sfdem).name) self.assertEqual("sfdem", self.cat.get_resource("sfdem", workspace=sf).name) self.assertEqual("sfdem", self.cat.get_resource("sfdem").name) def testLayers(self): expected = set(["Arc_Sample", "Pk50095", "Img_Sample", "mosaic", "sfdem", "bugsites", "restricted", "streams", "archsites", "roads", "tasmania_roads", "tasmania_water_bodies", "tasmania_state_boundaries", "tasmania_cities", "states", "poly_landmarks", "tiger_roads", "poi", "giant_polygon" ]) actual = set(l.name for l in self.cat.get_layers()) missing = expected - actual extras = actual - expected message = "Actual layer list did not match expected! (Extras: %s) (Missing: %s)" % (extras, missing) self.assert_(len(expected ^ actual) == 0, message) states = self.cat.get_layer("states") self.assert_("states", states.name) self.assert_(isinstance(states.resource, ResourceInfo)) self.assertEqual(set(s.name for s in states.styles), set(['pophatch', 'polygon'])) self.assertEqual(states.default_style.name, "population") def testLayerGroups(self): expected = set(["tasmania", "tiger-ny", "spearfish"]) actual = set(l.name for l in self.cat.get_layergroups()) missing = expected - actual extras = actual - expected message = "Actual layergroup list did not match expected! (Extras: %s) (Missing: %s)" % (extras, missing) self.assert_(len(expected ^ actual) == 0, message) tas = self.cat.get_layergroup("tasmania") self.assert_("tasmania", tas.name) self.assert_(isinstance(tas, LayerGroup)) self.assertEqual(tas.layers, ['tasmania_state_boundaries', 'tasmania_water_bodies', 'tasmania_roads', 'tasmania_cities'], tas.layers) self.assertEqual(tas.styles, [None, None, None, None], tas.styles) def testStyles(self): self.assertEqual(20, len(self.cat.get_styles())) self.assertEqual("population", self.cat.get_style("population").name) self.assertEqual("popshade.sld", self.cat.get_style("population").filename) self.assertEqual("population", self.cat.get_style("population").sld_name) def testEscaping(self): # GSConfig is inconsistent about using exceptions vs. returning None # when a resource isn't found. # But the basic idea is that none of them should throw HTTP errors from # misconstructed URLS self.cat.get_style("best style ever") self.cat.get_workspace("best workspace ever") self.cat.get_store(workspace="best workspace ever", name="best store ever") self.assertRaises(FailedRequestError, lambda: self.cat.get_resource( workspace="best workspace ever", store="best store ever", name="best resource ever")) self.cat.get_layer("best layer ever") self.cat.get_layergroup("best layergroup ever") def testUnicodeUrl(self): """ Tests that the geoserver.support.url function support unicode strings. """ # Test the url function with unicode seg = ['workspaces', 'test', 'datastores', u'operaci\xf3n_repo', 'featuretypes.xml'] u = url(base=self.cat.service_url, seg=seg) self.assertEqual(u, self.cat.service_url + "/workspaces/test/datastores/operaci%C3%B3n_repo/featuretypes.xml") # Test the url function with normal string seg = ['workspaces', 'test', 'datastores', 'test-repo', 'featuretypes.xml'] u = url(base=self.cat.service_url, seg=seg) self.assertEqual(u, self.cat.service_url + "/workspaces/test/datastores/test-repo/featuretypes.xml")
args = parser.parse_args(sys.argv[1:]) creds = Credentials(logger=logger) if args.disable_ssl_verification: bypassSSLVerification() # Disable FutureWarning from owslib warnings.simplefilter("ignore", category=FutureWarning) (user, password) = creds.getFromUrl(args.geoserver) gscatalog = Catalog(args.geoserver + "/rest/", username=user, password=password) errors = [] # Whole geoserver catalog if args.mode == "full": print_banner(args) # Layers workspaces = gscatalog.get_workspaces() for ws in workspaces: logger.debug("Inspecting workspace : %s" % ws) resources = gscatalog.get_resources(workspace=ws) for res in resources: try: layer = gscatalog.get_layer(res.workspace.name + ":" + res.name) logger.debug("Inspecting layer : %s:%s" % (res.workspace.name, res.name)) gn_to_gs_fix(layer, res, args.dry_run, creds, args.disable_ssl_verification) except Inconsistency as e: logger.debug("Inconsistency found : %s" % e) errors.append(e) # Layer groups TODO: not managed yet by gsconfig # lgroups = gscatalog.get_layergroups() # for lg in lgroups: # gn_to_gs_fix(lg, args.dry_run, creds)
class ModifyingTests(unittest.TestCase): def setUp(self): self.cat = Catalog(GSPARAMS['GSURL'], username=GSPARAMS['GSUSER'], password=GSPARAMS['GSPASSWORD']) self.gs_version = self.cat.get_short_version() def testFeatureTypeSave(self): # test saving round trip rs = self.cat.get_resources("bugsites", workspaces="sf")[0] old_abstract = rs.abstract new_abstract = "Not the original abstract" enabled = rs.enabled # Change abstract on server rs.abstract = new_abstract self.cat.save(rs) rs = self.cat.get_resources("bugsites", workspaces="sf")[0] self.assertEqual(new_abstract, rs.abstract) self.assertEqual(enabled, rs.enabled) # Change keywords on server rs.keywords = ["bugsites", "gsconfig"] enabled = rs.enabled self.cat.save(rs) rs = self.cat.get_resources("bugsites", workspaces="sf")[0] self.assertEqual(["bugsites", "gsconfig"], rs.keywords) self.assertEqual(enabled, rs.enabled) # Change metadata links on server rs.metadata_links = [("text/xml", "TC211", "http://example.com/gsconfig.test.metadata")] enabled = rs.enabled self.cat.save(rs) rs = self.cat.get_resources("bugsites", workspaces="sf")[0] self.assertEqual([ ("text/xml", "TC211", "http://example.com/gsconfig.test.metadata") ], rs.metadata_links) self.assertEqual(enabled, rs.enabled) # Restore abstract rs.abstract = old_abstract self.cat.save(rs) rs = self.cat.get_resources("bugsites", workspaces="sf")[0] self.assertEqual(old_abstract, rs.abstract) def testDataStoreCreate(self): ds = self.cat.create_datastore("vector_gsconfig") ds.connection_parameters.update(**DBPARAMS) self.cat.save(ds) def testPublishFeatureType(self): # Use the other test and store creation to load vector data into a database # @todo maybe load directly to database? try: self.testDataStoreCreateAndThenAlsoImportData() except FailedRequestError: pass try: lyr = self.cat.get_layer('import') data_source_name = lyr.resource.native_name # Delete the existing layer and resource to allow republishing. self.cat.delete(lyr) self.cat.delete(lyr.resource) ds = self.cat.get_stores("gsconfig_import_test")[0] # make sure it's gone self.assert_(self.cat.get_layer('import') is None) self.cat.publish_featuretype("import", ds, native_crs="EPSG:4326", native_name=data_source_name) # and now it's not self.assert_(self.cat.get_layer('import') is not None) finally: # tear stuff down to allow the other test to pass if we run first ds = self.cat.get_stores("gsconfig_import_test")[0] lyr = self.cat.get_layer('import') # Delete the existing layer and resource to allow republishing. try: if lyr: self.cat.delete(lyr) self.cat.delete(lyr.resource) if ds: self.cat.delete(ds) except: pass def testDataStoreModify(self): ds = self.cat.get_stores("sf")[0] self.assertFalse("foo" in ds.connection_parameters) ds.connection_parameters = ds.connection_parameters ds.connection_parameters["foo"] = "bar" orig_ws = ds.workspace.name self.cat.save(ds) ds = self.cat.get_stores("sf")[0] self.assertTrue("foo" in ds.connection_parameters) self.assertEqual("bar", ds.connection_parameters["foo"]) self.assertEqual(orig_ws, ds.workspace.name) @drop_table('import') def testDataStoreCreateAndThenAlsoImportData(self): ds = self.cat.create_datastore("gsconfig_import_test") ds.connection_parameters.update(**DBPARAMS) self.cat.save(ds) ds = self.cat.get_stores("gsconfig_import_test")[0] self.cat.add_data_to_store( ds, "import", { 'shp': 'test/data/states.shp', 'shx': 'test/data/states.shx', 'dbf': 'test/data/states.dbf', 'prj': 'test/data/states.prj' }) @drop_table('import2') def testVirtualTables(self): ds = self.cat.create_datastore("gsconfig_import_test2") ds.connection_parameters.update(**DBPARAMS) self.cat.save(ds) ds = self.cat.get_stores("gsconfig_import_test2")[0] self.cat.add_data_to_store( ds, "import2", { 'shp': 'test/data/states.shp', 'shx': 'test/data/states.shx', 'dbf': 'test/data/states.dbf', 'prj': 'test/data/states.prj' }) geom = JDBCVirtualTableGeometry('the_geom', 'MultiPolygon', '4326') ft_name = 'my_jdbc_vt_test' epsg_code = 'EPSG:4326' sql = "select * from import2 where 'STATE_NAME' = 'Illinois'" keyColumn = None parameters = None jdbc_vt = JDBCVirtualTable(ft_name, sql, 'false', geom, keyColumn, parameters) ft = self.cat.publish_featuretype(ft_name, ds, epsg_code, jdbc_virtual_table=jdbc_vt) # DISABLED; this test works only in the very particular case # "mytiff.tiff" is already present into the GEOSERVER_DATA_DIR # def testCoverageStoreCreate(self): # ds = self.cat.create_coveragestore2("coverage_gsconfig") # ds.data_url = "file:test/data/mytiff.tiff" # self.cat.save(ds) def testCoverageStoreModify(self): cs = self.cat.get_stores("sfdem")[0] self.assertEqual("GeoTIFF", cs.type) cs.type = "WorldImage" self.cat.save(cs) cs = self.cat.get_stores("sfdem")[0] self.assertEqual("WorldImage", cs.type) # not sure about order of test runs here, but it might cause problems # for other tests if this layer is misconfigured cs.type = "GeoTIFF" self.cat.save(cs) def testCoverageSave(self): # test saving round trip rs = self.cat.get_resources("Arc_Sample", workspaces="nurc")[0] old_abstract = rs.abstract new_abstract = "Not the original abstract" # # Change abstract on server rs.abstract = new_abstract self.cat.save(rs) rs = self.cat.get_resources("Arc_Sample", workspaces="nurc")[0] self.assertEqual(new_abstract, rs.abstract) # Restore abstract rs.abstract = old_abstract self.cat.save(rs) rs = self.cat.get_resources("Arc_Sample", workspaces="nurc")[0] self.assertEqual(old_abstract, rs.abstract) # Change metadata links on server rs.metadata_links = [("text/xml", "TC211", "http://example.com/gsconfig.test.metadata")] enabled = rs.enabled self.cat.save(rs) rs = self.cat.get_resources("Arc_Sample", workspaces="nurc")[0] self.assertEqual([ ("text/xml", "TC211", "http://example.com/gsconfig.test.metadata") ], rs.metadata_links) self.assertEqual(enabled, rs.enabled) srs_before = set(['EPSG:4326']) srs_after = set(['EPSG:4326', 'EPSG:3785']) formats = set( ['ARCGRID', 'ARCGRID-GZIP', 'GEOTIFF', 'PNG', 'GIF', 'TIFF']) formats_after = set(["PNG", "GIF", "TIFF"]) # set and save request_srs_list self.assertEquals(set(rs.request_srs_list), srs_before, str(rs.request_srs_list)) rs.request_srs_list = rs.request_srs_list + ['EPSG:3785'] self.cat.save(rs) rs = self.cat.get_resources("Arc_Sample", workspaces="nurc")[0] self.assertEquals(set(rs.request_srs_list), srs_after, str(rs.request_srs_list)) # set and save response_srs_list self.assertEquals(set(rs.response_srs_list), srs_before, str(rs.response_srs_list)) rs.response_srs_list = rs.response_srs_list + ['EPSG:3785'] self.cat.save(rs) rs = self.cat.get_resources("Arc_Sample", workspaces="nurc")[0] self.assertEquals(set(rs.response_srs_list), srs_after, str(rs.response_srs_list)) # set and save supported_formats self.assertEquals(set(rs.supported_formats), formats, str(rs.supported_formats)) rs.supported_formats = ["PNG", "GIF", "TIFF"] self.cat.save(rs) rs = self.cat.get_resources("Arc_Sample", workspaces="nurc")[0] self.assertEquals(set(rs.supported_formats), formats_after, str(rs.supported_formats)) def testWmsStoreCreate(self): ws = self.cat.create_wmsstore("wmsstore_gsconfig") ws.capabilitiesURL = "http://mesonet.agron.iastate.edu/cgi-bin/wms/iowa/rainfall.cgi?VERSION=1.1.1&REQUEST=GetCapabilities&SERVICE=WMS&" ws.type = "WMS" self.cat.save(ws) def testWmsLayer(self): self.cat.create_workspace("wmstest", "http://example.com/wmstest") wmstest = self.cat.get_workspaces("wmstest")[0] wmsstore = self.cat.create_wmsstore("wmsstore", wmstest) wmsstore.capabilitiesURL = "http://mesonet.agron.iastate.edu/cgi-bin/wms/iowa/rainfall.cgi?VERSION=1.1.1&REQUEST=GetCapabilities&SERVICE=WMS&" wmsstore.type = "WMS" self.cat.save(wmsstore) wmsstore = self.cat.get_stores("wmsstore")[0] self.assertEqual(1, len(self.cat.get_stores(workspaces=wmstest.name))) available_layers = wmsstore.get_resources(available=True) for layer in available_layers: # sanitize the layer name - validation will fail on newer geoservers name = layer.replace(':', '_') new_layer = self.cat.create_wmslayer(wmstest, wmsstore, name, nativeName=layer) added_layers = wmsstore.get_resources() self.assertEqual(len(available_layers), len(added_layers)) changed_layer = added_layers[0] self.assertEqual(True, changed_layer.advertised) self.assertEqual(True, changed_layer.enabled) changed_layer.advertised = False changed_layer.enabled = False self.cat.save(changed_layer) self.cat._cache.clear() changed_layer = wmsstore.get_resources()[0] changed_layer.fetch() self.assertEqual(False, changed_layer.advertised) self.assertEqual(False, changed_layer.enabled) # Testing projection and projection policy changes changed_layer.projection = "EPSG:900913" changed_layer.projection_policy = "REPROJECT_TO_DECLARED" self.cat.save(changed_layer) self.cat._cache.clear() layer = self.cat.get_layer(changed_layer.name) self.assertEqual(layer.resource.projection_policy, changed_layer.projection_policy) self.assertEqual(layer.resource.projection, changed_layer.projection) def testFeatureTypeCreate(self): shapefile_plus_sidecars = shapefile_and_friends("test/data/states") expected = { 'shp': 'test/data/states.shp', 'shx': 'test/data/states.shx', 'dbf': 'test/data/states.dbf', 'prj': 'test/data/states.prj' } self.assertEqual(len(expected), len(shapefile_plus_sidecars)) for k, v in expected.items(): self.assertEqual(v, shapefile_plus_sidecars[k]) sf = self.cat.get_workspaces("sf")[0] self.cat.create_featurestore("states_test", shapefile_plus_sidecars, sf.name) self.assert_( len(self.cat.get_resources("states_test", workspaces=sf.name)) > 0) self.assertRaises( ConflictingDataError, lambda: self.cat.create_featurestore( "states_test", shapefile_plus_sidecars, sf)) lyr = self.cat.get_layer("states_test") self.cat.delete(lyr) self.assert_(self.cat.get_layer("states_test") is None) def testLayerSave(self): # test saving round trip lyr = self.cat.get_layer("states") old_attribution = lyr.attribution new_attribution = { 'title': 'Not the original attribution', 'width': '123', 'height': '321', 'href': 'http://www.georchestra.org', 'url': 'https://www.cigalsace.org/portail/cigal/documents/page/mentions-legales/Logo_geOrchestra.jpg', 'type': 'image/jpeg' } # change attribution on server lyr.attribution = new_attribution self.cat.save(lyr) lyr = self.cat.get_layer("states") self.assertEqual(new_attribution, lyr.attribution) # Restore attribution lyr.attribution = old_attribution self.cat.save(lyr) lyr = self.cat.get_layer("states") self.assertEqual(old_attribution, lyr.attribution) self.assertEqual(lyr.default_style.name, "population") old_default_style = lyr.default_style lyr.default_style = 'pophatch' lyr.styles = [old_default_style] self.cat.save(lyr) lyr = self.cat.get_layer("states") self.assertEqual(lyr.default_style.name, "pophatch") self.assertEqual([s.name for s in lyr.styles], ["population"]) def testStyles(self): # check count before tests (upload) count = len(self.cat.get_styles()) # upload new style, verify existence self.cat.create_style("fred", open("test/fred.sld").read()) self.cat._cache.clear() fred = self.cat.get_styles(names="fred")[0] self.assert_(fred is not None) self.assertEqual("Fred", fred.sld_title) # replace style, verify changes self.cat.create_style("fred", open("test/ted.sld").read(), overwrite=True) self.cat._cache.clear() fred = self.cat.get_styles("fred")[0] self.assert_(fred is not None) self.assertEqual("Ted", fred.sld_title) # delete style, verify non-existence self.cat.delete(fred, purge=True) self.cat._cache.clear() self.assert_(len(self.cat.get_styles("fred")) == 0) # attempt creating new style self.cat.create_style("fred", open("test/fred.sld").read()) self.cat._cache.clear() fred = self.cat.get_styles("fred")[0] self.assertEqual("Fred", fred.sld_title) # compare count after upload self.assertEqual(count + 1, len(self.cat.get_styles())) # attempt creating a new style without "title" self.cat.create_style("notitle", open("test/notitle.sld").read()) self.cat._cache.clear() notitle = self.cat.get_styles("notitle")[0] self.assertEqual(None, notitle.sld_title) def testWorkspaceStyles(self): # upload new style, verify existence self.cat.create_style("jed", open("test/fred.sld").read(), workspace="topp") self.cat._cache.clear() jed = self.cat.get_styles(names="jed", workspaces="blarny") self.assert_(len(jed) == 0) jed = self.cat.get_styles(names="jed", workspaces="topp") self.assert_(len(jed) == 1) self.assertEqual("Fred", jed[0].sld_title) # replace style, verify changes self.cat.create_style("jed", open("test/ted.sld").read(), overwrite=True, workspace="topp") self.cat._cache.clear() jed = self.cat.get_styles(names="jed", workspaces="topp") self.assert_(len(jed) == 1) self.assertEqual("Ted", jed[0].sld_title) # delete style, verify non-existence self.cat.delete(jed[0], purge=True) self.assertEqual( 0, len(self.cat.get_styles(names="jed", workspaces="topp"))) # attempt creating new style self.cat.create_style("jed", open("test/fred.sld").read(), workspace="topp") self.cat._cache.clear() jed = self.cat.get_styles(names="jed", workspaces="topp") self.assertEqual("Fred", jed[0].sld_title) def testLayerWorkspaceStyles(self): # upload new style, verify existence self.cat.create_style("ned", open("test/fred.sld").read(), overwrite=True, workspace="topp") self.cat.create_style("zed", open("test/ted.sld").read(), overwrite=True, workspace="topp") self.cat._cache.clear() styles = self.cat.get_styles(names="ned, zed", workspaces="topp") self.assertEqual(2, len(styles)) ned, zed = styles lyr = self.cat.get_layer("states") lyr.default_style = ned lyr.styles = [zed] self.cat.save(lyr) self.assertEqual("topp:ned", lyr.default_style) self.assertEqual([zed], lyr.styles) lyr.refresh() self.assertEqual("topp:ned", lyr.default_style.fqn) self.assertEqual([zed.fqn], [s.fqn for s in lyr.styles]) def testWorkspaceCreate(self): ws = self.cat.get_workspaces("acme") self.assertEqual(0, len(ws)) self.cat.create_workspace("acme", "http://example.com/acme") ws = self.cat.get_workspaces("acme")[0] self.assertEqual("acme", ws.name) def testWorkspaceDelete(self): self.cat.create_workspace("foo", "http://example.com/foo") ws = self.cat.get_workspaces("foo")[0] self.cat.delete(ws) ws = self.cat.get_workspaces("foo") self.assertEqual(0, len(ws)) def testWorkspaceDefault(self): # save orig orig = self.cat.get_default_workspace() neu = self.cat.create_workspace("neu", "http://example.com/neu") try: # make sure setting it works self.cat.set_default_workspace("neu") ws = self.cat.get_default_workspace() self.assertEqual('neu', ws.name) finally: # cleanup and reset to the way things were self.cat.delete(neu) self.cat.set_default_workspace(orig.name) ws = self.cat.get_default_workspace() self.assertEqual(orig.name, ws.name) def testFeatureTypeDelete(self): pass def testCoverageDelete(self): pass def testDataStoreDelete(self): states = self.cat.get_stores('states_shapefile')[0] self.assert_(states.enabled == True) states.enabled = False self.assert_(states.enabled == False) self.cat.save(states) states = self.cat.get_stores('states_shapefile')[0] self.assert_(states.enabled == False) states.enabled = True self.cat.save(states) states = self.cat.get_stores('states_shapefile')[0] self.assert_(states.enabled == True) def testLayerGroupSave(self): tas = self.cat.get_layergroups("tasmania")[0] if self.gs_version >= "2.13": self.assertEqual(tas.layers, [ 'topp:tasmania_state_boundaries', 'topp:tasmania_water_bodies', 'topp:tasmania_roads', 'topp:tasmania_cities' ], tas.layers) else: self.assertEqual(tas.layers, [ 'tasmania_state_boundaries', 'tasmania_water_bodies', 'tasmania_roads', 'tasmania_cities' ], tas.layers) self.assertEqual(tas.styles, [None, None, None, None], tas.styles) tas.layers = tas.layers[:-1] tas.styles = tas.styles[:-1] self.cat.save(tas) # this verifies the local state if self.gs_version >= "2.13": self.assertEqual(tas.layers, [ 'topp:tasmania_state_boundaries', 'topp:tasmania_water_bodies', 'topp:tasmania_roads' ], tas.layers) else: self.assertEqual(tas.layers, [ 'tasmania_state_boundaries', 'tasmania_water_bodies', 'tasmania_roads' ], tas.layers) self.assertEqual(tas.styles, [None, None, None], tas.styles) # force a refresh to check the remote state # tas.refresh() if self.gs_version >= "2.13": self.assertEqual(tas.layers, [ 'topp:tasmania_state_boundaries', 'topp:tasmania_water_bodies', 'topp:tasmania_roads' ], tas.layers) else: self.assertEqual(tas.layers, [ 'tasmania_state_boundaries', 'tasmania_water_bodies', 'tasmania_roads' ], tas.layers) self.assertEqual(tas.styles, [None, None, None], tas.styles) def testImageMosaic(self): """ Test case for Issue #110 """ # testing the mosaic creation name = 'cea_mosaic' data = open('test/data/mosaic/cea.zip', 'rb') self.cat.create_imagemosaic(name, data) # get the layer resource back self.cat._cache.clear() resource = self.cat.get_layer(name).resource self.assert_(resource is not None) # delete granule from mosaic coverage = name store = self.cat.get_stores(name)[0] granules = self.cat.list_granules(coverage, store) self.assertEqual(1, len(granules['features'])) granule_id = name + '.1' self.cat.delete_granule(coverage, store, granule_id) granules = self.cat.list_granules(coverage, store) self.assertEqual(0, len(granules['features'])) ''' testing external Image mosaic creation ''' name = 'cea_mosaic_external' path = os.path.join(os.getcwd(), 'test/data/mosaic/external') self.cat.create_imagemosaic(name, path, workspace='topp') self.cat._cache.clear() resource = self.cat.get_layer("external").resource self.assert_(resource is not None) # add granule to mosaic granule_path = os.path.join( os.getcwd(), 'test/data/mosaic/granules/cea_20150102.tif') self.cat.add_granule(granule_path, name, workspace='topp') granules = self.cat.list_granules("external", name, 'topp') self.assertEqual(2, len(granules['features'])) # add external granule to mosaic granule_path = os.path.join( os.getcwd(), 'test/data/mosaic/granules/cea_20150103.zip') self.cat.add_granule(granule_path, name, workspace='topp') granules = self.cat.list_granules("external", name, 'topp') self.assertEqual(3, len(granules['features'])) # Delete store store = self.cat.get_stores(name)[0] self.cat.delete(store, purge=True, recurse=True) self.cat._cache.clear() def testTimeDimension(self): sf = self.cat.get_workspaces("sf")[0] files = shapefile_and_friends( os.path.join(gisdata.GOOD_DATA, "time", "boxes_with_end_date")) self.cat.create_featurestore("boxes_with_end_date", files, sf) get_resource = lambda: self.cat._cache.clear() or self.cat.get_layer( 'boxes_with_end_date').resource # configure time as LIST resource = get_resource() timeInfo = DimensionInfo("time", "true", "LIST", None, "ISO8601", None, attribute="date") resource.metadata = {'time': timeInfo} self.cat.save(resource) # and verify resource = get_resource() timeInfo = resource.metadata['time'] self.assertEqual("LIST", timeInfo.presentation) self.assertEqual(True, timeInfo.enabled) self.assertEqual("date", timeInfo.attribute) self.assertEqual("ISO8601", timeInfo.units) # disable time dimension timeInfo = resource.metadata['time'] timeInfo.enabled = False # since this is an xml property, it won't get written unless we modify it resource.metadata = {'time': timeInfo} self.cat.save(resource) # and verify resource = get_resource() timeInfo = resource.metadata['time'] self.assertEqual(False, timeInfo.enabled) # configure with interval, end_attribute and enable again timeInfo.enabled = True timeInfo.presentation = 'DISCRETE_INTERVAL' timeInfo.resolution = '3 days' timeInfo.end_attribute = 'enddate' resource.metadata = {'time': timeInfo} self.cat.save(resource) # and verify resource = get_resource() timeInfo = resource.metadata['time'] self.assertEqual(True, timeInfo.enabled) self.assertEqual('DISCRETE_INTERVAL', timeInfo.presentation) self.assertEqual('3 days', timeInfo.resolution_str()) self.assertEqual('enddate', timeInfo.end_attribute)
def wms(): cat = Catalog(config.wms["gs_loc"], config.wms["user"], config.wms["pass"]) return repr([layer.name for layer in cat.get_workspaces()])
class GeoserverHelper: def __init__(self, geoserverUrl = "", geoserverUserName = "", geoserverPW = "", geoserverWorkSpace = "", postgreIP = "", postgreUserName = "", postgrePW = ""): """use the constructor given arguments if used""" self.geoserverUrl = geoserverUrl if geoserverUrl != "" else GEOSERVERURL self.geoserverUserName = geoserverUserName if geoserverUserName != "" else GEOSERVERUSERNAME self.geoserverPW = geoserverPW if geoserverPW != "" else GEOSERVERPW self.geoserverWorkSpace = geoserverWorkSpace if geoserverWorkSpace != "" else "crc" self.postgreIP = postgreIP if postgreIP != "" else POSTGREIP self.postgreUserName = postgreUserName if postgreUserName != "" else POSTGREUSERNAME self.postgrePW = postgrePW if postgrePW != "" else POSTGREPW if self.geoserverUrl[-1] != '/': raise Exception("GeoserverUrl must end with a slash ('/')") self.catalog = Catalog(self.geoserverUrl+"rest/") self.catalog.http.add_credentials(self.geoserverUserName,self.geoserverPW) try: workspaces = self.catalog.get_workspaces() except: e = sys.exc_info()[0] print e self.cWorkSpace = self.catalog.get_workspace(self.geoserverWorkSpace) def getLayers(self): return self.cWorkSpace.catalog.get_layers() def insertShapeIntoPostGis(self, shapeFile, databaseName, tableName, encoding=3857): '''returns the returnCode of the execution of the insert script, e.g: helper.insertShapeIntoPostGis('/home/c815/gsTest/test.shp','crc','testingHelper2')''' if not os.path.isfile(shapeFile): print "Shape file not found" return -1 cmds = "PGPASSWORD={pgPW} ./createWSFTFromSHP.sh -s {shapeFileF} -d {databaseNameF} -t {tableNameF} -u {postgreUsername} -i {postgreIP}".format(pgPW=self.postgrePW, shapeFileF=shapeFile,databaseNameF=databaseName, tableNameF=tableName, postgreUsername=self.postgreUserName, postgreIP=self.postgreIP) return subprocess.call(cmds, shell=True) def uploadShapeFile(self, shapeFile, storeName): shpPlusSidcars = geoserver.util.shapefile_and_friends(shapeFile[:-3]) shpPlusSidcars self.ft = self.catalog.create_featurestore(storeName, shpPlusSidcars, self.cWorkSpace) def getStyles(self): return self.catalog.get_styles() def uploadStyleFile(self, sldFile, styleName, overWrite, workSpace = None): f = open(sldFile,'r') styleSrc = f.read() uploadStyle(styleSrc, styleName, overWrite, workSpace) f.close() def uploadStyle(self, sldSrc, styleName, overWrite, workSpace = None): self.catalog.create_style(styleName,sldSrc, overWrite, workSpace) def publishPostGISLayer(self,postGISLayerName, storeName, crs='EPSG:3857'): '''cat.publish_featuretype('testingstuff',crcStore,native_crs='EPSG:3857')''' store = self.catalog.get_store(storeName) if store != None: self.catalog.publish_featuretype(postGISLayerName, store, crs) def setDefaultStyleForLayer(self, layerName, styleName): l = self.catalog.get_layer(layerName) sNames = [ i.name for i in self.getStyles() ] if styleName not in sNames: split = styleName.split(':') if len(split) == 2: workSpace = styleName.split(':')[0] newStyleName = styleName.split(':')[1] else: return -1 style = self.catalog.get_style(newStyleName, workSpace) if style is None: return -1 if l != None: l._set_default_style(styleName) self.catalog.save(l) return 0 def createPostGISDataStore(self, storeName, postGisPassword, postGisUser, postGisHost, postGisDatabase, workSpace = None): #check if connection parameter are valid try: conn = psycopg2.connect("dbname='{dbName}' user='******' host='{Host}' password='******'".format(dbName=postGisDatabase, dbUser=postGisUser, Host=postGisHost, password=postGisPassword)) except: return False w = self.catalog.create_datastore(storeName, workSpace) template = Template("""{'validate connections': 'true', 'port': '5432', 'Support on the fly geometry simplification': 'true', 'create database': 'false', 'dbtype': 'postgis', 'Connection timeout': '20', 'namespace': 'http://www.crcproject.com', 'Max connection idle time': '300', 'Expose primary keys': 'false', 'min connections': '1', 'Max open prepared statements':'50', 'passwd': '$passwd', 'encode functions': 'false', 'max connections': '10', 'Evictor tests per run': '3', 'Loose bbox': 'true', 'Evictor run periodicity': '300', 'Estimated extends': 'true', 'database': '$database', 'fetch size': '1000', 'Test while idle': 'true', 'host': '$host', 'preparedStatements': 'false', 'schema': 'public', 'user': '******'}""") dic = ast.literal_eval(template.substitute( passwd=postGisPassword, user=postGisUser, host=postGisHost, database=postGisDatabase)) #'passwd': 'crypt1:Bsaz2AUI8T+6Pj43krA7kg==', #'user': '******'} #'database': 'crc', #'host': 'localhost', w.connection_parameters = dic self.catalog.save(w) return True
# written at 9:21, on 2017-12-20, helping function # removing the redundant layer groups - with vacant layers import os, sys from geoserver.catalog import Catalog geoserver_url = "http://172.18.77.15:8089/geoserver" cat = Catalog(geoserver_url + "/rest", username="******", password="******") # getting the names of all the existing workspaces srvr_wslist = cat.get_workspaces() for ws_obj in srvr_wslist: ws_name = ws_obj.name srvr_lyrgrplist = cat.get_layergroups(workspace=ws_obj) # check if all the related layers exists in the current layer group for grp_obj in srvr_lyrgrplist: for mbr_lyr_name in grp_obj.layers: if not cat.get_resource(mbr_lyr_name): cat.delete(grp_obj) print "Deleting group: ", grp_obj.name break # then removing all the layer groups with the appointed suffixes
class CatalogTests(unittest.TestCase): def setUp(self): self.cat = Catalog("http://localhost:8080/geoserver/rest") def testWorkspaces(self): self.assertEqual(7, len(self.cat.get_workspaces())) # marking out test since geoserver default workspace is not consistent # self.assertEqual("cite", self.cat.get_default_workspace().name) self.assertEqual("topp", self.cat.get_workspace("topp").name) def testStores(self): topp = self.cat.get_workspace("topp") sf = self.cat.get_workspace("sf") self.assertEqual(9, len(self.cat.get_stores())) self.assertEqual(2, len(self.cat.get_stores(topp))) self.assertEqual(2, len(self.cat.get_stores(sf))) self.assertEqual("states_shapefile", self.cat.get_store("states_shapefile", topp).name) self.assertEqual("states_shapefile", self.cat.get_store("states_shapefile").name) self.assertEqual("states_shapefile", self.cat.get_store("states_shapefile").name) self.assertEqual("sfdem", self.cat.get_store("sfdem", sf).name) self.assertEqual("sfdem", self.cat.get_store("sfdem").name) def testResources(self): topp = self.cat.get_workspace("topp") sf = self.cat.get_workspace("sf") states = self.cat.get_store("states_shapefile", topp) sfdem = self.cat.get_store("sfdem", sf) self.assertEqual(19, len(self.cat.get_resources())) self.assertEqual(1, len(self.cat.get_resources(states))) self.assertEqual(5, len(self.cat.get_resources(workspace=topp))) self.assertEqual(1, len(self.cat.get_resources(sfdem))) self.assertEqual(6, len(self.cat.get_resources(workspace=sf))) self.assertEqual("states", self.cat.get_resource("states", states).name) self.assertEqual("states", self.cat.get_resource("states", workspace=topp).name) self.assertEqual("states", self.cat.get_resource("states").name) states = self.cat.get_resource("states") fields = [ states.title, states.abstract, states.native_bbox, states.latlon_bbox, states.projection, states.projection_policy ] self.assertFalse(None in fields, str(fields)) self.assertFalse(len(states.keywords) == 0) self.assertFalse(len(states.attributes) == 0) self.assertTrue(states.enabled) self.assertEqual("sfdem", self.cat.get_resource("sfdem", sfdem).name) self.assertEqual("sfdem", self.cat.get_resource("sfdem", workspace=sf).name) self.assertEqual("sfdem", self.cat.get_resource("sfdem").name) def testLayers(self): expected = set(["Arc_Sample", "Pk50095", "Img_Sample", "mosaic", "sfdem", "bugsites", "restricted", "streams", "archsites", "roads", "tasmania_roads", "tasmania_water_bodies", "tasmania_state_boundaries", "tasmania_cities", "states", "poly_landmarks", "tiger_roads", "poi", "giant_polygon" ]) actual = set(l.name for l in self.cat.get_layers()) missing = expected - actual extras = actual - expected message = "Actual layer list did not match expected! (Extras: %s) (Missing: %s)" % (extras, missing) self.assert_(len(expected ^ actual) == 0, message) states = self.cat.get_layer("states") self.assert_("states", states.name) self.assert_(isinstance(states.resource, ResourceInfo)) self.assertEqual(set(s.name for s in states.styles), set(['pophatch', 'polygon'])) self.assertEqual(states.default_style.name, "population") def testLayerGroups(self): expected = set(["tasmania", "tiger-ny", "spearfish"]) actual = set(l.name for l in self.cat.get_layergroups()) missing = expected - actual extras = actual - expected message = "Actual layergroup list did not match expected! (Extras: %s) (Missing: %s)" % (extras, missing) self.assert_(len(expected ^ actual) == 0, message) tas = self.cat.get_layergroup("tasmania") self.assert_("tasmania", tas.name) self.assert_(isinstance(tas, LayerGroup)) self.assertEqual(tas.layers, ['tasmania_state_boundaries', 'tasmania_water_bodies', 'tasmania_roads', 'tasmania_cities'], tas.layers) self.assertEqual(tas.styles, [None, None, None, None], tas.styles) def testStyles(self): self.assertEqual(20, len(self.cat.get_styles())) self.assertEqual("population", self.cat.get_style("population").name)
if len(sys.argv) < 2: print 'USAGE: populate [GEOSERVER] [DBSERVER]' sys.exit(1) appserver = sys.argv[1] dbserver = sys.argv[2] ws_name = 'naturalearth' ds_name = 'ne_pg' lg_name = "ne_pg" cat = Catalog(appserver + '/rest') # check if workspace exists, bail if it does (safter than deleting it) if any(ws.name == ws_name for ws in cat.get_workspaces()): print 'workspace already exists...' ws = cat.get_workspace(ws_name) else: print 'creating workspace...' ws = cat.create_workspace(ws_name, 'http://www.naturalearth.org') if any(ds.workspace.name == ws.name and ds.name == ds_name for ds in cat.get_stores()): print 'datastore already exists...' ds = cat.get_store(ds_name, ws_name) else: print 'creating datastore' ds = cat.create_datastore(ds_name, ws.name) ds.connection_parameters.update( host=dbserver, port='5432',
class GsConn: def __init__(self, host, login, password, debug=False): """ Geoserver connection """ self.host = host self.login = login self.password = password self.debug = debug # Connect to server self.cat = Catalog("http://%s/geoserver/rest" % host, login, password) if self.debug is True: print "Connected to geoserver" def crate_workspace(self, name, overwrite=False): """ Creates a workspace :param name: Workspace name. :param overwrite: If True, delete existing workspace. :return: None """ workspaces = [workspace.name for workspace in self.cat.get_workspaces()] if name in workspaces and overwrite is True: # ws2del = self.cat.get_workspace(name) # self.cat.delete(ws2del, purge=True, recurse=True) return None # NOTE: If we delete the workspace then all associated layers are lost. elif name in workspaces and overwrite is False: print "ERROR: Workspace %s already exists (use overwrite=True)." % name self.cat.create_workspace(name, "http://%s/%s" % (self.host, name)) if self.debug is True: print "Workspace %s available." % name ws = self.cat.get_workspace(name) ws.enabled = True def create_pg_store(self, name, workspace, host, port, login, password, dbname, schema, overwrite=False): """ Creates datastore. :param name: Name of the datastore. :param workspace: Name of the workspace to use. :param overwrite: If True replace datastore. :return: None """ stores = [store.name for store in self.cat.get_stores()] if name in stores and overwrite is True: # st2del = self.cat.get_store(name) # self.cat.delete(st2del, purge=True, recurse=True) # self.cat.reload() return None # NOTE: If we delete store, every layers associated with are lost. elif name in stores and overwrite is False: print "ERROR: Store %s already exists (use overwrite=True)." % name ds = self.cat.create_datastore(name, workspace) ds.connection_parameters.update( host=host, port=port, user=login, passwd=password, dbtype="postgis", database=dbname, schema=schema ) self.cat.save(ds) ds = self.cat.get_store(name) if ds.enabled is False: print "ERROR: Geoserver store %s not enabled" % name if self.debug is True: print "Datastore %s created." % name def publish_pg_layer(self, layer_table, layer_name, store, srid, overwrite=True): """ """ existing_lyr = self.cat.get_layer("ma_carte:%s" % layer_table) if existing_lyr is not None: print "Layer ma_carte:%s already exists, deleting it." % layer_table self.cat.delete(existing_lyr) self.cat.reload() ds = self.cat.get_store(store) ft = self.cat.publish_featuretype(layer_table, ds, "EPSG:%s" % srid, srs="EPSG:4326") ft.projection_policy = "REPROJECT_TO_DECLARED" ft.title = layer_name self.cat.save(ft) if ft.enabled is False: print "ERROR: Layer %s %s %s is not enabled."(ft.workspace.name, ft.store.name, ft.title) if self.debug is True: print "Layer %s>%s>%s published." % (ft.workspace.name, ft.store.name, ft.title) def create_style_from_sld(self, style_name, sld_file, workspace, overwrite=True): """ """ if self.cat.get_style(style_name) is not None: print "Style %s already exists, deleting it." % style_name style2del = self.cat.get_style(style_name) self.cat.delete(style2del) self.cat.create_style( style_name, open(sld_file).read(), overwrite=overwrite ) # FIXME: if ", workspace=workspace" specified can't delete style if self.debug is True: print "Style %s created in Geoserver" % style_name def apply_style_to_layer(self, layer_name, style_name): """ Apply a geoserver styler to a layer """ gs_layer = self.cat.get_layer(layer_name) gs_style = self.cat.get_style(style_name) # FIXME: Which works better? # gs_layer.default_style = gs_style / gs_layer._set_default_style(gs_style) # FIXME: Maybe indicate workspace when saving style then name the style as "workspace:style" gs_layer._set_default_style(gs_style) self.cat.save(gs_layer) if self.debug is True: print "Style applied to %s" % layer_name
def create_workspace(server, username, password, workspace): cat = Catalog(server, username, password) if not workspace in [w.name for w in cat.get_workspaces()]: print 'Creating workspace: %s' % workspace cat.create_workspace(workspace, 'api.npolar.no/' + workspace)
class GeoServer(Server): """ Represents a server running GeoServer [1], an application that provides access to layers. This class provides a concrete implementation of the more generic Server component (which is intentionally generic). Currently the Server class does not dictate an interface for accessing resources but this class aims to present GeoServer specific components (such as workspaces) as generic components (such as namespaces). GeoServer instances typically represent individual instances (i.e. hosts are servers) rather than a wider and more abstract platform offered by a service provider. Information on layers and other resources are fetched using a combination of the GeoServer specific administrative API [2] accessed through geoserver-restconfig [3] and OGC services accessed through OWSLib [4] (and currently limited to WMS and WFS). [1] https://geoserver.readthedocs.io/en/latest/ [2] https://geoserver.readthedocs.io/en/latest/rest/index.html [3] https://pypi.org/project/geoserver-restconfig [4] https://pypi.org/project/OWSLib/ """ def __init__( self, server_id: str, label: str, hostname: str, port: str, api_path: str, wms_path: str, wfs_path: str, username: str, password: str, ): """ :param server_id: unique identifier, typically a ULID (Universally Unique Lexicographically Sortable Identifier) :param label: a human readable, well-known, identifier for the server - typically based on the hostname :param hostname: servers fully qualified hostname :param port: port on which GeoServer is running (usually '80' or '8080') :param api_path: URL path, relative to the root of the server, to the GeoServer API (usually '/geoserver/rest') :param wms_path: URL path, relative to the root of the server, to the GeoServer WMS endpoint (usually '/geoserver/ows?service=wms&version=1.3.0&request=GetCapabilities') :param wfs_path: URL path, relative to the root of the server, to the GeoServer WFS endpoint (usually '/geoserver/ows?service=wfs&version=2.0.0&request=GetCapabilities') :param username: username for account to use for GeoServer API :param password: password for account to use for GeoServer API """ endpoint = build_base_data_source_endpoint(data_source={ "hostname": hostname, "port": port }) self.client = Catalogue(service_url=f"{endpoint}{api_path}", username=username, password=password) self.wms = WebMapService(url=f"{endpoint}{wms_path}", version="1.3.0", username=username, password=password) self.wfs = WebFeatureService(url=f"{endpoint}{wfs_path}", version="2.0.0", username=username, password=password) super().__init__( server_id=server_id, label=label, hostname=hostname, server_type=ServerType.GEOSERVER.value, version=self._get_geoserver_version(), ) def get_namespaces(self) -> List[str]: """ Gets all GeoServer workspace names as Namespace labels :return: list of Namespace labels """ workspaces = [] for workspace in self.client.get_workspaces(): workspaces.append(workspace.name) return workspaces def get_namespace(self, namespace_reference: str) -> Dict[str, str]: """ Gets a specific workspace as a Namespace Note: GeoServer workspaces do not support the concept of a title, a static substitute value is therefore used Note: GeoServer workspaces do support the concept of a namespace, but it is not yet implemented [#28] :param namespace_reference: Namespace (workspace) label (name) :return: dictionary of Namespace information that can be made into a Namespace object """ workspace = self.client.get_workspace(name=namespace_reference) if workspace is None: raise KeyError( f"Namespace [{namespace_reference}] not found in server [{self.label}]" ) return {"label": workspace.name, "title": "-", "namespace": "-"} def get_repositories(self) -> List[Tuple[str, str]]: """ Gets all GeoServer store names as Repository labels :return: list of Repository:Namespace label tuples """ stores = [] # Passing workspaces here is a workaround for a bug in the get stores method where workspaces aren't specified. # The method says all workspaces should be checked but the logic to do this is in the wrong place so none are. for store in self.client.get_stores( workspaces=self.client.get_workspaces()): stores.append((store.name, store.workspace.name)) return stores def get_repository(self, repository_reference: str, namespace_reference: str) -> Dict[str, str]: """ Gets a specific store as a Repository If a Namespace (workspace) label is specified the Repository must exist within that Namespace. GeoServer store types are sometimes unsuitable or non-standard and so need to be mapped to a conventional value. in the RepositoryType enum using the GeoServerRepositoryType enum. Note: GeoServer stores do not support the concept of a title, a static substitute value is therefore used Note: Names (labels) will be returned for related components instead of identifiers or complete objects [#33] :param repository_reference: Repository (store) label (name) :param namespace_reference: Namespace (store) label (name) :return: dictionary of repository information that can be made into a Repository object """ _store = self.client.get_store(name=repository_reference, workspace=namespace_reference) if _store is None: raise KeyError( f"Repository [{repository_reference}] not found in server [{self.label}]" ) store = { "label": _store.name, "title": "-", "repository_type": RepositoryType[GeoServerRepositoryType(str( _store.type).lower()).name].value, "namespace_label": _store.workspace.name, } if hasattr(_store, "description") and _store.description is not None: store["title"] = _store.description if (store["repository_type"] == RepositoryType.POSTGIS.value or store["repository_type"] == RepositoryType.ORACLE.value): store["hostname"] = _store.connection_parameters["host"] store["database"] = _store.connection_parameters["database"] store["schema"] = _store.connection_parameters["schema"] return store def get_styles(self) -> List[Tuple[str, Optional[str]]]: """ Gets all GeoServer style names as Style labels Python's None value will be used to represent the Namespace of global styles (i.e that don't have a Namespace (workspace)). :return: list of Style:Namespace label tuples """ styles = [] for _style in self.client.get_styles(): styles.append((_style.name, _style.workspace)) return styles def get_style(self, style_reference: str, namespace_reference: str = None) -> Dict[str, str]: """ Gets a specific style as a Style If a Namespace (workspace) label is specified the Style must exist within that Namespace. Note: GeoServer styles do support the concept of a title, but it is not exposed through the admin API so a static substitute value is therefore used Note: Names (labels) will be returned for related components instead of identifiers or complete objects [#33] :param style_reference: Style (style) label (name) :param namespace_reference: Namespace (store) label (name) :return: dictionary of style information that can be made into a Style object """ _style = self.client.get_style(name=style_reference, workspace=namespace_reference) _type = str(_style.style_format).lower() if _type == "sld10": _type = "sld" style = { "label": _style.name, "title": "-", "style_type": _type, } if hasattr(_style, "workspace") and _style.workspace is not None: style["namespace_label"] = _style.workspace return style def get_layers(self) -> List[str]: """ Gets all GeoServer layer names as Layer labels :return: list of Layer labels """ layers = [] for _layer in self.client.get_layers(): layers.append(_layer.name) return layers def get_layer( self, layer_reference: str ) -> Dict[str, Union[Optional[str], List[str], List[Tuple[ str, Optional[str]]]]]: """ Gets a specific layer as a Layer Note: Names (labels) will be returned for related components instead of identifiers or complete objects [#33] :param layer_reference: Layer (layer) label (name) :return: dictionary of layer information that can be made into a Layer object """ _layer = self.client.get_layer(name=layer_reference) layer = { "label": _layer.resource.name, "title": _layer.resource.title, "layer_type": str(_layer.type).lower(), "geometry_type": None, "services": [], "table_view": None, "namespace_label": _layer.resource.workspace.name, "repository_label": _layer.resource.store.name, "style_labels": [(_layer.default_style.name, _layer.default_style.workspace)], } if layer_reference in list( self.wms.contents ) or f"{_layer.resource.workspace.name}:{layer_reference}" in list( self.wms.contents): layer["services"].append(LayerService.WMS.value) if layer_reference in list( self.wfs.contents ) or f"{_layer.resource.workspace.name}:{layer_reference}" in list( self.wfs.contents): layer["services"].append(LayerService.WFS.value) # WFS lookups don't seem to mind if the layer is namespaced or not _properties = self.wfs.get_schema(layer_reference) if "geometry" in _properties and isinstance( _properties["geometry"], str): try: layer["geometry_type"] = LayerGeometry[ GeoServerLayerGeometry(str( _properties["geometry"])).name].value except ValueError: raise ValueError( f"Geometry [{_properties['geometry']}] for layer {layer_reference} not mapped to " f"LayerGeometry enum.") elif "properties" in _properties: for geometry_column_name in GeoServerGeometryColumnNames: if geometry_column_name.value in _properties[ "properties"].keys(): try: layer["geometry_type"] = LayerGeometry[ GeoPropertyGeoServerLayerGeom( str(_properties["properties"][ geometry_column_name.value]) ).name].value except ValueError: raise ValueError( f"Geometry [{_properties['properties'][geometry_column_name.value]}] for layer " f"{layer_reference} in column '{geometry_column_name.value}' not mapped to " f"LayerGeometry enum.") if (str(_layer.resource.store.type).lower() == RepositoryType.POSTGIS.value or str(_layer.resource.store.type).lower() == RepositoryType.ORACLE.value): layer["table_view"] = _layer.resource.native_name return layer def get_layer_groups(self) -> List[Tuple[str, Optional[str]]]: """ Gets all GeoServer layer group names as LayerGroup labels Python's None value will be used to represent the Namespace of global layer groups (i.e that don't have a Namespace (workspace)). :return: list of LayerGroup:Namespace label tuples """ layer_groups = [] for _layer_group in self.client.get_layergroups( workspaces=self.client.get_workspaces()): layer_groups.append((_layer_group.name, _layer_group.workspace)) return layer_groups def get_layer_group( self, layer_group_reference: str, namespace_reference: str ) -> Dict[str, Union[Optional[str], List[str], List[Tuple[ str, Optional[str]]]]]: """ Gets a specific layer group as a LayerGroup If a Namespace (workspace) label is specified the LayerGroup must exist within that Namespace. Note: Names (labels) will be returned for related components instead of identifiers or complete objects [#33] :param layer_group_reference: LayerGroup (layer group) label (name) :param namespace_reference: Namespace (store) label (name) :return: dictionary of layer group information that can be made into a LayerGroup object """ _layer_group = self.client.get_layergroup( name=layer_group_reference, workspace=namespace_reference) layer_group = { "label": _layer_group.name, "title": _layer_group.title, "services": [], "namespace_label": _layer_group.workspace, "layer_labels": [], "style_labels": [], } for layer_label in _layer_group.layers: layer_label = layer_label.split(":") if len(layer_label) == 2: layer_group["layer_labels"].append( (layer_label[1], layer_label[0])) elif len(layer_label) == 1: layer_group["layer_labels"].append((layer_label[0], None)) if f"{namespace_reference}:{layer_group_reference}" in list( self.wms.contents): layer_group["services"].append(LayerService.WMS.value) if f"{namespace_reference}:{layer_group_reference}" in list( self.wfs.contents): layer_group["services"].append(LayerService.WFS.value) _properties = self.wfs.get_schema( f"{namespace_reference}:{layer_group_reference}") try: layer_group["geometry_type"] = LayerGeometry[ GeoServerLayerGeometry(str( _properties["geometry"])).name].value except ValueError: raise ValueError( f"Geometry [{_properties['geometry']}] not mapped to LayerGeometry enum." ) for style_label in _layer_group.styles: if style_label is not None: style_label = style_label.split(":") if len(style_label) == 2 and ( style_label[1], style_label[0]) not in layer_group["style_labels"]: layer_group["style_labels"].append( (style_label[1], style_label[0])) if len(style_label) == 1 and ( style_label[0], None) not in layer_group["style_labels"]: layer_group["style_labels"].append((style_label[0], None)) return layer_group def _get_geoserver_version(self) -> str: """ Gets the GeoServer version :return: GeoServer version string """ return self.client.get_version()
from geoserver.catalog import Catalog import os gspwd=os.environ['GS_ADMIN_PASS'] cat = Catalog("http://localhost:8080/geoserver/rest", "admin", gspwd) layers=cat.get_layers() print "............. All layers ........ " for eachl in layers: print eachl.name print ".............. Workspaces ........ " worksp=cat.get_workspaces() for wk in worksp: print wk.name print ".............. Stores ........ " stores=cat.get_stores() for st in stores: print st.name print ".............. Styles ........ " styles=cat.get_styles()
class CatalogTests(unittest.TestCase): def setUp(self): self.cat = Catalog(GSPARAMS['GSURL'], username=GSPARAMS['GSUSER'], password=GSPARAMS['GSPASSWORD']) def testAbout(self): about_html = self.cat.about() self.assertTrue( '<html xmlns="http://www.w3.org/1999/xhtml"' in str(about_html)) def testGSVersion(self): version = self.cat.gsversion() pat = re.compile('\d\.\d+(\.[\dx]|-SNAPSHOT)') self.assertTrue(pat.match('2.2.x')) self.assertTrue(pat.match('2.3.2')) self.assertTrue(pat.match('2.3-SNAPSHOT')) self.assertTrue(pat.match('2.10.1')) self.assertFalse(pat.match('2.3.y')) self.assertFalse(pat.match('233')) self.assertTrue(pat.match(version)) def testWorkspaces(self): self.assertEqual(7, len(self.cat.get_workspaces())) # marking out test since geoserver default workspace is not consistent # self.assertEqual("cite", self.cat.get_default_workspace().name) self.assertEqual("topp", self.cat.get_workspace("topp").name) self.assertEqual("topp", self.cat.get_workspaces("topp")[-1].name) self.assertEqual(2, len(self.cat.get_workspaces(names=['topp', 'sde']))) self.assertEqual(2, len(self.cat.get_workspaces(names='topp, sde'))) def testStores(self): self.assertEqual(0, len(self.cat.get_stores("nonexistentstore"))) topp = self.cat.get_workspace("topp") sf = self.cat.get_workspace("sf") self.assertEqual(9, len(self.cat.get_stores())) self.assertEqual(2, len(self.cat.get_stores(workspace=topp))) self.assertEqual(2, len(self.cat.get_stores(workspace=sf))) self.assertEqual(2, len(self.cat.get_stores(workspace='sf'))) self.assertEqual( 2, len(self.cat.get_stores(names='states_shapefile, sfdem'))) self.assertEqual( 2, len(self.cat.get_stores(names=['states_shapefile', 'sfdem']))) self.assertEqual("sfdem", self.cat.get_stores("sfdem")[-1].name) self.assertEqual("states_shapefile", self.cat.get_store("states_shapefile", topp).name) self.assertEqual("states_shapefile", self.cat.get_store("states_shapefile").name) self.assertEqual("states_shapefile", self.cat.get_store("states_shapefile", "topp").name) self.assertEqual("sfdem", self.cat.get_store("sfdem", sf).name) self.assertEqual("sfdem", self.cat.get_store("sfdem").name) def testResources(self): topp = self.cat.get_workspace("topp") sf = self.cat.get_workspace("sf") states = self.cat.get_store("states_shapefile", topp) sfdem = self.cat.get_store("sfdem", sf) self.assertEqual(19, len(self.cat.get_resources())) self.assertEqual(1, len(self.cat.get_resources(states))) self.assertEqual(5, len(self.cat.get_resources(workspace=topp))) self.assertEqual(1, len(self.cat.get_resources(sfdem))) self.assertEqual(6, len(self.cat.get_resources(workspace=sf))) self.assertEqual("states", self.cat.get_resource("states", states).name) self.assertEqual("states", self.cat.get_resource("states", workspace=topp).name) self.assertEqual("states", self.cat.get_resource("states").name) states = self.cat.get_resource("states") fields = [ states.title, states.abstract, states.native_bbox, states.latlon_bbox, states.projection, states.projection_policy ] self.assertFalse(None in fields, str(fields)) self.assertFalse(len(states.keywords) == 0) self.assertFalse(len(states.attributes) == 0) self.assertTrue(states.enabled) self.assertEqual("sfdem", self.cat.get_resource("sfdem", sfdem).name) self.assertEqual("sfdem", self.cat.get_resource("sfdem", workspace=sf).name) self.assertEqual("sfdem", self.cat.get_resource("sfdem").name) def testResourcesUpdate(self): res_dest = self.cat.get_resources() count = 0 for rd in res_dest: # only wms layers if rd.resource_type != "wmsLayer": continue # looking for same name ro = self.cat.get_resource(rd.name) if ro is not None: rd.title = ro.title rd.abstract = ro.abstract rd.keywords = ro.keywords rd.projection = ro.projection rd.native_bbox = ro.native_bbox rd.latlon_bbox = ro.latlon_bbox rd.projection_policy = ro.projection_policy rd.enabled = ro.enabled rd.advertised = ro.advertised rd.metadata_links = ro.metadata_links or None self.cat.save(rd) self.cat.reload() # print "Updated layer: " + rd.name count += 1 # print "Total updated layers: " + str(count) def testLayers(self): expected = set([ "Arc_Sample", "Pk50095", "Img_Sample", "mosaic", "sfdem", "bugsites", "restricted", "streams", "archsites", "roads", "tasmania_roads", "tasmania_water_bodies", "tasmania_state_boundaries", "tasmania_cities", "states", "poly_landmarks", "tiger_roads", "poi", "giant_polygon" ]) actual = set(l.name for l in self.cat.get_layers()) missing = expected - actual extras = actual - expected message = "Actual layer list did not match expected! (Extras: %s) (Missing: %s)" % ( extras, missing) self.assertTrue(len(expected ^ actual) == 0, message) states = self.cat.get_layer("states") self.assertEqual("states", states.name) self.assertIsInstance(states.resource, ResourceInfo) self.assertEqual(set(s.name for s in states.styles), set(['pophatch', 'polygon'])) self.assertEqual(states.default_style.name, "population") def testLayerGroups(self): expected = set(["tasmania", "tiger-ny", "spearfish"]) actual = set(l.name for l in self.cat.get_layergroups()) missing = expected - actual extras = actual - expected message = "Actual layergroup list did not match expected! (Extras: %s) (Missing: %s)" % ( extras, missing) self.assertTrue(len(expected ^ actual) == 0, message) tas = self.cat.get_layergroup("tasmania") self.assertEqual("tasmania", tas.name) self.assertIsInstance(tas, LayerGroup) self.assertEqual(tas.layers, [ 'tasmania_state_boundaries', 'tasmania_water_bodies', 'tasmania_roads', 'tasmania_cities' ], tas.layers) self.assertEqual(tas.styles, [None, None, None, None], tas.styles) # Try to create a new Layer Group into the "topp" workspace self.assertIsNotNone(self.cat.get_workspace("topp")) tas2 = self.cat.create_layergroup("tasmania_reloaded", tas.layers, workspace="topp") self.cat.save(tas2) self.assertIsNone(self.cat.get_layergroup("tasmania_reloaded")) self.assertIsNotNone( self.cat.get_layergroup("tasmania_reloaded", "topp")) tas2 = self.cat.get_layergroup("tasmania_reloaded", "topp") self.assertEqual("tasmania_reloaded", tas2.name) self.assertIsInstance(tas2, LayerGroup) self.assertEqual(tas2.workspace, "topp", tas2.workspace) self.assertEqual(tas2.layers, [ 'tasmania_state_boundaries', 'tasmania_water_bodies', 'tasmania_roads', 'tasmania_cities' ], tas2.layers) self.assertEqual(tas2.styles, [None, None, None, None], tas2.styles) def testStyles(self): self.assertEqual("population", self.cat.get_style("population").name) self.assertEqual("popshade.sld", self.cat.get_style("population").filename) self.assertEqual("population", self.cat.get_style("population").sld_name) self.assertIsNone(self.cat.get_style('non-existing-style')) def testEscaping(self): # GSConfig is inconsistent about using exceptions vs. returning None # when a resource isn't found. # But the basic idea is that none of them should throw HTTP errors from # misconstructed URLS self.cat.get_style("best style ever") self.cat.get_workspace("best workspace ever") self.assertEqual( self.cat.get_store(workspace="best workspace ever", name="best store ever"), None) self.cat.get_layer("best layer ever") self.cat.get_layergroup("best layergroup ever") def testUnicodeUrl(self): """ Tests that the geoserver.support.url function support unicode strings. """ # Test the url function with unicode seg = [ 'workspaces', 'test', 'datastores', u'operaci\xf3n_repo', 'featuretypes.xml' ] u = url(base=self.cat.service_url, seg=seg) self.assertEqual( u, self.cat.service_url + "/workspaces/test/datastores/operaci%C3%B3n_repo/featuretypes.xml") # Test the url function with normal string seg = [ 'workspaces', 'test', 'datastores', 'test-repo', 'featuretypes.xml' ] u = url(base=self.cat.service_url, seg=seg) self.assertEqual( u, self.cat.service_url + "/workspaces/test/datastores/test-repo/featuretypes.xml")
class GeoserverHelper: def __init__(self, geoserverUrl="", geoserverUserName="", geoserverPW="", geoserverWorkSpace="", postgreIP="", postgreUserName="", postgrePW=""): """use the constructor given arguments if used""" self.geoserverUrl = geoserverUrl if geoserverUrl != "" else GEOSERVERURL self.geoserverUserName = geoserverUserName if geoserverUserName != "" else GEOSERVERUSERNAME self.geoserverPW = geoserverPW if geoserverPW != "" else GEOSERVERPW self.geoserverWorkSpace = geoserverWorkSpace if geoserverWorkSpace != "" else "crc" self.postgreIP = postgreIP if postgreIP != "" else POSTGREIP self.postgreUserName = postgreUserName if postgreUserName != "" else POSTGREUSERNAME self.postgrePW = postgrePW if postgrePW != "" else POSTGREPW if self.geoserverUrl[-1] != '/': raise Exception("GeoserverUrl must end with a slash ('/')") self.catalog = Catalog(self.geoserverUrl + "rest/") self.catalog.http.add_credentials(self.geoserverUserName, self.geoserverPW) try: workspaces = self.catalog.get_workspaces() except: e = sys.exc_info()[0] print e self.cWorkSpace = self.catalog.get_workspace(self.geoserverWorkSpace) def getLayers(self): return self.cWorkSpace.catalog.get_layers() def insertShapeIntoPostGis(self, shapeFile, databaseName, tableName, encoding=3857): '''returns the returnCode of the execution of the insert script, e.g: helper.insertShapeIntoPostGis('/home/c815/gsTest/test.shp','crc','testingHelper2')''' if not os.path.isfile(shapeFile): print "Shape file not found" return -1 cmds = "PGPASSWORD={pgPW} ./createWSFTFromSHP.sh -s {shapeFileF} -d {databaseNameF} -t {tableNameF} -u {postgreUsername} -i {postgreIP}".format( pgPW=self.postgrePW, shapeFileF=shapeFile, databaseNameF=databaseName, tableNameF=tableName, postgreUsername=self.postgreUserName, postgreIP=self.postgreIP) return subprocess.call(cmds, shell=True) def uploadShapeFile(self, shapeFile, storeName): shpPlusSidcars = geoserver.util.shapefile_and_friends(shapeFile[:-3]) shpPlusSidcars self.ft = self.catalog.create_featurestore(storeName, shpPlusSidcars, self.cWorkSpace) def getStyles(self): return self.catalog.get_styles() def uploadStyleFile(self, sldFile, styleName, overWrite, workSpace=None): f = open(sldFile, 'r') styleSrc = f.read() uploadStyle(styleSrc, styleName, overWrite, workSpace) f.close() def uploadStyle(self, sldSrc, styleName, overWrite, workSpace=None): self.catalog.create_style(styleName, sldSrc, overWrite, workSpace) def publishPostGISLayer(self, postGISLayerName, storeName, crs='EPSG:3857'): '''cat.publish_featuretype('testingstuff',crcStore,native_crs='EPSG:3857')''' store = self.catalog.get_store(storeName) if store != None: self.catalog.publish_featuretype(postGISLayerName, store, crs) def setDefaultStyleForLayer(self, layerName, styleName): l = self.catalog.get_layer(layerName) sNames = [i.name for i in self.getStyles()] if styleName not in sNames: split = styleName.split(':') if len(split) == 2: workSpace = styleName.split(':')[0] newStyleName = styleName.split(':')[1] else: return -1 style = self.catalog.get_style(newStyleName, workSpace) if style is None: return -1 if l != None: l._set_default_style(styleName) self.catalog.save(l) return 0 def createPostGISDataStore(self, storeName, postGisPassword, postGisUser, postGisHost, postGisDatabase, workSpace=None): #check if connection parameter are valid try: conn = psycopg2.connect( "dbname='{dbName}' user='******' host='{Host}' password='******'" .format(dbName=postGisDatabase, dbUser=postGisUser, Host=postGisHost, password=postGisPassword)) except: return False w = self.catalog.create_datastore(storeName, workSpace) template = Template( """{'validate connections': 'true', 'port': '5432', 'Support on the fly geometry simplification': 'true', 'create database': 'false', 'dbtype': 'postgis', 'Connection timeout': '20', 'namespace': 'http://www.crcproject.com', 'Max connection idle time': '300', 'Expose primary keys': 'false', 'min connections': '1', 'Max open prepared statements':'50', 'passwd': '$passwd', 'encode functions': 'false', 'max connections': '10', 'Evictor tests per run': '3', 'Loose bbox': 'true', 'Evictor run periodicity': '300', 'Estimated extends': 'true', 'database': '$database', 'fetch size': '1000', 'Test while idle': 'true', 'host': '$host', 'preparedStatements': 'false', 'schema': 'public', 'user': '******'}""") dic = ast.literal_eval( template.substitute(passwd=postGisPassword, user=postGisUser, host=postGisHost, database=postGisDatabase)) #'passwd': 'crypt1:Bsaz2AUI8T+6Pj43krA7kg==', #'user': '******'} #'database': 'crc', #'host': 'localhost', w.connection_parameters = dic self.catalog.save(w) return True
class CatalogTests(unittest.TestCase): def setUp(self): self.cat = Catalog(GSPARAMS['GSURL'], username=GSPARAMS['GSUSER'], password=GSPARAMS['GSPASSWORD']) def testAbout(self): about_html = self.cat.about() self.assertTrue('<html xmlns="http://www.w3.org/1999/xhtml"' in about_html) def testGSVersion(self): version = self.cat.gsversion() pat = re.compile('\d\.\d(\.[\dx]|-SNAPSHOT)') self.assertTrue(pat.match('2.2.x')) self.assertTrue(pat.match('2.3.2')) self.assertTrue(pat.match('2.3-SNAPSHOT')) self.assertFalse(pat.match('2.3.y')) self.assertFalse(pat.match('233')) self.assertTrue(pat.match(version)) def testWorkspaces(self): self.assertEqual(7, len(self.cat.get_workspaces())) # marking out test since geoserver default workspace is not consistent # self.assertEqual("cite", self.cat.get_default_workspace().name) self.assertEqual("topp", self.cat.get_workspace("topp").name) def testStores(self): topp = self.cat.get_workspace("topp") sf = self.cat.get_workspace("sf") self.assertEqual(9, len(self.cat.get_stores())) self.assertEqual(2, len(self.cat.get_stores(topp))) self.assertEqual(2, len(self.cat.get_stores(sf))) self.assertEqual("states_shapefile", self.cat.get_store("states_shapefile", topp).name) self.assertEqual("states_shapefile", self.cat.get_store("states_shapefile").name) self.assertEqual("states_shapefile", self.cat.get_store("states_shapefile").name) self.assertEqual("sfdem", self.cat.get_store("sfdem", sf).name) self.assertEqual("sfdem", self.cat.get_store("sfdem").name) def testResources(self): topp = self.cat.get_workspace("topp") sf = self.cat.get_workspace("sf") states = self.cat.get_store("states_shapefile", topp) sfdem = self.cat.get_store("sfdem", sf) self.assertEqual(19, len(self.cat.get_resources())) self.assertEqual(1, len(self.cat.get_resources(states))) self.assertEqual(5, len(self.cat.get_resources(workspace=topp))) self.assertEqual(1, len(self.cat.get_resources(sfdem))) self.assertEqual(6, len(self.cat.get_resources(workspace=sf))) self.assertEqual("states", self.cat.get_resource("states", states).name) self.assertEqual("states", self.cat.get_resource("states", workspace=topp).name) self.assertEqual("states", self.cat.get_resource("states").name) states = self.cat.get_resource("states") fields = [ states.title, states.abstract, states.native_bbox, states.latlon_bbox, states.projection, states.projection_policy ] self.assertFalse(None in fields, str(fields)) self.assertFalse(len(states.keywords) == 0) self.assertFalse(len(states.attributes) == 0) self.assertTrue(states.enabled) self.assertEqual("sfdem", self.cat.get_resource("sfdem", sfdem).name) self.assertEqual("sfdem", self.cat.get_resource("sfdem", workspace=sf).name) self.assertEqual("sfdem", self.cat.get_resource("sfdem").name) def testResourcesUpdate(self): res_dest = self.cat.get_resources() count = 0 for rd in res_dest: # only wms layers if rd.resource_type != "wmsLayer": continue # looking for same name ro = self.cat.get_resource(rd.name) if ro is not None: rd.title = ro.title rd.abstract = ro.abstract rd.keywords = ro.keywords rd.projection = ro.projection rd.native_bbox = ro.native_bbox rd.latlon_bbox = ro.latlon_bbox rd.projection_policy = ro.projection_policy rd.enabled = ro.enabled rd.advertised = ro.advertised rd.metadata_links = ro.metadata_links or None self.cat.save(rd) self.cat.reload() # print "Updated layer: " + rd.name count += 1 # print "Total updated layers: " + str(count) def testLayers(self): expected = set(["Arc_Sample", "Pk50095", "Img_Sample", "mosaic", "sfdem", "bugsites", "restricted", "streams", "archsites", "roads", "tasmania_roads", "tasmania_water_bodies", "tasmania_state_boundaries", "tasmania_cities", "states", "poly_landmarks", "tiger_roads", "poi", "giant_polygon" ]) actual = set(l.name for l in self.cat.get_layers()) missing = expected - actual extras = actual - expected message = "Actual layer list did not match expected! (Extras: %s) (Missing: %s)" % (extras, missing) self.assert_(len(expected ^ actual) == 0, message) states = self.cat.get_layer("states") self.assert_("states", states.name) self.assert_(isinstance(states.resource, ResourceInfo)) self.assertEqual(set(s.name for s in states.styles), set(['pophatch', 'polygon'])) self.assertEqual(states.default_style.name, "population") def testLayerGroups(self): expected = set(["tasmania", "tiger-ny", "spearfish"]) actual = set(l.name for l in self.cat.get_layergroups()) missing = expected - actual extras = actual - expected message = "Actual layergroup list did not match expected! (Extras: %s) (Missing: %s)" % (extras, missing) self.assert_(len(expected ^ actual) == 0, message) tas = self.cat.get_layergroup("tasmania") self.assert_("tasmania", tas.name) self.assert_(isinstance(tas, LayerGroup)) self.assertEqual(tas.layers, ['tasmania_state_boundaries', 'tasmania_water_bodies', 'tasmania_roads', 'tasmania_cities'], tas.layers) self.assertEqual(tas.styles, [None, None, None, None], tas.styles) # Try to create a new Layer Group into the "topp" workspace self.assert_(self.cat.get_workspace("topp") is not None) tas2 = self.cat.create_layergroup("tasmania_reloaded", tas.layers, workspace = "topp") self.cat.save(tas2) self.assert_(self.cat.get_layergroup("tasmania_reloaded") is None) self.assert_(self.cat.get_layergroup("tasmania_reloaded", "topp") is not None) tas2 = self.cat.get_layergroup("tasmania_reloaded", "topp") self.assert_("tasmania_reloaded", tas2.name) self.assert_(isinstance(tas2, LayerGroup)) self.assertEqual(tas2.workspace, "topp", tas2.workspace) self.assertEqual(tas2.layers, ['tasmania_state_boundaries', 'tasmania_water_bodies', 'tasmania_roads', 'tasmania_cities'], tas2.layers) self.assertEqual(tas2.styles, [None, None, None, None], tas2.styles) def testStyles(self): self.assertEqual("population", self.cat.get_style("population").name) self.assertEqual("popshade.sld", self.cat.get_style("population").filename) self.assertEqual("population", self.cat.get_style("population").sld_name) self.assert_(self.cat.get_style('non-existing-style') is None) def testEscaping(self): # GSConfig is inconsistent about using exceptions vs. returning None # when a resource isn't found. # But the basic idea is that none of them should throw HTTP errors from # misconstructed URLS self.cat.get_style("best style ever") self.cat.get_workspace("best workspace ever") try: self.cat.get_store(workspace="best workspace ever", name="best store ever") self.fail('expected exception') except FailedRequestError, fre: self.assertEqual('No store found named: best store ever', fre.message) try: self.cat.get_resource(workspace="best workspace ever", store="best store ever", name="best resource ever") except FailedRequestError, fre: self.assertEqual('No store found named: best store ever', fre.message)
class CatalogTests(unittest.TestCase): def setUp(self): self.cat = Catalog(GSPARAMS['GSURL'], username=GSPARAMS['GSUSER'], password=GSPARAMS['GSPASSWORD']) self.gs_version = self.cat.get_short_version() def testGSVersion(self): version = self.cat.get_version() pat = re.compile('\d\.\d+') self.assertTrue(pat.match('2.2.x')) self.assertTrue(pat.match('2.3.2')) self.assertTrue(pat.match('2.3-SNAPSHOT')) self.assertTrue(pat.match(version)) def testWorkspaces(self): self.assertEqual(7, len(self.cat.get_workspaces())) # marking out test since geoserver default workspace is not consistent # self.assertEqual("cite", self.cat.get_default_workspace().name) self.assertEqual("topp", self.cat.get_workspaces(names="topp")[-1].name) self.assertEqual(2, len(self.cat.get_workspaces(names=['topp', 'sde']))) self.assertEqual(2, len(self.cat.get_workspaces(names='topp, sde'))) self.assertEqual("topp", self.cat.get_workspace("topp").name) self.assertIsNone(self.cat.get_workspace("blahblah-")) def testStores(self): self.assertEqual(0, len(self.cat.get_stores(names="nonexistentstore"))) topp = self.cat.get_workspaces("topp")[0] sf = self.cat.get_workspaces("sf")[0] self.assertEqual(9, len(self.cat.get_stores())) self.assertEqual(2, len(self.cat.get_stores(workspaces=topp))) self.assertEqual(2, len(self.cat.get_stores(workspaces=sf))) self.assertEqual(2, len(self.cat.get_stores(workspaces='sf'))) self.assertEqual(2, len(self.cat.get_stores(names='states_shapefile, sfdem'))) self.assertEqual(2, len(self.cat.get_stores(names=['states_shapefile', 'sfdem']))) self.assertEqual("states_shapefile", self.cat.get_stores(names="states_shapefile", workspaces=topp.name)[0].name) self.assertEqual("states_shapefile", self.cat.get_stores(names="states_shapefile")[0].name) self.assertEqual("sfdem", self.cat.get_stores(names="sfdem", workspaces=sf.name)[0].name) self.assertEqual("sfdem", self.cat.get_stores(names="sfdem")[0].name) self.assertEqual("sfdem", self.cat.get_store("sfdem").name) self.assertIsNone(self.cat.get_store("blah+blah-")) def testResources(self): topp = self.cat.get_workspaces("topp")[0] sf = self.cat.get_workspaces("sf")[0] states = self.cat.get_stores(names="states_shapefile", workspaces=topp.name)[0] sfdem = self.cat.get_stores(names="sfdem", workspaces=sf.name)[0] self.assertEqual(19, len(self.cat.get_resources())) self.assertEqual(2, len(self.cat.get_resources(stores=[states.name, sfdem.name]))) self.assertEqual(11, len(self.cat.get_resources(workspaces=[topp.name, sf.name]))) self.assertEqual("states", self.cat.get_resources(names="states", stores=states.name)[0].name) self.assertEqual("states", self.cat.get_resources(names="states", workspaces=topp.name)[0].name) self.assertEqual("states", self.cat.get_resources(names="states")[0].name) self.assertEqual("states", self.cat.get_resource("states").name) self.assertIsNone(self.cat.get_resource("blah+1blah-2")) states = self.cat.get_resources(names="states")[0] fields = [ states.title, states.abstract, states.native_bbox, states.latlon_bbox, states.projection, states.projection_policy ] self.assertFalse(None in fields, str(fields)) self.assertFalse(len(states.keywords) == 0) self.assertFalse(len(states.attributes) == 0) self.assertTrue(states.enabled) self.assertEqual("sfdem", self.cat.get_resources(names="sfdem", stores=sfdem.name)[0].name) self.assertEqual("sfdem", self.cat.get_resources(names="sfdem", workspaces=sf.name)[0].name) self.assertEqual("sfdem", self.cat.get_resources(names="sfdem")[0].name) def testResourcesUpdate(self): res_dest = self.cat.get_resources() count = 0 for rd in res_dest: # only wms layers if rd.resource_type != "wmsLayer": continue # looking for same name ro = self.cat.get_resources(names=rd.name) if ro is not None: rd.title = ro.title rd.abstract = ro.abstract rd.keywords = ro.keywords rd.projection = ro.projection rd.native_bbox = ro.native_bbox rd.latlon_bbox = ro.latlon_bbox rd.projection_policy = ro.projection_policy rd.enabled = ro.enabled rd.advertised = ro.advertised rd.metadata_links = ro.metadata_links or None self.cat.save(rd) self.cat.reload() count += 1 def testLayers(self): if self.gs_version >= "2.13": expected = set([ 'sf:roads', 'sf:sfdem', 'nurc:mosaic', 'tiger:giant_polygon', 'sf:bugsites', 'topp:states', 'sf:streams', 'tiger:poly_landmarks', 'tiger:poi', 'topp:tasmania_water_bodies', 'tiger:tiger_roads', 'topp:tasmania_roads', 'nurc:Pk50095', 'topp:tasmania_cities', 'nurc:Img_Sample', 'sf:restricted', 'nurc:Arc_Sample', 'sf:archsites', 'topp:tasmania_state_boundaries' ]) else: expected = set([ "Arc_Sample", "Pk50095", "Img_Sample", "mosaic", "sfdem", "bugsites", "restricted", "streams", "archsites", "roads", "tasmania_roads", "tasmania_water_bodies", "tasmania_state_boundaries", "tasmania_cities", "states", "poly_landmarks", "tiger_roads", "poi", "giant_polygon" ]) actual = set(l.name for l in self.cat.get_layers()) missing = expected - actual extras = actual - expected message = "Actual layer list did not match expected! (Extras: %s) (Missing: %s)" % (extras, missing) self.assert_(len(expected ^ actual) == 0, message) states = self.cat.get_layer("states") self.assert_("states", states.name) self.assert_(isinstance(states.resource, ResourceInfo)) self.assertEqual(set(s.name for s in states.styles), set(['pophatch', 'polygon'])) self.assertEqual(states.default_style.name, "population") def testLayerGroups(self): expected = set(["tasmania", "tiger-ny", "spearfish"]) actual = set(l.name for l in self.cat.get_layergroups(names=["tasmania", "tiger-ny", "spearfish"])) missing = expected - actual extras = actual - expected message = "Actual layergroup list did not match expected! (Extras: %s) (Missing: %s)" % (extras, missing) self.assert_(len(expected ^ actual) == 0, message) tas = self.cat.get_layergroups(names="tasmania")[0] self.assert_("tasmania", tas.name) self.assert_(isinstance(tas, LayerGroup)) if self.gs_version >= "2.13": self.assertEqual(tas.layers, [ 'topp:tasmania_state_boundaries', 'topp:tasmania_water_bodies', 'topp:tasmania_roads', 'topp:tasmania_cities' ], tas.layers) else: self.assertEqual(tas.layers, [ 'tasmania_state_boundaries', 'tasmania_water_bodies', 'tasmania_roads', 'tasmania_cities' ], tas.layers) self.assertEqual(tas.styles, [None, None, None, None], tas.styles) # Try to create a new Layer Group into the "topp" workspace self.assert_(self.cat.get_workspaces("topp")[0] is not None) tas2 = self.cat.create_layergroup("tasmania_reloaded", tas.layers, workspace = "topp") self.cat.save(tas2) self.assertEqual(1, len(self.cat.get_layergroups(names='tasmania_reloaded', workspaces="topp"))) tas2 = self.cat.get_layergroups(names='tasmania_reloaded', workspaces="topp")[0] self.assert_("tasmania_reloaded", tas2.name) self.assert_(isinstance(tas2, LayerGroup)) self.assertEqual(tas2.workspace, "topp", tas2.workspace) if self.gs_version >= "2.13": self.assertEqual(tas2.layers, [ 'topp:tasmania_state_boundaries', 'topp:tasmania_water_bodies', 'topp:tasmania_roads', 'topp:tasmania_cities' ], tas2.layers) else: self.assertEqual(tas2.layers, [ 'tasmania_state_boundaries', 'tasmania_water_bodies', 'tasmania_roads', 'tasmania_cities' ], tas2.layers) self.assertEqual(tas2.styles, [None, None, None, None], tas2.styles) def testStyles(self): self.assertEqual("population", self.cat.get_styles("population")[0].name) self.assertEqual("popshade.sld", self.cat.get_styles("population")[0].filename) self.assertEqual("population", self.cat.get_styles("population")[0].sld_name) self.assertEqual("population", self.cat.get_style("population").sld_name) self.assertIsNone(self.cat.get_style("blah+#5blah-")) self.assertEqual(0, len(self.cat.get_styles('non-existing-style'))) def testEscaping(self): # GSConfig is inconsistent about using exceptions vs. returning None # when a resource isn't found. # But the basic idea is that none of them should throw HTTP errors from # misconstructed URLS self.cat.get_styles("best style ever") self.cat.get_workspaces("best workspace ever") self.assertEqual(0, len(self.cat.get_stores(workspaces="best workspace ever", names="best store ever"))) self.cat.get_layer("best layer ever") self.cat.get_layergroups("best layergroup ever") def testUnicodeUrl(self): """ Tests that the geoserver.support.url function support unicode strings. """ # Test the url function with unicode seg = ['workspaces', 'test', 'datastores', u'operaci\xf3n_repo', 'featuretypes.xml'] u = build_url(base=self.cat.service_url, seg=seg) self.assertEqual(u, self.cat.service_url + "/workspaces/test/datastores/operaci%C3%B3n_repo/featuretypes.xml") # Test the url function with normal string seg = ['workspaces', 'test', 'datastores', 'test-repo', 'featuretypes.xml'] u = build_url(base=self.cat.service_url, seg=seg) self.assertEqual(u, self.cat.service_url + "/workspaces/test/datastores/test-repo/featuretypes.xml")
class CatalogTests(unittest.TestCase): def setUp(self): self.cat = Catalog("http://localhost:8080/geoserver/rest") def testAbout(self): about_html = self.cat.about() self.assertTrue( '<html xmlns="http://www.w3.org/1999/xhtml"' in about_html) def testGSVersion(self): version = self.cat.gsversion() pat = re.compile('\d\.\d(\.[\dx]|-SNAPSHOT)') self.assertTrue(pat.match('2.2.x')) self.assertTrue(pat.match('2.3.2')) self.assertTrue(pat.match('2.3-SNAPSHOT')) self.assertFalse(pat.match('2.3.y')) self.assertFalse(pat.match('233')) self.assertTrue(pat.match(version)) def testWorkspaces(self): self.assertEqual(7, len(self.cat.get_workspaces())) # marking out test since geoserver default workspace is not consistent # self.assertEqual("cite", self.cat.get_default_workspace().name) self.assertEqual("topp", self.cat.get_workspace("topp").name) def testStores(self): topp = self.cat.get_workspace("topp") sf = self.cat.get_workspace("sf") self.assertEqual(9, len(self.cat.get_stores())) self.assertEqual(2, len(self.cat.get_stores(topp))) self.assertEqual(2, len(self.cat.get_stores(sf))) self.assertEqual("states_shapefile", self.cat.get_store("states_shapefile", topp).name) self.assertEqual("states_shapefile", self.cat.get_store("states_shapefile").name) self.assertEqual("states_shapefile", self.cat.get_store("states_shapefile").name) self.assertEqual("sfdem", self.cat.get_store("sfdem", sf).name) self.assertEqual("sfdem", self.cat.get_store("sfdem").name) def testResources(self): topp = self.cat.get_workspace("topp") sf = self.cat.get_workspace("sf") states = self.cat.get_store("states_shapefile", topp) sfdem = self.cat.get_store("sfdem", sf) self.assertEqual(19, len(self.cat.get_resources())) self.assertEqual(1, len(self.cat.get_resources(states))) self.assertEqual(5, len(self.cat.get_resources(workspace=topp))) self.assertEqual(1, len(self.cat.get_resources(sfdem))) self.assertEqual(6, len(self.cat.get_resources(workspace=sf))) self.assertEqual("states", self.cat.get_resource("states", states).name) self.assertEqual("states", self.cat.get_resource("states", workspace=topp).name) self.assertEqual("states", self.cat.get_resource("states").name) states = self.cat.get_resource("states") fields = [ states.title, states.abstract, states.native_bbox, states.latlon_bbox, states.projection, states.projection_policy ] self.assertFalse(None in fields, str(fields)) self.assertFalse(len(states.keywords) == 0) self.assertFalse(len(states.attributes) == 0) self.assertTrue(states.enabled) self.assertEqual("sfdem", self.cat.get_resource("sfdem", sfdem).name) self.assertEqual("sfdem", self.cat.get_resource("sfdem", workspace=sf).name) self.assertEqual("sfdem", self.cat.get_resource("sfdem").name) def testLayers(self): expected = set([ "Arc_Sample", "Pk50095", "Img_Sample", "mosaic", "sfdem", "bugsites", "restricted", "streams", "archsites", "roads", "tasmania_roads", "tasmania_water_bodies", "tasmania_state_boundaries", "tasmania_cities", "states", "poly_landmarks", "tiger_roads", "poi", "giant_polygon" ]) actual = set(l.name for l in self.cat.get_layers()) missing = expected - actual extras = actual - expected message = "Actual layer list did not match expected! (Extras: %s) (Missing: %s)" % ( extras, missing) self.assert_(len(expected ^ actual) == 0, message) states = self.cat.get_layer("states") self.assert_("states", states.name) self.assert_(isinstance(states.resource, ResourceInfo)) self.assertEqual(set(s.name for s in states.styles), set(['pophatch', 'polygon'])) self.assertEqual(states.default_style.name, "population") def testLayerGroups(self): expected = set(["tasmania", "tiger-ny", "spearfish"]) actual = set(l.name for l in self.cat.get_layergroups()) missing = expected - actual extras = actual - expected message = "Actual layergroup list did not match expected! (Extras: %s) (Missing: %s)" % ( extras, missing) self.assert_(len(expected ^ actual) == 0, message) tas = self.cat.get_layergroup("tasmania") self.assert_("tasmania", tas.name) self.assert_(isinstance(tas, LayerGroup)) self.assertEqual(tas.layers, [ 'tasmania_state_boundaries', 'tasmania_water_bodies', 'tasmania_roads', 'tasmania_cities' ], tas.layers) self.assertEqual(tas.styles, [None, None, None, None], tas.styles) def testStyles(self): self.assertEqual(20, len(self.cat.get_styles())) self.assertEqual("population", self.cat.get_style("population").name) self.assertEqual("popshade.sld", self.cat.get_style("population").filename) self.assertEqual("population", self.cat.get_style("population").sld_name) self.assert_(self.cat.get_style('non-existing-style') is None) def testEscaping(self): # GSConfig is inconsistent about using exceptions vs. returning None # when a resource isn't found. # But the basic idea is that none of them should throw HTTP errors from # misconstructed URLS self.cat.get_style("best style ever") self.cat.get_workspace("best workspace ever") try: self.cat.get_store(workspace="best workspace ever", name="best store ever") self.fail('expected exception') except FailedRequestError, fre: self.assertEqual('No store found named: best store ever', fre.message) try: self.cat.get_resource(workspace="best workspace ever", store="best store ever", name="best resource ever") except FailedRequestError, fre: self.assertEqual('No store found named: best store ever', fre.message)
class ModifyingTests(unittest.TestCase): def setUp(self): self.cat = Catalog(GSPARAMS['GSURL'], username=GSPARAMS['GSUSER'], password=GSPARAMS['GSPASSWORD']) self.gs_version = self.cat.get_short_version() def testFeatureTypeSave(self): # test saving round trip rs = self.cat.get_resources("bugsites")[0] old_abstract = rs.abstract new_abstract = "Not the original abstract" enabled = rs.enabled # Change abstract on server rs.abstract = new_abstract self.cat.save(rs) rs = self.cat.get_resources("bugsites")[0] self.assertEqual(new_abstract, rs.abstract) self.assertEqual(enabled, rs.enabled) # Change keywords on server rs.keywords = ["bugsites", "gsconfig"] enabled = rs.enabled self.cat.save(rs) rs = self.cat.get_resources("bugsites")[0] self.assertEqual(["bugsites", "gsconfig"], rs.keywords) self.assertEqual(enabled, rs.enabled) # Change metadata links on server rs.metadata_links = [("text/xml", "TC211", "http://example.com/gsconfig.test.metadata")] enabled = rs.enabled self.cat.save(rs) rs = self.cat.get_resources("bugsites")[0] self.assertEqual( [("text/xml", "TC211", "http://example.com/gsconfig.test.metadata")], rs.metadata_links) self.assertEqual(enabled, rs.enabled) # Restore abstract rs.abstract = old_abstract self.cat.save(rs) rs = self.cat.get_resources("bugsites")[0] self.assertEqual(old_abstract, rs.abstract) def testDataStoreCreate(self): ds = self.cat.create_datastore("vector_gsconfig") ds.connection_parameters.update(**DBPARAMS) self.cat.save(ds) def testPublishFeatureType(self): # Use the other test and store creation to load vector data into a database # @todo maybe load directly to database? try: self.testDataStoreCreateAndThenAlsoImportData() except FailedRequestError: pass try: lyr = self.cat.get_layer('import') data_source_name = lyr.resource.native_name # Delete the existing layer and resource to allow republishing. self.cat.delete(lyr) self.cat.delete(lyr.resource) ds = self.cat.get_stores("gsconfig_import_test")[0] # make sure it's gone self.assert_(self.cat.get_layer('import') is None) self.cat.publish_featuretype("import", ds, native_crs="EPSG:4326", native_name=data_source_name) # and now it's not self.assert_(self.cat.get_layer('import') is not None) finally: # tear stuff down to allow the other test to pass if we run first ds = self.cat.get_stores("gsconfig_import_test")[0] lyr = self.cat.get_layer('import') # Delete the existing layer and resource to allow republishing. try: if lyr: self.cat.delete(lyr) self.cat.delete(lyr.resource) if ds: self.cat.delete(ds) except: pass def testDataStoreModify(self): ds = self.cat.get_stores("sf")[0] self.assertFalse("foo" in ds.connection_parameters) ds.connection_parameters = ds.connection_parameters ds.connection_parameters["foo"] = "bar" orig_ws = ds.workspace.name self.cat.save(ds) ds = self.cat.get_stores("sf")[0] self.assertTrue("foo" in ds.connection_parameters) self.assertEqual("bar", ds.connection_parameters["foo"]) self.assertEqual(orig_ws, ds.workspace.name) @drop_table('import') def testDataStoreCreateAndThenAlsoImportData(self): ds = self.cat.create_datastore("gsconfig_import_test") ds.connection_parameters.update(**DBPARAMS) self.cat.save(ds) ds = self.cat.get_stores("gsconfig_import_test")[0] self.cat.add_data_to_store(ds, "import", { 'shp': 'test/data/states.shp', 'shx': 'test/data/states.shx', 'dbf': 'test/data/states.dbf', 'prj': 'test/data/states.prj' }) @drop_table('import2') def testVirtualTables(self): ds = self.cat.create_datastore("gsconfig_import_test2") ds.connection_parameters.update(**DBPARAMS) self.cat.save(ds) ds = self.cat.get_stores("gsconfig_import_test2")[0] self.cat.add_data_to_store(ds, "import2", { 'shp': 'test/data/states.shp', 'shx': 'test/data/states.shx', 'dbf': 'test/data/states.dbf', 'prj': 'test/data/states.prj' }) geom = JDBCVirtualTableGeometry('the_geom', 'MultiPolygon', '4326') ft_name = 'my_jdbc_vt_test' epsg_code = 'EPSG:4326' sql = "select * from import2 where 'STATE_NAME' = 'Illinois'" keyColumn = None parameters = None jdbc_vt = JDBCVirtualTable(ft_name, sql, 'false', geom, keyColumn, parameters) ft = self.cat.publish_featuretype(ft_name, ds, epsg_code, jdbc_virtual_table=jdbc_vt) # DISABLED; this test works only in the very particular case # "mytiff.tiff" is already present into the GEOSERVER_DATA_DIR # def testCoverageStoreCreate(self): # ds = self.cat.create_coveragestore2("coverage_gsconfig") # ds.data_url = "file:test/data/mytiff.tiff" # self.cat.save(ds) def testCoverageStoreModify(self): cs = self.cat.get_stores("sfdem")[0] self.assertEqual("GeoTIFF", cs.type) cs.type = "WorldImage" self.cat.save(cs) cs = self.cat.get_stores("sfdem")[0] self.assertEqual("WorldImage", cs.type) # not sure about order of test runs here, but it might cause problems # for other tests if this layer is misconfigured cs.type = "GeoTIFF" self.cat.save(cs) def testCoverageSave(self): # test saving round trip rs = self.cat.get_resources("Arc_Sample")[0] old_abstract = rs.abstract new_abstract = "Not the original abstract" # # Change abstract on server rs.abstract = new_abstract self.cat.save(rs) rs = self.cat.get_resources("Arc_Sample")[0] self.assertEqual(new_abstract, rs.abstract) # Restore abstract rs.abstract = old_abstract self.cat.save(rs) rs = self.cat.get_resources("Arc_Sample")[0] self.assertEqual(old_abstract, rs.abstract) # Change metadata links on server rs.metadata_links = [("text/xml", "TC211", "http://example.com/gsconfig.test.metadata")] enabled = rs.enabled self.cat.save(rs) rs = self.cat.get_resources("Arc_Sample")[0] self.assertEqual( [("text/xml", "TC211", "http://example.com/gsconfig.test.metadata")], rs.metadata_links) self.assertEqual(enabled, rs.enabled) srs_before = set(['EPSG:4326']) srs_after = set(['EPSG:4326', 'EPSG:3785']) formats = set(['ARCGRID', 'ARCGRID-GZIP', 'GEOTIFF', 'PNG', 'GIF', 'TIFF']) formats_after = set(["PNG", "GIF", "TIFF"]) # set and save request_srs_list self.assertEquals(set(rs.request_srs_list), srs_before, str(rs.request_srs_list)) rs.request_srs_list = rs.request_srs_list + ['EPSG:3785'] self.cat.save(rs) rs = self.cat.get_resources("Arc_Sample")[0] self.assertEquals(set(rs.request_srs_list), srs_after, str(rs.request_srs_list)) # set and save response_srs_list self.assertEquals(set(rs.response_srs_list), srs_before, str(rs.response_srs_list)) rs.response_srs_list = rs.response_srs_list + ['EPSG:3785'] self.cat.save(rs) rs = self.cat.get_resources("Arc_Sample")[0] self.assertEquals(set(rs.response_srs_list), srs_after, str(rs.response_srs_list)) # set and save supported_formats self.assertEquals(set(rs.supported_formats), formats, str(rs.supported_formats)) rs.supported_formats = ["PNG", "GIF", "TIFF"] self.cat.save(rs) rs = self.cat.get_resources("Arc_Sample")[0] self.assertEquals(set(rs.supported_formats), formats_after, str(rs.supported_formats)) def testWmsStoreCreate(self): ws = self.cat.create_wmsstore("wmsstore_gsconfig") ws.capabilitiesURL = "http://mesonet.agron.iastate.edu/cgi-bin/wms/iowa/rainfall.cgi?VERSION=1.1.1&REQUEST=GetCapabilities&SERVICE=WMS&" ws.type = "WMS" self.cat.save(ws) def testWmsLayer(self): self.cat.create_workspace("wmstest", "http://example.com/wmstest") wmstest = self.cat.get_workspaces("wmstest")[0] wmsstore = self.cat.create_wmsstore("wmsstore", wmstest) wmsstore.capabilitiesURL = "http://mesonet.agron.iastate.edu/cgi-bin/wms/iowa/rainfall.cgi?VERSION=1.1.1&REQUEST=GetCapabilities&SERVICE=WMS&" wmsstore.type = "WMS" self.cat.save(wmsstore) wmsstore = self.cat.get_stores("wmsstore")[0] self.assertEqual(1, len(self.cat.get_stores(workspaces=wmstest.name))) available_layers = wmsstore.get_resources(available=True) for layer in available_layers: # sanitize the layer name - validation will fail on newer geoservers name = layer.replace(':', '_') new_layer = self.cat.create_wmslayer(wmstest, wmsstore, name, nativeName=layer) added_layers = wmsstore.get_resources() self.assertEqual(len(available_layers), len(added_layers)) changed_layer = added_layers[0] self.assertEqual(True, changed_layer.advertised) self.assertEqual(True, changed_layer.enabled) changed_layer.advertised = False changed_layer.enabled = False self.cat.save(changed_layer) self.cat._cache.clear() changed_layer = wmsstore.get_resources()[0] changed_layer.fetch() self.assertEqual(False, changed_layer.advertised) self.assertEqual(False, changed_layer.enabled) # Testing projection and projection policy changes changed_layer.projection = "EPSG:900913" changed_layer.projection_policy = "REPROJECT_TO_DECLARED" self.cat.save(changed_layer) self.cat._cache.clear() layer = self.cat.get_layer(changed_layer.name) self.assertEqual(layer.resource.projection_policy, changed_layer.projection_policy) self.assertEqual(layer.resource.projection, changed_layer.projection) def testFeatureTypeCreate(self): shapefile_plus_sidecars = shapefile_and_friends("test/data/states") expected = { 'shp': 'test/data/states.shp', 'shx': 'test/data/states.shx', 'dbf': 'test/data/states.dbf', 'prj': 'test/data/states.prj' } self.assertEqual(len(expected), len(shapefile_plus_sidecars)) for k, v in expected.items(): self.assertEqual(v, shapefile_plus_sidecars[k]) sf = self.cat.get_workspaces("sf")[0] self.cat.create_featurestore("states_test", shapefile_plus_sidecars, sf.name) self.assert_(len(self.cat.get_resources("states_test", workspaces=sf.name)) > 0) self.assertRaises( ConflictingDataError, lambda: self.cat.create_featurestore("states_test", shapefile_plus_sidecars, sf) ) lyr = self.cat.get_layer("states_test") self.cat.delete(lyr) self.assert_(self.cat.get_layer("states_test") is None) def testLayerSave(self): # test saving round trip lyr = self.cat.get_layer("states") old_attribution = lyr.attribution new_attribution = { 'title': 'Not the original attribution', 'width': '123', 'height': '321', 'href': 'http://www.georchestra.org', 'url': 'https://www.cigalsace.org/portail/cigal/documents/page/mentions-legales/Logo_geOrchestra.jpg', 'type': 'image/jpeg' } # change attribution on server lyr.attribution = new_attribution self.cat.save(lyr) lyr = self.cat.get_layer("states") self.assertEqual(new_attribution, lyr.attribution) # Restore attribution lyr.attribution = old_attribution self.cat.save(lyr) lyr = self.cat.get_layer("states") self.assertEqual(old_attribution, lyr.attribution) self.assertEqual(lyr.default_style.name, "population") old_default_style = lyr.default_style lyr.default_style = 'pophatch' lyr.styles = [old_default_style] self.cat.save(lyr) lyr = self.cat.get_layer("states") self.assertEqual(lyr.default_style.name, "pophatch") self.assertEqual([s.name for s in lyr.styles], ["population"]) def testStyles(self): # check count before tests (upload) count = len(self.cat.get_styles()) # upload new style, verify existence self.cat.create_style("fred", open("test/fred.sld").read()) self.cat._cache.clear() fred = self.cat.get_styles(names="fred")[0] self.assert_(fred is not None) self.assertEqual("Fred", fred.sld_title) # replace style, verify changes self.cat.create_style("fred", open("test/ted.sld").read(), overwrite=True) self.cat._cache.clear() fred = self.cat.get_styles("fred")[0] self.assert_(fred is not None) self.assertEqual("Ted", fred.sld_title) # delete style, verify non-existence self.cat.delete(fred, purge=True) self.cat._cache.clear() self.assert_(len(self.cat.get_styles("fred")) == 0) # attempt creating new style self.cat.create_style("fred", open("test/fred.sld").read()) self.cat._cache.clear() fred = self.cat.get_styles("fred")[0] self.assertEqual("Fred", fred.sld_title) # compare count after upload self.assertEqual(count + 1, len(self.cat.get_styles())) # attempt creating a new style without "title" self.cat.create_style("notitle", open("test/notitle.sld").read()) self.cat._cache.clear() notitle = self.cat.get_styles("notitle")[0] self.assertEqual(None, notitle.sld_title) def testWorkspaceStyles(self): # upload new style, verify existence self.cat.create_style("jed", open("test/fred.sld").read(), workspace="topp") self.cat._cache.clear() jed = self.cat.get_styles(names="jed", workspaces="blarny") self.assert_(len(jed) == 0) jed = self.cat.get_styles(names="jed", workspaces="topp") self.assert_(len(jed) == 1) self.assertEqual("Fred", jed[0].sld_title) # replace style, verify changes self.cat.create_style("jed", open("test/ted.sld").read(), overwrite=True, workspace="topp") self.cat._cache.clear() jed = self.cat.get_styles(names="jed", workspaces="topp") self.assert_(len(jed) == 1) self.assertEqual("Ted", jed[0].sld_title) # delete style, verify non-existence self.cat.delete(jed[0], purge=True) self.assertEqual(0, len(self.cat.get_styles(names="jed", workspaces="topp"))) # attempt creating new style self.cat.create_style("jed", open("test/fred.sld").read(), workspace="topp") self.cat._cache.clear() jed = self.cat.get_styles(names="jed", workspaces="topp") self.assertEqual("Fred", jed[0].sld_title) def testLayerWorkspaceStyles(self): # upload new style, verify existence self.cat.create_style("ned", open("test/fred.sld").read(), overwrite=True, workspace="topp") self.cat.create_style("zed", open("test/ted.sld").read(), overwrite=True, workspace="topp") self.cat._cache.clear() styles = self.cat.get_styles(names="ned, zed", workspaces="topp") self.assertEqual(2, len(styles)) ned, zed = styles lyr = self.cat.get_layer("states") lyr.default_style = ned lyr.styles = [zed] self.cat.save(lyr) self.assertEqual("topp:ned", lyr.default_style) self.assertEqual([zed], lyr.styles) lyr.refresh() self.assertEqual("topp:ned", lyr.default_style.fqn) self.assertEqual([zed.fqn], [s.fqn for s in lyr.styles]) def testWorkspaceCreate(self): ws = self.cat.get_workspaces("acme") self.assertEqual(0, len(ws)) self.cat.create_workspace("acme", "http://example.com/acme") ws = self.cat.get_workspaces("acme")[0] self.assertEqual("acme", ws.name) def testWorkspaceDelete(self): self.cat.create_workspace("foo", "http://example.com/foo") ws = self.cat.get_workspaces("foo")[0] self.cat.delete(ws) ws = self.cat.get_workspaces("foo") self.assertEqual(0, len(ws)) def testWorkspaceDefault(self): # save orig orig = self.cat.get_default_workspace() neu = self.cat.create_workspace("neu", "http://example.com/neu") try: # make sure setting it works self.cat.set_default_workspace("neu") ws = self.cat.get_default_workspace() self.assertEqual('neu', ws.name) finally: # cleanup and reset to the way things were self.cat.delete(neu) self.cat.set_default_workspace(orig.name) ws = self.cat.get_default_workspace() self.assertEqual(orig.name, ws.name) def testFeatureTypeDelete(self): pass def testCoverageDelete(self): pass def testDataStoreDelete(self): states = self.cat.get_stores('states_shapefile')[0] self.assert_(states.enabled == True) states.enabled = False self.assert_(states.enabled == False) self.cat.save(states) states = self.cat.get_stores('states_shapefile')[0] self.assert_(states.enabled == False) states.enabled = True self.cat.save(states) states = self.cat.get_stores('states_shapefile')[0] self.assert_(states.enabled == True) def testLayerGroupSave(self): tas = self.cat.get_layergroups("tasmania")[0] if self.gs_version >= "2.13": self.assertEqual(tas.layers, [ 'topp:tasmania_state_boundaries', 'topp:tasmania_water_bodies', 'topp:tasmania_roads', 'topp:tasmania_cities' ], tas.layers) else: self.assertEqual(tas.layers, [ 'tasmania_state_boundaries', 'tasmania_water_bodies', 'tasmania_roads', 'tasmania_cities' ], tas.layers) self.assertEqual(tas.styles, [None, None, None, None], tas.styles) tas.layers = tas.layers[:-1] tas.styles = tas.styles[:-1] self.cat.save(tas) # this verifies the local state if self.gs_version >= "2.13": self.assertEqual(tas.layers, [ 'topp:tasmania_state_boundaries', 'topp:tasmania_water_bodies', 'topp:tasmania_roads' ], tas.layers) else: self.assertEqual(tas.layers, [ 'tasmania_state_boundaries', 'tasmania_water_bodies', 'tasmania_roads' ], tas.layers) self.assertEqual(tas.styles, [None, None, None], tas.styles) # force a refresh to check the remote state tas.refresh() if self.gs_version >= "2.13": self.assertEqual(tas.layers, [ 'topp:tasmania_state_boundaries', 'topp:tasmania_water_bodies', 'topp:tasmania_roads' ], tas.layers) else: self.assertEqual(tas.layers, [ 'tasmania_state_boundaries', 'tasmania_water_bodies', 'tasmania_roads' ], tas.layers) self.assertEqual(tas.styles, [None, None, None], tas.styles) def testImageMosaic(self): """ Test case for Issue #110 """ # testing the mosaic creation name = 'cea_mosaic' data = open('test/data/mosaic/cea.zip', 'rb') self.cat.create_imagemosaic(name, data) # get the layer resource back self.cat._cache.clear() resource = self.cat.get_layer(name).resource self.assert_(resource is not None) # delete granule from mosaic coverage = name store = self.cat.get_stores(name)[0] granules = self.cat.list_granules(coverage, store) self.assertEqual(1, len(granules['features'])) granule_id = name + '.1' self.cat.delete_granule(coverage, store, granule_id) granules = self.cat.list_granules(coverage, store) self.assertEqual(0, len(granules['features'])) ''' testing external Image mosaic creation ''' name = 'cea_mosaic_external' path = os.path.join(os.getcwd(), 'test/data/mosaic/external') self.cat.create_imagemosaic(name, path, workspace = 'topp') self.cat._cache.clear() resource = self.cat.get_layer("external").resource self.assert_(resource is not None) # add granule to mosaic granule_path = os.path.join(os.getcwd(), 'test/data/mosaic/granules/cea_20150102.tif') self.cat.add_granule(granule_path, name, workspace='topp') granules = self.cat.list_granules("external", name, 'topp') self.assertEqual(2, len(granules['features'])) # add external granule to mosaic granule_path = os.path.join(os.getcwd(), 'test/data/mosaic/granules/cea_20150103.zip') self.cat.add_granule(granule_path, name, workspace='topp') granules = self.cat.list_granules("external", name, 'topp') self.assertEqual(3, len(granules['features'])) # Delete store store = self.cat.get_stores(name)[0] self.cat.delete(store, purge=True, recurse=True) self.cat._cache.clear() def testTimeDimension(self): sf = self.cat.get_workspaces("sf")[0] files = shapefile_and_friends(os.path.join(gisdata.GOOD_DATA, "time", "boxes_with_end_date")) self.cat.create_featurestore("boxes_with_end_date", files, sf) get_resource = lambda: self.cat._cache.clear() or self.cat.get_layer('boxes_with_end_date').resource # configure time as LIST resource = get_resource() timeInfo = DimensionInfo("time", "true", "LIST", None, "ISO8601", None, attribute="date") resource.metadata = {'time': timeInfo} self.cat.save(resource) # and verify resource = get_resource() timeInfo = resource.metadata['time'] self.assertEqual("LIST", timeInfo.presentation) self.assertEqual(True, timeInfo.enabled) self.assertEqual("date", timeInfo.attribute) self.assertEqual("ISO8601", timeInfo.units) # disable time dimension timeInfo = resource.metadata['time'] timeInfo.enabled = False # since this is an xml property, it won't get written unless we modify it resource.metadata = {'time': timeInfo} self.cat.save(resource) # and verify resource = get_resource() timeInfo = resource.metadata['time'] self.assertEqual(False, timeInfo.enabled) # configure with interval, end_attribute and enable again timeInfo.enabled = True timeInfo.presentation = 'DISCRETE_INTERVAL' timeInfo.resolution = '3 days' timeInfo.end_attribute = 'enddate' resource.metadata = {'time': timeInfo} self.cat.save(resource) # and verify resource = get_resource() timeInfo = resource.metadata['time'] self.assertEqual(True, timeInfo.enabled) self.assertEqual('DISCRETE_INTERVAL', timeInfo.presentation) self.assertEqual('3 days', timeInfo.resolution_str()) self.assertEqual('enddate', timeInfo.end_attribute)