Mercurial > gemma
changeset 395:272ed64a5053
Create feature layers in GeoServer via REST API.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Mon, 13 Aug 2018 18:55:43 +0200 |
parents | f24ed1d570c7 |
children | c6290776c65c |
files | cmd/gemma/geoserver.go |
diffstat | 1 files changed, 95 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/cmd/gemma/geoserver.go Mon Aug 13 17:38:24 2018 +0200 +++ b/cmd/gemma/geoserver.go Mon Aug 13 18:55:43 2018 +0200 @@ -18,12 +18,15 @@ databaseType = "postgis" ) -const startupSQL = `SET SESSION AUTHORIZATION waterway_user;` +const ( + startupSQL = `` // `SET SESSION AUTHORIZATION waterway_user` + closeupSQL = `` // `RESET SESSION AUTHORIZATION` +) func basicAuth(user, password string) func(req *http.Request) { auth := "Basic " + misc.BasicAuth(user, password) return func(req *http.Request) { - req.Header.Add("Authorization", auth) + req.Header.Add("authorization", auth) } } @@ -59,6 +62,9 @@ } // Create workspace + + log.Println("info: creating workspace " + workspaceName) + const createJSON = `{"workspace":{"name":"` + workspaceName + `"}}` req, err = http.NewRequest( @@ -91,7 +97,7 @@ auth = basicAuth(user, password) ) - // Probe workspace. + // Probe datastore. req, err := http.NewRequest( http.MethodGet, url+"/rest/workspaces/"+workspaceName+"/datastores/"+datastoreName+".json", @@ -110,6 +116,9 @@ return nil } + // Create datastore. + log.Println("info: creating datastore " + datastoreName) + type entry struct { Key interface{} `json:"@key"` Value interface{} `json:"$"` @@ -123,11 +132,13 @@ "entry": []entry{ {"host", config.DBHost()}, {"port", config.DBPort()}, + {"database", config.DBName()}, {"schema", databaseScheme}, {"user", config.SysAdmin()}, {"passwd", config.SysAdminPassword()}, {"dbtype", databaseType}, {"Session startup SQL", startupSQL}, + {"Session close-up SQL", closeupSQL}, }, }, }, @@ -161,15 +172,87 @@ return err } +func ensureFeatures() error { + var ( + url = config.GeoServerURL() + user = config.GeoServerUser() + password = config.GeoServerPassword() + auth = basicAuth(user, password) + tables = config.GeoServerTables() + ) + + log.Printf("info: number of tables to publish %d\n", len(tables)) + + for _, table := range tables { + log.Printf("checking layer %s\n", table) + // Probe featuretype. + req, err := http.NewRequest( + http.MethodGet, + url+"/rest/workspaces/"+workspaceName+ + "/datastores/"+datastoreName+ + "/featuretypes/"+table+".json", + nil) + if err != nil { + return err + } + auth(req) + resp, err := http.DefaultClient.Do(req) + if err != nil { + return err + } + + if resp.StatusCode != http.StatusNotFound { + log.Println("info: featuretype " + table + " already exists.") + continue + } + + // Create featuretype. + log.Printf("info: creating featuretype %s\n", table) + + // Create featuretype + ft := map[string]interface{}{ + "featureType": map[string]interface{}{ + "name": table, + "nativeName": table, + "title": table, + }, + } + + var out bytes.Buffer + enc := json.NewEncoder(&out) + if err := enc.Encode(&ft); err != nil { + return err + } + + req, err = http.NewRequest( + http.MethodPost, + url+"/rest/workspaces/"+workspaceName+ + "/datastores/"+datastoreName+ + "/featuretypes", + bytes.NewReader(out.Bytes())) + if err != nil { + return err + } + auth(req) + asJSON(req) + resp, err = http.DefaultClient.Do(req) + if err != nil { + return err + } + + if resp.StatusCode != http.StatusCreated { + return fmt.Errorf("Status code '%s' (%d)", + http.StatusText(resp.StatusCode), + resp.StatusCode) + } + } + + return nil +} + func prepareGeoServer() error { - var ( - url = config.GeoServerURL() - //tables = config.GeoServerTables() - ) - - //if url == "" || len(tables) == 0 { - if url == "" { + if config.GeoServerURL() == "" { log.Println("info: No tables to publish on GeoServer") return nil } @@ -182,7 +265,7 @@ return err } - // TODO: Create layers. + // TODO: Styles - return nil + return ensureFeatures() }