changeset 878:495fc3264265 geo-style

Connect uploaded styles with layers during GeoServer boot configuration.
author Sascha L. Teichmann <teichmann@intevation.de>
date Mon, 01 Oct 2018 09:20:26 +0200
parents 254cd247826d
children afd83fb3399d
files pkg/geoserver/boot.go
diffstat 1 files changed, 83 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/pkg/geoserver/boot.go	Sun Sep 30 20:09:02 2018 +0200
+++ b/pkg/geoserver/boot.go	Mon Oct 01 09:20:26 2018 +0200
@@ -35,6 +35,16 @@
 	}
 }
 
+func toStream(x interface{}) io.Reader {
+	var buf bytes.Buffer
+
+	if err := json.NewEncoder(&buf).Encode(x); err != nil {
+		// Should not happen
+		log.Printf("bad JSON: %v\n", err)
+	}
+	return bytes.NewReader(buf.Bytes())
+}
+
 func asJSON(req *http.Request) {
 	req.Header.Set("Content-Type", "application/json")
 }
@@ -109,7 +119,8 @@
 	// Probe datastore.
 	req, err := http.NewRequest(
 		http.MethodGet,
-		geoURL+"/rest/workspaces/"+workspaceName+"/datastores/"+datastoreName+".json",
+		geoURL+"/rest/workspaces/"+workspaceName+
+			"/datastores/"+datastoreName+".json",
 		nil)
 	if err != nil {
 		return err
@@ -152,16 +163,11 @@
 			},
 		},
 	}
-	var out bytes.Buffer
-	enc := json.NewEncoder(&out)
-	if err := enc.Encode(&ds); err != nil {
-		return err
-	}
 
 	req, err = http.NewRequest(
 		http.MethodPost,
 		geoURL+"/rest/workspaces/"+workspaceName+"/datastores",
-		bytes.NewReader(out.Bytes()))
+		toStream(ds))
 	if err != nil {
 		return err
 	}
@@ -261,18 +267,12 @@
 			},
 		}
 
-		var out bytes.Buffer
-		enc := json.NewEncoder(&out)
-		if err := enc.Encode(&ft); err != nil {
-			return err
-		}
-
 		req, err := http.NewRequest(
 			http.MethodPost,
 			geoURL+"/rest/workspaces/"+workspaceName+
 				"/datastores/"+datastoreName+
 				"/featuretypes",
-			bytes.NewReader(out.Bytes()))
+			toStream(ft))
 		if err != nil {
 			return err
 		}
@@ -379,10 +379,51 @@
 
 		log.Printf("creating style %s\n", entries[i].Name)
 
+		styleURL := geoURL + "/rest/workspaces/" + workspaceName +
+			"/styles"
+
+		// First create style
+
+		type Style struct {
+			Name     string `json:"name"`
+			Filename string `json:"filename"`
+		}
+
+		var layer = struct {
+			Style Style `json:"style"`
+		}{
+			Style: Style{
+				Name:     entries[i].Name,
+				Filename: entries[i].Name + ".sld",
+			},
+		}
+
 		req, err := http.NewRequest(
 			http.MethodPost,
-			geoURL+"/rest/workspaces/"+workspaceName+"/styles?name="+
-				url.QueryEscape(entries[i].Name),
+			styleURL,
+			toStream(&layer))
+
+		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("Unable to create style %s (%s)",
+				entries[i].Name,
+				http.StatusText(resp.StatusCode))
+		}
+
+		// Second upload data
+
+		req, err = http.NewRequest(
+			http.MethodPut,
+			styleURL+"/"+url.PathEscape(entries[i].Name),
 			strings.NewReader(entries[i].Style.String))
 		if err != nil {
 			return err
@@ -393,19 +434,39 @@
 		} else {
 			asContentType(req, "application/vnd.ogc.sld+xml")
 		}
-		resp, err := http.DefaultClient.Do(req)
+		resp, err = http.DefaultClient.Do(req)
+		if err != nil {
+			return err
+		}
+
+		if resp.StatusCode != http.StatusOK {
+			return fmt.Errorf("cannot upload style %s (%s)",
+				entries[i].Name, http.StatusText(resp.StatusCode))
+		}
+
+		// Third associate with layer
+
+		req, err = http.NewRequest(
+			http.MethodPost,
+			geoURL+"/rest/layers/"+
+				url.PathEscape(workspaceName+":"+entries[i].Name)+
+				"/styles?default=true",
+			toStream(&layer))
+		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("cannot create style %s (%s)",
+			return fmt.Errorf("cannot connect style %s with layer (%s)",
 				entries[i].Name, http.StatusText(resp.StatusCode))
 		}
-
-		//log.Printf("%s\n", entries[i].Style.String)
-
-		// TODO: Connect with feature.
 	}
 
 	return nil