1
0
Fork 0
mirror of https://github.com/matrix-org/dendrite.git synced 2025-03-28 04:24:28 -05:00

Add API for querying the state after a list of events

This commit is contained in:
Mark Haines 2017-05-25 19:38:39 +01:00
parent 84ad4ff9f6
commit 6ee0fe0f65
2 changed files with 86 additions and 1 deletions
src/github.com/matrix-org/dendrite/roomserver

View file

@ -24,7 +24,7 @@ import (
// QueryLatestEventsAndStateRequest is a request to QueryLatestEventsAndState
type QueryLatestEventsAndStateRequest struct {
// The roomID to query the latest events for.
// The room ID to query the latest events for.
RoomID string
// The state key tuples to fetch from the room current state.
// If this list is empty or nil then no state events are returned.
@ -44,6 +44,30 @@ type QueryLatestEventsAndStateResponse struct {
StateEvents []gomatrixserverlib.Event
}
// QueryStateAfterEventsRequest is a request to QueryStateAfterEvents
type QueryStateAfterEventsRequest struct {
// The room ID to query the state in.
RoomID string
// The list of previous events to return the events after.
PrevEventIDs []string
// The state key tuples to fetch from the state
StateToFetch []gomatrixserverlib.StateKeyTuple
}
// QueryStateAfterEventsResponse is a response to QueryStateAfterEvents
type QueryStateAfterEventsResponse struct {
// Copy of the request for debugging.
QueryStateAfterEventsRequest
// Does the room exist on this roomserver?
// If the room doesn't exist this will be false and StateEvents will be empty.
RoomExists bool
// Do all the previous events exist on this roomserver?
// If some of previous events do not exist this will be false and StateEvents will be empty.
PrevEventsExist bool
// The state events requested.
StateEvents []gomatrixserverlib.Event
}
// RoomserverQueryAPI is used to query information from the room server.
type RoomserverQueryAPI interface {
// Query the latest events and state for a room from the room server.
@ -51,11 +75,20 @@ type RoomserverQueryAPI interface {
request *QueryLatestEventsAndStateRequest,
response *QueryLatestEventsAndStateResponse,
) error
// Query the state after a list of events in a room from the room server.
QueryStateAfterEvents(
request *QueryStateAfterEventsRequest,
response *QueryStateAfterEventsResponse,
) error
}
// RoomserverQueryLatestEventsAndStatePath is the HTTP path for the QueryLatestEventsAndState API.
const RoomserverQueryLatestEventsAndStatePath = "/api/roomserver/QueryLatestEventsAndState"
// RoomserverQueryStateAfterEventsPath is the HTTP path for the QueryStateAfterEvents API.
const RoomserverQueryStateAfterEventsPath = "/api/roomserver/QueryStateAfterEvents"
// NewRoomserverQueryAPIHTTP creates a RoomserverQueryAPI implemented by talking to a HTTP POST API.
// If httpClient is nil then it uses the http.DefaultClient
func NewRoomserverQueryAPIHTTP(roomserverURL string, httpClient *http.Client) RoomserverQueryAPI {
@ -79,6 +112,15 @@ func (h *httpRoomserverQueryAPI) QueryLatestEventsAndState(
return postJSON(h.httpClient, apiURL, request, response)
}
// QueryStateAfterEvents implements RoomserverQueryAPI
func (h *httpRoomserverQueryAPI) QueryStateAfterEvents(
request *QueryStateAfterEventsRequest,
response *QueryStateAfterEventsResponse,
) error {
apiURL := h.roomserverURL + RoomserverQueryStateAfterEventsPath
return postJSON(h.httpClient, apiURL, request, response)
}
func postJSON(httpClient http.Client, apiURL string, request, response interface{}) error {
jsonBytes, err := json.Marshal(request)
if err != nil {

View file

@ -38,6 +38,8 @@ type RoomserverQueryAPIDatabase interface {
// Lookup the Events for a list of numeric event IDs.
// Returns a list of events sorted by numeric event ID.
Events(eventNIDs []types.EventNID) ([]types.Event, error)
// Lookup the state at a list of string event IDs.
StateAtEventIDs(eventIDs []string) ([]types.StateAtEvent, error)
}
// RoomserverQueryAPI is an implementation of RoomserverQueryAPI
@ -88,6 +90,33 @@ func (r *RoomserverQueryAPI) QueryLatestEventsAndState(
return nil
}
// QueryStateAfterEvents implements api.RoomserverQueryAPI
func (r *RoomserverQueryAPI) QueryStateAfterEvents(
request *api.QueryStateAfterEventsRequest,
response *api.QueryStateAfterEventsResponse,
) (err error) {
response.QueryStateAfterEventsRequest = *request
roomNID, err := r.DB.RoomNID(request.RoomID)
if err != nil {
return err
}
if roomNID == 0 {
return nil
}
response.RoomExists = true
_, err = r.DB.StateAtEventIDs(request.PrevEventIDs)
if err != nil {
// TODO: Check if the error was because we are missing events from the
// database or are missing state at events from the database.
return err
}
response.PrevEventsExist = true
// TODO: Calculate the state and return it.
return nil
}
// SetupHTTP adds the RoomserverQueryAPI handlers to the http.ServeMux.
func (r *RoomserverQueryAPI) SetupHTTP(servMux *http.ServeMux) {
servMux.Handle(
@ -104,6 +133,20 @@ func (r *RoomserverQueryAPI) SetupHTTP(servMux *http.ServeMux) {
return util.JSONResponse{Code: 200, JSON: &response}
}),
)
servMux.Handle(
api.RoomserverQueryStateAfterEventsPath,
makeAPI("query_state_after_events", func(req *http.Request) util.JSONResponse {
var request api.QueryStateAfterEventsRequest
var response api.QueryStateAfterEventsResponse
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
return util.ErrorResponse(err)
}
if err := r.QueryStateAfterEvents(&request, &response); err != nil {
return util.ErrorResponse(err)
}
return util.JSONResponse{Code: 200, JSON: &response}
}),
)
}
func makeAPI(metric string, apiFunc func(req *http.Request) util.JSONResponse) http.Handler {