Skip to content

Commit

Permalink
[FAB-4469] Add REST endpoint for sanity check
Browse files Browse the repository at this point in the history
The sanity checking code added in FAB-4468 currently has no external
interface.  In order to satisfy the requirements of FAB-3831, it is
necessary to expose an external interface to this sanity checking
ability.

This CR adds a REST endpoint at /configtxlator/sanitycheck/config which
the user may POST a marshaled common.Config to.  The REST target then
replies with a JSON document, indicating the error types and paths, as
reported by the sanity checking code.

Change-Id: I97616eec67aebd77ea8191b8ae39808716330aec
Signed-off-by: Jason Yellick <jyellick@us.ibm.com>
  • Loading branch information
Jason Yellick committed Jun 9, 2017
1 parent 9577fb7 commit 9bb26f3
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 1 deletion.
37 changes: 36 additions & 1 deletion common/tools/configtxlator/rest/configtxlator_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ limitations under the License.
package rest

import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"

"github.com/hyperledger/fabric/common/tools/configtxlator/sanitycheck"
"github.com/hyperledger/fabric/common/tools/configtxlator/update"

cb "github.com/hyperledger/fabric/protos/common"

"github.com/golang/protobuf/proto"
Expand Down Expand Up @@ -88,3 +89,37 @@ func ComputeUpdateFromConfigs(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/octet-stream")
w.Write(encoded)
}

func SanityCheckConfig(w http.ResponseWriter, r *http.Request) {
buf, err := ioutil.ReadAll(r.Body)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintln(w, err)
return
}

config := &cb.Config{}
err = proto.Unmarshal(buf, config)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(w, "Error unmarshaling data to common.Config': %s\n", err)
return
}

fmt.Printf("Sanity checking %+v\n", config)
sanityCheckMessages, err := sanitycheck.Check(config)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(w, "Error performing sanity check: %s\n", err)
return
}

resBytes, err := json.Marshal(sanityCheckMessages)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(w, "Error marshaling result to JSON: %s\n", err)
return
}
w.WriteHeader(http.StatusOK)
w.Write(resBytes)
}
25 changes: 25 additions & 0 deletions common/tools/configtxlator/rest/configtxlator_handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ package rest

import (
"bytes"
"encoding/json"
"mime/multipart"
"net/http"
"net/http/httptest"
"testing"

"github.com/hyperledger/fabric/common/tools/configtxlator/sanitycheck"
cb "github.com/hyperledger/fabric/protos/common"
"github.com/hyperledger/fabric/protos/utils"

Expand Down Expand Up @@ -157,3 +159,26 @@ func TestProtolatorCorruptProtos(t *testing.T) {

assert.Equal(t, http.StatusBadRequest, rec.Code)
}

func TestConfigtxlatorSanityCheckConfig(t *testing.T) {
req, _ := http.NewRequest("POST", "/configtxlator/config/verify", bytes.NewReader(utils.MarshalOrPanic(&cb.Config{})))
rec := httptest.NewRecorder()
r := NewRouter()
r.ServeHTTP(rec, req)

assert.Equal(t, http.StatusOK, rec.Code)

outputMsg := &sanitycheck.Messages{}

err := json.Unmarshal(rec.Body.Bytes(), outputMsg)
assert.NoError(t, err)
}

func TestConfigtxlatorSanityCheckMalformedConfig(t *testing.T) {
req, _ := http.NewRequest("POST", "/configtxlator/config/verify", bytes.NewReader([]byte("Garbage")))
rec := httptest.NewRecorder()
r := NewRouter()
r.ServeHTTP(rec, req)

assert.Equal(t, http.StatusBadRequest, rec.Code)
}
3 changes: 3 additions & 0 deletions common/tools/configtxlator/rest/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ func NewRouter() *mux.Router {
router.
HandleFunc("/configtxlator/compute/update-from-configs", ComputeUpdateFromConfigs).
Methods("POST")
router.
HandleFunc("/configtxlator/config/verify", SanityCheckConfig).
Methods("POST")

return router
}

0 comments on commit 9bb26f3

Please sign in to comment.