Skip to content

Commit

Permalink
Merge pull request #259 from terranodo/issue-252
Browse files Browse the repository at this point in the history
Issue 252
  • Loading branch information
ARolek authored Jan 16, 2018
2 parents 5feb399 + 5426190 commit a5c7f37
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 43 deletions.
2 changes: 1 addition & 1 deletion provider/postgis/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ password = "" # PostGIS database password (required)

### Connection Properties

- `name` (string): [Required] provider name is referenced from map layers (required)
- `name` (string): [Required] provider name is referenced from map layers
- `type` (string): [Required] the type of data provider. must be "postgis" to use this data provider
- `host` (string): [Required] PostGIS database host
- `port` (int): [Required] PostGIS database port (required)
Expand Down
17 changes: 15 additions & 2 deletions server/README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
# Sever

The server package is responsible for handling webserver requests for map tiles and various JSON endpoints describing the configured server. Example config:

## Local development of the embeded inspector
```toml
[webserver]
port = ":9090" # set something different than default ":8080"
```

### Config properties

- `port` (string): [Optional] Port and bind string. For example ":9090" or "127.0.0.1:9090". Defaults to ":8080"
- `hostname` (string): [Optional] The hostname to use in the various JSON endpoints. This is useful if tegola is behind a proxy and can't read the API consumer's request host directly.
- `cors_allowed_origin` (string): [Optional] The value to include with the Cross Origin Resource Sharing (CORS) `Access-Control-Allow-Origin` header. Defaults to `*`.


## Local development of the embedded inspector

tegola's built in viewer code is stored in the static/ directory. To generate a bindata file so the static assets can be compiled into the binary, [bindata-assetfs](https://github.com/elazarl/go-bindata-assetfs) is used. Once bindata-assetfs is installed the following command can be used to generate the file for inclusion:

```
go-bindata-assetfs -pkg=server -ignore=.DS_Store static/...
```

bindata-assetfs also supports a debug mode which is descriped as "Do not embed the assets, but provide the embedding API. Contents will still be loaded from disk." This mode is ideal for development and can be configured using the following command:
bindata-assetfs also supports a debug mode which is descried as "Do not embed the assets, but provide the embedding API. Contents will still be loaded from disk." This mode is ideal for development and can be configured using the following command:

