Skip to content
Permalink
Browse files
Closes #57
Add flags for verbose output of HTTP request data

New global flags `--verbose` and `--vverbose` (very verbose) configure the network library to write data about API requests to stderr. (I would have used `-v` and `-vv` but the former is already taken as shorthand for `--version`.)

The intention is to make it easier to debug both the working of the CLI and unexpected responses from Brooklyn servers.

Example:
```
$ ./bin/br --verbose deploy ./bp.yaml
POST /v1/applications HTTP/1.1
Host: localhost:8081
User-Agent: Go-http-client/1.1
Content-Length: 0
Authorization: ******
Content-Type: application/json
Accept-Encoding: gzip

HTTP/1.1 201 Created
Transfer-Encoding: chunked
Cache-Control: no-cache, no-store
Content-Type: application/json
Date: Thu, 27 Jul 2017 14:12:56 GMT
Expires: 0
Location: http://localhost:8081/v1/applications/sr9uw9bdbu
Pragma: no-cache
Server: Jetty(9.2.13.v20150730)
Vary: Accept-Encoding

Id:       | sr9uw9bdbu
Name:     | Application (sr9uw9bdbu)
Status:   | In progress
```

```
$ ./bin/br --vverbose application vhkhp6nbbl entity
GET /v1/applications/vhkhp6nbbl/entities HTTP/1.1
Host: localhost:8081
User-Agent: Go-http-client/1.1
Accept: application/json, text/plain
Authorization: ******
Accept-Encoding: gzip

HTTP/1.1 200 OK
Transfer-Encoding: chunked
Cache-Control: no-cache, no-store
Content-Type: application/json
Date: Thu, 27 Jul 2017 14:16:43 GMT
Expires: 0
Pragma: no-cache
Server: Jetty(9.2.13.v20150730)
Vary: Accept-Encoding

503
[{"id":"tqj1a2g883","name":"Tomcat 7 Server","type":"org.apache.brooklyn.entity.webapp.tomcat.TomcatServer","catalogItemId":"org.apache.brooklyn.entity.webapp.tomcat.TomcatServer:0.12.0-SNAPSHOT","links":{"self":"/v1/applications/vhkhp6nbbl/entities/tqj1a2g883","parent":"/v1/applications/vhkhp6nbbl/entities/vhkhp6nbbl","application":"/v1/applications/vhkhp6nbbl","children":"/v1/applications/vhkhp6nbbl/entities/tqj1a2g883/children","config":"/v1/applications/vhkhp6nbbl/entities/tqj1a2g883/config","sensors":"/v1/applications/vhkhp6nbbl/entities/tqj1a2g883/sensors","effectors":"/v1/applications/vhkhp6nbbl/entities/tqj1a2g883/effectors","policies":"/v1/applications/vhkhp6nbbl/entities/tqj1a2g883/policies","activities":"/v1/applications/vhkhp6nbbl/entities/tqj1a2g883/activities","locations":"/v1/applications/vhkhp6nbbl/entities/tqj1a2g883/locations","tags":"/v1/applications/vhkhp6nbbl/entities/tqj1a2g883/tags","expunge":"/v1/applications/vhkhp6nbbl/entities/tqj1a2g883/expunge","rename":"/v1/applications/vhkhp6nbbl/entities/tqj1a2g883/name","spec":"/v1/applications/vhkhp6nbbl/entities/tqj1a2g883/spec","iconUrl":"/v1/applications/vhkhp6nbbl/entities/tqj1a2g883/icon","catalog":"/v1/catalog/entities/org.apache.brooklyn.entity.webapp.tomcat.TomcatServer/0.12.0-SNAPSHOT"}}]
0

Id           | Name              | Type
tqj1a2g883   | Tomcat 7 Server   | org.apache.brooklyn.entity.webapp.tomcat.TomcatServer
```

The Authorization header is redacted.
  • Loading branch information
geomacy committed Jul 28, 2017
2 parents 5dc3c6c + c88df99 commit 3dc6921fc90e3a33cd4fdea8397f17c5b6ec1723
Showing 3 changed files with 60 additions and 3 deletions.
@@ -60,6 +60,14 @@ func NewApp(baseName string, cmdRunner command_runner.Runner, metadatas ...comma
Name: "json, j",
Usage: "Render value as json with json path selector as described at https://github.com/NodePrime/jsonpath. (Experimental, not supported on all commands at present) ",
},
cli.BoolFlag {
Name: "verbose",
Usage: "Print HTTP requests and responses",
},
cli.BoolFlag {
Name: "vverbose",
Usage: "Print HTTP requests and responses and include body data",
},
}

app.Commands = []cli.Command{}
@@ -39,7 +39,7 @@ func main() {
}

//target, username, password := "http://192.168.50.101:8081", "brooklyn", "Sns4Hh9j7l"
network := net.NewNetwork(target, username, password, skipSslChecks)
network := net.NewNetwork(target, username, password, skipSslChecks, verbosity(os.Args))
cmdFactory := command_factory.NewFactory(network, config)

args, scope := scope.ScopeArguments(os.Args)
@@ -72,6 +72,16 @@ func requiresLogin(args []string) bool {
return true
}

func verbosity(args []string) string {
if contains(args, "--vverbose") {
return "vverbose"
} else if contains(args, "--verbose") {
return "verbose"
} else {
return "normal"
}
}

func contains(slice []string, val string) bool {
for _, a := range slice {
if a == val {
@@ -22,9 +22,12 @@ import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"net/http/httputil"
"net/url"
"os"
"path/filepath"
@@ -38,14 +41,16 @@ type Network struct {
BrooklynUser string
BrooklynPass string
SkipSslChecks bool
Verbosity string
}

func NewNetwork(brooklynUrl, brooklynUser, brooklynPass string, skipSslChecks bool) (net *Network) {
func NewNetwork(brooklynUrl, brooklynUser, brooklynPass string, skipSslChecks bool, verbose string) (net *Network) {
net = new(Network)
net.BrooklynUrl = brooklynUrl
net.BrooklynUser = brooklynUser
net.BrooklynPass = brooklynPass
net.SkipSslChecks = skipSslChecks
net.Verbosity = verbose
return
}

@@ -119,9 +124,43 @@ func (net *Network) makeClient() (*http.Client) {
return client
}

func debug(verbosity string, supp func(b bool) ([]byte, error)) {
writer := func(data []byte, err error) {
if err == nil {
fmt.Fprintf(os.Stderr, "%s", data)
// include newline if data doesn't have one
if data[len(data)-1] != '\n' {
fmt.Fprintln(os.Stderr, "")
}
} else {
log.Fatalf("%s\n", err)
}
}
switch verbosity {
case "verbose":
writer(supp(false))
case "vverbose":
writer(supp(true))
}
}

func (net *Network) SendRequestGetStatusCode(req *http.Request) ([]byte, int, error) {
client := net.makeClient()
client := net.makeClient()
debug(net.Verbosity, func (includeBody bool) ([]byte, error) {
var authHeader = req.Header.Get("Authorization")
if authHeader != "" {
req.Header.Set("Authorization", "******")
}
data, err := httputil.DumpRequestOut(req, includeBody)
if authHeader != "" {
req.Header.Set("Authorization", authHeader)
}
return data, err
})
resp, err := client.Do(req)
debug(net.Verbosity, func (includeBody bool) ([]byte, error) {
return httputil.DumpResponse(resp, includeBody)
})
if err != nil {
return nil, 0, err
}

0 comments on commit 3dc6921

Please sign in to comment.