diff pkg/geoserver/boot.go @ 4607:064b6c46ea6c geoserver_sql_views

Create SQL views in GeoServer from appropriate configuration
author Tom Gottfried <tom@intevation.de>
date Thu, 05 Sep 2019 16:55:40 +0200
parents dfe9cde6a20c
children 1bf26d18b4d7
line wrap: on
line diff
--- a/pkg/geoserver/boot.go	Thu Sep 05 12:23:31 2019 +0200
+++ b/pkg/geoserver/boot.go	Thu Sep 05 16:55:40 2019 +0200
@@ -59,6 +59,41 @@
 	return bytes.NewReader(buf.Bytes())
 }
 
+// XXX: Creating SQL views with JSON via GeoServer REST-API fails
+// Begin code for handling with XML instead
+func toXMLStream(x interface{}) io.Reader {
+	var buf bytes.Buffer
+	if err := xml.NewEncoder(&buf).Encode(x); err != nil {
+		// Should not happen
+		log.Printf("warn: bad XML: %v\n", err)
+	}
+	return bytes.NewReader(buf.Bytes())
+}
+
+type ftXML struct {
+	XMLName  xml.Name `xml:"featureType"`
+	Name     string   `xml:"name"`
+	Title    string   `xml:"title"`
+	Metadata ftMetadata
+}
+
+type ftMetadata struct {
+	XMLName xml.Name `xml:"metadata"`
+	Entry   ftMetadataEntry
+}
+
+type ftMetadataEntry struct {
+	XMLName   xml.Name `xml:"entry"`
+	Key       string   `xml:"key,attr"`
+	VirtTable ftVirtTable
+}
+
+type ftVirtTable struct {
+	XMLName xml.Name `xml:"virtualTable"`
+	Name    string   `xml:"name"`
+	SQL     string   `xml:"sql"`
+} // End code for handling with XML
+
 func asJSON(req *http.Request) {
 	req.Header.Set("Content-Type", "application/json")
 }
@@ -213,6 +248,9 @@
 		auth     = basicAuth(user, password)
 	)
 
+	datastoreURL := geoURL + "/rest/workspaces/" + workspaceName +
+		"/datastores/" + datastoreName
+
 	tables := models.InternalServices.Filter(models.IntWFS)
 	if len(tables) == 0 {
 		log.Println("info: no tables to publish")
@@ -241,9 +279,7 @@
 	// Fetch all featuretypes.
 	req, err := http.NewRequest(
 		http.MethodGet,
-		geoURL+"/rest/workspaces/"+workspaceName+
-			"/datastores/"+datastoreName+
-			"/featuretypes.json",
+		datastoreURL+"/featuretypes.json",
 		nil)
 	if err != nil {
 		return err
@@ -285,26 +321,49 @@
 		// 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 req *http.Request
+		if models.IntSQLView(tables[i]) {
+			// XXX: Creating SQL views with JSON via GeoServer REST-API fails
+			// Begin code for handling with XML instead
+			ft := ftXML{
+				Name:  table,
+				Title: table,
+				Metadata: ftMetadata{
+					Entry: ftMetadataEntry{
+						Key: "JDBC_VIRTUAL_TABLE",
+						VirtTable: ftVirtTable{
+							Name: table,
+							SQL:  *tables[i].SQL}}}}
 
-		req, err := http.NewRequest(
-			http.MethodPost,
-			geoURL+"/rest/workspaces/"+workspaceName+
-				"/datastores/"+datastoreName+
-				"/featuretypes",
-			toStream(ft))
-		if err != nil {
-			return err
+			req, err = http.NewRequest(
+				http.MethodPost,
+				datastoreURL+"/featuretypes",
+				toXMLStream(ft))
+			if err != nil {
+				return err
+			}
+			asContentType(req, "text/xml")
+			// End code for handling with XML instead
+		} else {
+			ft := map[string]interface{}{
+				"featureType": map[string]interface{}{
+					"name":       table,
+					"nativeName": table,
+					"title":      table,
+				},
+			}
+
+			req, err = http.NewRequest(
+				http.MethodPost,
+				datastoreURL+"/featuretypes",
+				toStream(ft))
+			if err != nil {
+				return err
+			}
+			asJSON(req)
 		}
 		auth(req)
-		asJSON(req)
+
 		resp, err := http.DefaultClient.Do(req)
 		if err != nil {
 			return err