```
go-bindata-assetfs -debug -pkg=server -ignore=.DS_Store static/...
Expand Down
9 changes: 5 additions & 4 deletions server/handle_map_layer_zxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"strings"

"github.com/dimfeld/httptreemux"

"github.com/terranodo/tegola"
"github.com/terranodo/tegola/atlas"
"github.com/terranodo/tegola/mvt"
Expand Down Expand Up @@ -110,11 +111,11 @@ func (req HandleMapLayerZXY) ServeHTTP(w http.ResponseWriter, r *http.Request) {
tile.Buffer = TileBuffer

// filter down the layers we need for this zoom
m = m.DisableAllLayers().EnableLayersByZoom(tile.Z)
m = m.DisableAllLayers().DisableDebugLayers().EnableLayersByZoom(tile.Z)

// check for the debug query string
if req.debug {
m = m.EnableDebugLayers()
if !req.debug {
m = m.DisableDebugLayers()
}

pbyte, err := m.Encode(r.Context(), tile)
Expand All @@ -127,7 +128,7 @@ func (req HandleMapLayerZXY) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// TODO: add debug logs
return
default:
errMsg := fmt.Sprintf("Error marshalling tile: %v", err)
errMsg := fmt.Sprintf("error marshalling tile: %v", err)
log.Printf(errMsg)
http.Error(w, errMsg, http.StatusInternalServerError)
return
Expand Down
80 changes: 61 additions & 19 deletions server/handle_map_layer_zxy_test.go
Original file line number Diff line number Diff line change
@@ -1,50 +1,59 @@
package server_test

import (
"io/ioutil"
"net/http"
"net/http/httptest"
"reflect"
"strings"
"testing"

"github.com/dimfeld/httptreemux"
"github.com/golang/protobuf/proto"

"github.com/terranodo/tegola/mvt/vector_tile"
"github.com/terranodo/tegola/server"
)

func TestHandleMapLayerZXY(t *testing.T) {
// setup a new provider
testcases := []struct {
handler http.Handler
uri string
uriPattern string
reqMethod string
expectedCode int
expected []byte
uri string
uriPattern string
reqMethod string
expectedCode int
expected []byte
expectedLayers []string
}{
{
handler: server.HandleMapLayerZXY{},
uri: "/maps/test-map/test-layer/1/2/3.pbf",
uriPattern: "/maps/:map_name/:layer_name/:z/:x/:y",
reqMethod: "GET",
expectedCode: http.StatusOK,
uri: "/maps/test-map/test-layer/4/2/3.pbf",
uriPattern: "/maps/:map_name/:layer_name/:z/:x/:y",
reqMethod: "GET",
expectedCode: http.StatusOK,
expectedLayers: []string{"test-layer"},
},
{
uri: "/maps/test-map/test-layer/4/2/3.pbf?debug=true",
uriPattern: "/maps/:map_name/:layer_name/:z/:x/:y",
reqMethod: "GET",
expectedCode: http.StatusOK,
expectedLayers: []string{"debug-tile-outline", "debug-tile-center", "test-layer"},
},
{ // Negative row (y) not allowed (issue-229)
handler: server.HandleMapLayerZXY{},
uri: "/maps/test-map/test-layer/1/2/-1.pbf",
uriPattern: "/maps/:map_name/:layer_name/:z/:x/:y",
reqMethod: "GET",
expectedCode: http.StatusBadRequest,
expected: []byte("invalid Y value (-1.pbf)"),
},
{ // Negative column (x) not allowed
handler: server.HandleMapLayerZXY{},
uri: "/maps/test-map/test-layer/1/-1/3.pbf",
uriPattern: "/maps/:map_name/:layer_name/:z/:x/:y",
reqMethod: "GET",
expectedCode: http.StatusBadRequest,
expected: []byte("invalid X value (-1)"),
},
{ // issue-163
handler: server.HandleMapZXY{},
uri: "/maps/test-map/test-layer/-1/0/0.pbf",
uriPattern: "/maps/:map_name/:layer_name/:z/:x/:y",
reqMethod: "GET",
Expand All @@ -60,25 +69,58 @@ func TestHandleMapLayerZXY(t *testing.T) {
router := httptreemux.New()
// setup a new router group
group := router.NewGroup("/")
group.UsingContext().Handler(test.reqMethod, test.uriPattern, server.HandleMapZXY{})
group.UsingContext().Handler(test.reqMethod, test.uriPattern, server.HandleMapLayerZXY{})

r, err := http.NewRequest(test.reqMethod, test.uri, nil)
if err != nil {
t.Fatal(err)
t.Errorf("[%v] error making request", i, err)
continue
}

w := httptest.NewRecorder()
router.ServeHTTP(w, r)

if w.Code != test.expectedCode {
t.Errorf("failed test %v. handler returned wrong status code: got (%v) expected (%v)", i, w.Code, test.expectedCode)
t.Errorf("[%v] handler returned wrong status code: got (%v) expected (%v)", i, w.Code, test.expectedCode)
continue
}
// Only try to decode as string for errors.

// error checking
if len(test.expected) > 0 && test.expectedCode >= 400 {
wbody := strings.TrimSpace(w.Body.String())

if string(test.expected) != wbody {
t.Errorf("failed test %v. handler returned wrong body: got (%v) expected (%v)", i, wbody, string(test.expected))
t.Errorf("[%v] handler returned wrong body: got (%v) expected (%v)", i, wbody, string(test.expected))
continue
}
continue
}

// success check
if len(test.expectedLayers) > 0 {
var tile vectorTile.Tile
var responseBodyBytes []byte

responseBodyBytes, err = ioutil.ReadAll(w.Body)
if err != nil {
t.Errorf("[%v] error reading response body", i, err)
continue
}

if err = proto.Unmarshal(responseBodyBytes, &tile); err != nil {
t.Errorf("[%v] error unmarshalling response body", i, err)
continue
}

var tileLayers []string
// extract all the layers names in the response
for i := range tile.Layers {
tileLayers = append(tileLayers, *tile.Layers[i].Name)
}

if !reflect.DeepEqual(test.expectedLayers, tileLayers) {
t.Errorf("[%v] expected layers (%v) got (%v)", i, test.expectedLayers, tileLayers)
continue
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions server/handle_map_zxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ func (req HandleMapZXY) ServeHTTP(w http.ResponseWriter, r *http.Request) {
m = m.DisableAllLayers().EnableLayersByZoom(tile.Z)

// check for the debug query string
if req.debug {
m = m.EnableDebugLayers()
if !req.debug {
m = m.DisableDebugLayers()
}

pbyte, err := m.Encode(r.Context(), tile)
Expand Down
67 changes: 52 additions & 15 deletions server/handle_map_zxy_test.go
Original file line number Diff line number Diff line change
@@ -1,56 +1,64 @@
package server_test

import (
"io/ioutil"
"net/http"
"net/http/httptest"
"reflect"
"strings"
"testing"

"github.com/dimfeld/httptreemux"
"github.com/golang/protobuf/proto"

"github.com/terranodo/tegola/mvt/vector_tile"
"github.com/terranodo/tegola/server"
)

func TestHandleMapZXY(t *testing.T) {
// setup a new provider
testcases := []struct {
handler http.Handler
uri string
uriPattern string
reqMethod string
expected []byte
expectedCode int
uri string
uriPattern string
reqMethod string
expected []byte
expectedCode int
expectedLayers []string
}{
{
handler: server.HandleMapZXY{},
uri: "/maps/test-map/1/2/3.pbf",
uriPattern: "/maps/:map_name/:z/:x/:y",
reqMethod: "GET",
expectedCode: http.StatusOK,
uri: "/maps/test-map/10/2/3.pbf",
uriPattern: "/maps/:map_name/:z/:x/:y",
reqMethod: "GET",
expectedCode: http.StatusOK,
expectedLayers: []string{"test-layer-2-name", "test-layer"},
},
{
uri: "/maps/test-map/10/2/3.pbf?debug=true",
uriPattern: "/maps/:map_name/:z/:x/:y",
reqMethod: "GET",
expectedCode: http.StatusOK,
expectedLayers: []string{"debug-tile-outline", "debug-tile-center", "test-layer-2-name", "test-layer"},
},
{ // issue-163
handler: server.HandleMapZXY{},
uri: "/maps/test-map/-1/0/0.pbf",
uriPattern: "/maps/:map_name/:z/:x/:y",
reqMethod: "GET",
expectedCode: http.StatusBadRequest,
expected: []byte("invalid Z value (-1)"),
},
{ // Check that values outside expected zoom result in 404.
handler: server.HandleMapZXY{},
uri: "/maps/test-map/-1/2/3.pbf",
uriPattern: "/maps/:map_name/:z/:x/:y",
reqMethod: "GET",
expectedCode: http.StatusBadRequest,
},
{ // Check that negative y value results in 404. (issue-229)
handler: server.HandleMapZXY{},
uri: "/maps/test-map/1/2/-1.pbf",
uriPattern: "/maps/:map_name/:z/:x/:y",
reqMethod: "GET",
expectedCode: http.StatusBadRequest,
},
{ // Check that nagative x value results in 404.
handler: server.HandleMapZXY{},
uri: "/maps/test-map/1/-1/3.pbf",
uriPattern: "/maps/:map_name/:z/:x/:y",
reqMethod: "GET",
Expand Down Expand Up @@ -79,6 +87,7 @@ func TestHandleMapZXY(t *testing.T) {
if w.Code != test.expectedCode {
t.Errorf("failed test %v. handler returned wrong status code: got (%v) expected (%v)", i, w.Code, test.expectedCode)
}

// Only try to decode as string for errors.
if len(test.expected) > 0 && test.expectedCode >= 400 {
wbody := strings.TrimSpace(w.Body.String())
Expand All @@ -87,5 +96,33 @@ func TestHandleMapZXY(t *testing.T) {
t.Errorf("failed test %v. handler returned wrong body: got (%v) expected (%v)", i, wbody, string(test.expected))
}
}

// success check
if len(test.expectedLayers) > 0 {
var tile vectorTile.Tile
var responseBodyBytes []byte

responseBodyBytes, err = ioutil.ReadAll(w.Body)
if err != nil {
t.Errorf("[%v] error reading response body", i, err)
continue
}

if err = proto.Unmarshal(responseBodyBytes, &tile); err != nil {
t.Errorf("[%v] error unmarshalling response body", i, err)
continue
}

var tileLayers []string
// extract all the layers names in the response
for i := range tile.Layers {
tileLayers = append(tileLayers, *tile.Layers[i].Name)
}

if !reflect.DeepEqual(test.expectedLayers, tileLayers) {
t.Errorf("[%v] expected layers (%v) got (%v)", i, test.expectedLayers, tileLayers)
continue
}
}
}
}

0 comments on commit a5c7f37

Please sign in to comment.