From f54fda1d3f4aa01f014460c67734459c7dfecaa8 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Tue, 14 Mar 2017 14:11:54 +0000 Subject: [PATCH] Query the roomserver for the current room state We need this to send messages. --- .../dendrite/clientapi/clientapi.go | 5 ++- .../dendrite/clientapi/config/config.go | 2 + .../dendrite/clientapi/routing/routing.go | 7 ++-- .../dendrite/clientapi/writers/sendmessage.go | 38 +++++++++++++++++-- 4 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/github.com/matrix-org/dendrite/clientapi/clientapi.go b/src/github.com/matrix-org/dendrite/clientapi/clientapi.go index 9f17edea1..51f67817c 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/clientapi.go +++ b/src/github.com/matrix-org/dendrite/clientapi/clientapi.go @@ -9,6 +9,7 @@ import ( "github.com/matrix-org/dendrite/clientapi/config" "github.com/matrix-org/dendrite/clientapi/routing" + "github.com/matrix-org/dendrite/roomserver/api" log "github.com/Sirupsen/logrus" "github.com/matrix-org/dugong" @@ -53,6 +54,7 @@ func main() { PrivateKey: privKey, KafkaProducerURIs: []string{"localhost:9092"}, ClientAPIOutputTopic: "clientapiOutput", + RoomserverURL: "http://localhost:7777", } log.Info("Starting clientapi") @@ -61,7 +63,8 @@ func main() { if err != nil { log.Panicf("Failed to setup kafka producers(%s): %s", cfg.KafkaProducerURIs, err) } + queryAPI := api.NewRoomserverQueryAPIHTTP(cfg.RoomserverURL, nil) - routing.Setup(http.DefaultServeMux, http.DefaultClient, cfg, producer) + routing.Setup(http.DefaultServeMux, http.DefaultClient, cfg, producer, queryAPI) log.Fatal(http.ListenAndServe(bindAddr, nil)) } diff --git a/src/github.com/matrix-org/dendrite/clientapi/config/config.go b/src/github.com/matrix-org/dendrite/clientapi/config/config.go index 001da837b..7f048fca9 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/config/config.go +++ b/src/github.com/matrix-org/dendrite/clientapi/config/config.go @@ -15,4 +15,6 @@ type ClientAPI struct { KafkaProducerURIs []string // The topic for events which are written to the logs. ClientAPIOutputTopic string + // The URL of the roomserver which can service Query API requests + RoomserverURL string } diff --git a/src/github.com/matrix-org/dendrite/clientapi/routing/routing.go b/src/github.com/matrix-org/dendrite/clientapi/routing/routing.go index a98c05b57..aacebebc9 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/routing/routing.go +++ b/src/github.com/matrix-org/dendrite/clientapi/routing/routing.go @@ -7,6 +7,7 @@ import ( "github.com/matrix-org/dendrite/clientapi/config" "github.com/matrix-org/dendrite/clientapi/readers" "github.com/matrix-org/dendrite/clientapi/writers" + "github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/util" "github.com/prometheus/client_golang/prometheus" sarama "gopkg.in/Shopify/sarama.v1" @@ -16,7 +17,7 @@ const pathPrefixR0 = "/_matrix/client/r0" // Setup registers HTTP handlers with the given ServeMux. It also supplies the given http.Client // to clients which need to make outbound HTTP requests. -func Setup(servMux *http.ServeMux, httpClient *http.Client, cfg config.ClientAPI, producer sarama.SyncProducer) { +func Setup(servMux *http.ServeMux, httpClient *http.Client, cfg config.ClientAPI, producer sarama.SyncProducer, queryAPI api.RoomserverQueryAPI) { apiMux := mux.NewRouter() r0mux := apiMux.PathPrefix(pathPrefixR0).Subrouter() r0mux.Handle("/createRoom", make("createRoom", util.NewJSONRequestHandler(func(req *http.Request) util.JSONResponse { @@ -25,10 +26,10 @@ func Setup(servMux *http.ServeMux, httpClient *http.Client, cfg config.ClientAPI r0mux.Handle("/sync", make("sync", util.NewJSONRequestHandler(func(req *http.Request) util.JSONResponse { return readers.Sync(req) }))) - r0mux.Handle("/rooms/{roomID}/send/{eventType}", + r0mux.Handle("/rooms/{roomID}/send/{eventType}/{txnID}", make("send_message", util.NewJSONRequestHandler(func(req *http.Request) util.JSONResponse { vars := mux.Vars(req) - return writers.SendMessage(req, vars["roomID"], vars["eventType"]) + return writers.SendMessage(req, vars["roomID"], vars["eventType"], vars["txnID"], cfg, queryAPI) })), ) diff --git a/src/github.com/matrix-org/dendrite/clientapi/writers/sendmessage.go b/src/github.com/matrix-org/dendrite/clientapi/writers/sendmessage.go index bbb432ec8..9d49b4230 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/writers/sendmessage.go +++ b/src/github.com/matrix-org/dendrite/clientapi/writers/sendmessage.go @@ -3,22 +3,54 @@ package writers import ( "net/http" + "fmt" log "github.com/Sirupsen/logrus" "github.com/matrix-org/dendrite/clientapi/auth" + "github.com/matrix-org/dendrite/clientapi/config" + "github.com/matrix-org/dendrite/clientapi/httputil" + "github.com/matrix-org/dendrite/common" + "github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/util" ) -// SendMessage implements /rooms/{roomID}/send/{eventType} -func SendMessage(req *http.Request, roomID, eventType string) util.JSONResponse { +// http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-send-eventtype-txnid +type sendMessageResponse struct { + EventID string `json:"event_id"` +} + +// SendMessage implements /rooms/{roomID}/send/{eventType}/{txnID} +func SendMessage(req *http.Request, roomID, eventType, txnID string, cfg config.ClientAPI, queryAPI api.RoomserverQueryAPI) util.JSONResponse { logger := util.GetLogger(req.Context()) userID, resErr := auth.VerifyAccessToken(req) if resErr != nil { return *resErr } + var r map[string]interface{} // must be a JSON object + resErr = httputil.UnmarshalJSONRequest(req, &r) + if resErr != nil { + return *resErr + } + eventID := fmt.Sprintf("$%s:%s", util.RandomString(16), cfg.ServerName) + + queryReq := api.QueryLatestEventsAndStateRequest{ + RoomID: roomID, + StateToFetch: []common.StateKeyTuple{ + {"m.room.member", userID}, + }, + } + var queryRes api.QueryLatestEventsAndStateResponse + if err := queryAPI.QueryLatestEventsAndState(&queryReq, &queryRes); err != nil { + return httputil.LogThenError(req, err) + } + logger.WithFields(log.Fields{ "roomID": roomID, "eventType": eventType, "userID": userID, + "res": queryRes, }).Info("Doing stuff...") - return util.MessageResponse(404, "Not implemented yet") + return util.JSONResponse{ + Code: 200, + JSON: sendMessageResponse{eventID}, + } }