Add Queryer and Inputer and factor out more RSAPI stuff (#1382)
* Add Queryer and use embedded structs * Add Inputer and factor out more RS API stuff This neatly splits up the RS API based on the functionality it provides, whilst providing a useful place for code sharing via the `helpers` package.main
parent
f06637435b
commit
9d9e854fe0
|
@ -270,7 +270,7 @@ func buildMembershipEvent(
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return eventutil.BuildEvent(ctx, &builder, cfg.Matrix, evTime, rsAPI, nil)
|
return eventutil.QueryAndBuildEvent(ctx, &builder, cfg.Matrix, evTime, rsAPI, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadProfile lookups the profile of a given user from the database and returns
|
// loadProfile lookups the profile of a given user from the database and returns
|
||||||
|
|
|
@ -375,7 +375,7 @@ func buildMembershipEvents(
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
event, err := eventutil.BuildEvent(ctx, &builder, cfg.Matrix, evTime, rsAPI, nil)
|
event, err := eventutil.QueryAndBuildEvent(ctx, &builder, cfg.Matrix, evTime, rsAPI, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,7 @@ func SendRedaction(
|
||||||
}
|
}
|
||||||
|
|
||||||
var queryRes api.QueryLatestEventsAndStateResponse
|
var queryRes api.QueryLatestEventsAndStateResponse
|
||||||
e, err := eventutil.BuildEvent(req.Context(), &builder, cfg.Matrix, time.Now(), rsAPI, &queryRes)
|
e, err := eventutil.QueryAndBuildEvent(req.Context(), &builder, cfg.Matrix, time.Now(), rsAPI, &queryRes)
|
||||||
if err == eventutil.ErrRoomNoExists {
|
if err == eventutil.ErrRoomNoExists {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
Code: http.StatusNotFound,
|
Code: http.StatusNotFound,
|
||||||
|
|
|
@ -158,7 +158,7 @@ func generateSendEvent(
|
||||||
}
|
}
|
||||||
|
|
||||||
var queryRes api.QueryLatestEventsAndStateResponse
|
var queryRes api.QueryLatestEventsAndStateResponse
|
||||||
e, err := eventutil.BuildEvent(req.Context(), &builder, cfg.Matrix, evTime, rsAPI, &queryRes)
|
e, err := eventutil.QueryAndBuildEvent(req.Context(), &builder, cfg.Matrix, evTime, rsAPI, &queryRes)
|
||||||
if err == eventutil.ErrRoomNoExists {
|
if err == eventutil.ErrRoomNoExists {
|
||||||
return nil, &util.JSONResponse{
|
return nil, &util.JSONResponse{
|
||||||
Code: http.StatusNotFound,
|
Code: http.StatusNotFound,
|
||||||
|
|
|
@ -354,7 +354,7 @@ func emit3PIDInviteEvent(
|
||||||
}
|
}
|
||||||
|
|
||||||
queryRes := api.QueryLatestEventsAndStateResponse{}
|
queryRes := api.QueryLatestEventsAndStateResponse{}
|
||||||
event, err := eventutil.BuildEvent(ctx, builder, cfg.Matrix, evTime, rsAPI, &queryRes)
|
event, err := eventutil.QueryAndBuildEvent(ctx, builder, cfg.Matrix, evTime, rsAPI, &queryRes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,7 @@ func MakeJoin(
|
||||||
queryRes := api.QueryLatestEventsAndStateResponse{
|
queryRes := api.QueryLatestEventsAndStateResponse{
|
||||||
RoomVersion: verRes.RoomVersion,
|
RoomVersion: verRes.RoomVersion,
|
||||||
}
|
}
|
||||||
event, err := eventutil.BuildEvent(httpReq.Context(), &builder, cfg.Matrix, time.Now(), rsAPI, &queryRes)
|
event, err := eventutil.QueryAndBuildEvent(httpReq.Context(), &builder, cfg.Matrix, time.Now(), rsAPI, &queryRes)
|
||||||
if err == eventutil.ErrRoomNoExists {
|
if err == eventutil.ErrRoomNoExists {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
Code: http.StatusNotFound,
|
Code: http.StatusNotFound,
|
||||||
|
|
|
@ -61,7 +61,7 @@ func MakeLeave(
|
||||||
}
|
}
|
||||||
|
|
||||||
var queryRes api.QueryLatestEventsAndStateResponse
|
var queryRes api.QueryLatestEventsAndStateResponse
|
||||||
event, err := eventutil.BuildEvent(httpReq.Context(), &builder, cfg.Matrix, time.Now(), rsAPI, &queryRes)
|
event, err := eventutil.QueryAndBuildEvent(httpReq.Context(), &builder, cfg.Matrix, time.Now(), rsAPI, &queryRes)
|
||||||
if err == eventutil.ErrRoomNoExists {
|
if err == eventutil.ErrRoomNoExists {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
Code: http.StatusNotFound,
|
Code: http.StatusNotFound,
|
||||||
|
|
|
@ -30,13 +30,13 @@ import (
|
||||||
// doesn't exist
|
// doesn't exist
|
||||||
var ErrRoomNoExists = errors.New("Room does not exist")
|
var ErrRoomNoExists = errors.New("Room does not exist")
|
||||||
|
|
||||||
// BuildEvent builds a Matrix event using the event builder and roomserver query
|
// QueryAndBuildEvent builds a Matrix event using the event builder and roomserver query
|
||||||
// API client provided. If also fills roomserver query API response (if provided)
|
// API client provided. If also fills roomserver query API response (if provided)
|
||||||
// in case the function calling FillBuilder needs to use it.
|
// in case the function calling FillBuilder needs to use it.
|
||||||
// Returns ErrRoomNoExists if the state of the room could not be retrieved because
|
// Returns ErrRoomNoExists if the state of the room could not be retrieved because
|
||||||
// the room doesn't exist
|
// the room doesn't exist
|
||||||
// Returns an error if something else went wrong
|
// Returns an error if something else went wrong
|
||||||
func BuildEvent(
|
func QueryAndBuildEvent(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
builder *gomatrixserverlib.EventBuilder, cfg *config.Global, evTime time.Time,
|
builder *gomatrixserverlib.EventBuilder, cfg *config.Global, evTime time.Time,
|
||||||
rsAPI api.RoomserverInternalAPI, queryRes *api.QueryLatestEventsAndStateResponse,
|
rsAPI api.RoomserverInternalAPI, queryRes *api.QueryLatestEventsAndStateResponse,
|
||||||
|
@ -45,11 +45,25 @@ func BuildEvent(
|
||||||
queryRes = &api.QueryLatestEventsAndStateResponse{}
|
queryRes = &api.QueryLatestEventsAndStateResponse{}
|
||||||
}
|
}
|
||||||
|
|
||||||
ver, err := AddPrevEventsToEvent(ctx, builder, rsAPI, queryRes)
|
eventsNeeded, err := queryRequiredEventsForBuilder(ctx, builder, rsAPI, queryRes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// This can pass through a ErrRoomNoExists to the caller
|
// This can pass through a ErrRoomNoExists to the caller
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
return BuildEvent(ctx, builder, cfg, evTime, eventsNeeded, queryRes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildEvent builds a Matrix event from the builder and QueryLatestEventsAndStateResponse
|
||||||
|
// provided.
|
||||||
|
func BuildEvent(
|
||||||
|
ctx context.Context,
|
||||||
|
builder *gomatrixserverlib.EventBuilder, cfg *config.Global, evTime time.Time,
|
||||||
|
eventsNeeded *gomatrixserverlib.StateNeeded, queryRes *api.QueryLatestEventsAndStateResponse,
|
||||||
|
) (*gomatrixserverlib.HeaderedEvent, error) {
|
||||||
|
err := addPrevEventsToEvent(builder, eventsNeeded, queryRes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
event, err := builder.Build(
|
event, err := builder.Build(
|
||||||
evTime, cfg.ServerName, cfg.KeyID,
|
evTime, cfg.ServerName, cfg.KeyID,
|
||||||
|
@ -59,23 +73,23 @@ func BuildEvent(
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
h := event.Headered(ver)
|
h := event.Headered(queryRes.RoomVersion)
|
||||||
return &h, nil
|
return &h, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddPrevEventsToEvent fills out the prev_events and auth_events fields in builder
|
// queryRequiredEventsForBuilder queries the roomserver for auth/prev events needed for this builder.
|
||||||
func AddPrevEventsToEvent(
|
func queryRequiredEventsForBuilder(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
builder *gomatrixserverlib.EventBuilder,
|
builder *gomatrixserverlib.EventBuilder,
|
||||||
rsAPI api.RoomserverInternalAPI, queryRes *api.QueryLatestEventsAndStateResponse,
|
rsAPI api.RoomserverInternalAPI, queryRes *api.QueryLatestEventsAndStateResponse,
|
||||||
) (gomatrixserverlib.RoomVersion, error) {
|
) (*gomatrixserverlib.StateNeeded, error) {
|
||||||
eventsNeeded, err := gomatrixserverlib.StateNeededForEventBuilder(builder)
|
eventsNeeded, err := gomatrixserverlib.StateNeededForEventBuilder(builder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("gomatrixserverlib.StateNeededForEventBuilder: %w", err)
|
return nil, fmt.Errorf("gomatrixserverlib.StateNeededForEventBuilder: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(eventsNeeded.Tuples()) == 0 {
|
if len(eventsNeeded.Tuples()) == 0 {
|
||||||
return "", errors.New("expecting state tuples for event builder, got none")
|
return nil, errors.New("expecting state tuples for event builder, got none")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ask the roomserver for information about this room
|
// Ask the roomserver for information about this room
|
||||||
|
@ -83,17 +97,22 @@ func AddPrevEventsToEvent(
|
||||||
RoomID: builder.RoomID,
|
RoomID: builder.RoomID,
|
||||||
StateToFetch: eventsNeeded.Tuples(),
|
StateToFetch: eventsNeeded.Tuples(),
|
||||||
}
|
}
|
||||||
if err = rsAPI.QueryLatestEventsAndState(ctx, &queryReq, queryRes); err != nil {
|
return &eventsNeeded, rsAPI.QueryLatestEventsAndState(ctx, &queryReq, queryRes)
|
||||||
return "", fmt.Errorf("rsAPI.QueryLatestEventsAndState: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// addPrevEventsToEvent fills out the prev_events and auth_events fields in builder
|
||||||
|
func addPrevEventsToEvent(
|
||||||
|
builder *gomatrixserverlib.EventBuilder,
|
||||||
|
eventsNeeded *gomatrixserverlib.StateNeeded,
|
||||||
|
queryRes *api.QueryLatestEventsAndStateResponse,
|
||||||
|
) error {
|
||||||
if !queryRes.RoomExists {
|
if !queryRes.RoomExists {
|
||||||
return "", ErrRoomNoExists
|
return ErrRoomNoExists
|
||||||
}
|
}
|
||||||
|
|
||||||
eventFormat, err := queryRes.RoomVersion.EventFormat()
|
eventFormat, err := queryRes.RoomVersion.EventFormat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("queryRes.RoomVersion.EventFormat: %w", err)
|
return fmt.Errorf("queryRes.RoomVersion.EventFormat: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.Depth = queryRes.Depth
|
builder.Depth = queryRes.Depth
|
||||||
|
@ -103,13 +122,13 @@ func AddPrevEventsToEvent(
|
||||||
for i := range queryRes.StateEvents {
|
for i := range queryRes.StateEvents {
|
||||||
err = authEvents.AddEvent(&queryRes.StateEvents[i].Event)
|
err = authEvents.AddEvent(&queryRes.StateEvents[i].Event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("authEvents.AddEvent: %w", err)
|
return fmt.Errorf("authEvents.AddEvent: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
refs, err := eventsNeeded.AuthEventReferences(&authEvents)
|
refs, err := eventsNeeded.AuthEventReferences(&authEvents)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("eventsNeeded.AuthEventReferences: %w", err)
|
return fmt.Errorf("eventsNeeded.AuthEventReferences: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
truncAuth, truncPrev := truncateAuthAndPrevEvents(refs, queryRes.LatestEvents)
|
truncAuth, truncPrev := truncateAuthAndPrevEvents(refs, queryRes.LatestEvents)
|
||||||
|
@ -129,7 +148,7 @@ func AddPrevEventsToEvent(
|
||||||
builder.PrevEvents = v2PrevRefs
|
builder.PrevEvents = v2PrevRefs
|
||||||
}
|
}
|
||||||
|
|
||||||
return queryRes.RoomVersion, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// truncateAuthAndPrevEvents limits the number of events we add into
|
// truncateAuthAndPrevEvents limits the number of events we add into
|
||||||
|
|
|
@ -2,20 +2,28 @@ package internal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/Shopify/sarama"
|
"github.com/Shopify/sarama"
|
||||||
fsAPI "github.com/matrix-org/dendrite/federationsender/api"
|
fsAPI "github.com/matrix-org/dendrite/federationsender/api"
|
||||||
"github.com/matrix-org/dendrite/internal/caching"
|
"github.com/matrix-org/dendrite/internal/caching"
|
||||||
"github.com/matrix-org/dendrite/internal/config"
|
"github.com/matrix-org/dendrite/internal/config"
|
||||||
"github.com/matrix-org/dendrite/roomserver/api"
|
"github.com/matrix-org/dendrite/roomserver/api"
|
||||||
|
"github.com/matrix-org/dendrite/roomserver/internal/input"
|
||||||
"github.com/matrix-org/dendrite/roomserver/internal/perform"
|
"github.com/matrix-org/dendrite/roomserver/internal/perform"
|
||||||
|
"github.com/matrix-org/dendrite/roomserver/internal/query"
|
||||||
"github.com/matrix-org/dendrite/roomserver/storage"
|
"github.com/matrix-org/dendrite/roomserver/storage"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RoomserverInternalAPI is an implementation of api.RoomserverInternalAPI
|
// RoomserverInternalAPI is an implementation of api.RoomserverInternalAPI
|
||||||
type RoomserverInternalAPI struct {
|
type RoomserverInternalAPI struct {
|
||||||
|
*input.Inputer
|
||||||
|
*query.Queryer
|
||||||
|
*perform.Inviter
|
||||||
|
*perform.Joiner
|
||||||
|
*perform.Leaver
|
||||||
|
*perform.Publisher
|
||||||
|
*perform.Backfiller
|
||||||
DB storage.Database
|
DB storage.Database
|
||||||
Cfg *config.RoomServer
|
Cfg *config.RoomServer
|
||||||
Producer sarama.SyncProducer
|
Producer sarama.SyncProducer
|
||||||
|
@ -24,12 +32,6 @@ type RoomserverInternalAPI struct {
|
||||||
KeyRing gomatrixserverlib.JSONVerifier
|
KeyRing gomatrixserverlib.JSONVerifier
|
||||||
fsAPI fsAPI.FederationSenderInternalAPI
|
fsAPI fsAPI.FederationSenderInternalAPI
|
||||||
OutputRoomEventTopic string // Kafka topic for new output room events
|
OutputRoomEventTopic string // Kafka topic for new output room events
|
||||||
Inviter *perform.Inviter
|
|
||||||
Joiner *perform.Joiner
|
|
||||||
Leaver *perform.Leaver
|
|
||||||
Publisher *perform.Publisher
|
|
||||||
Backfiller *perform.Backfiller
|
|
||||||
mutexes sync.Map // room ID -> *sync.Mutex, protects calls to processRoomEvent
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRoomserverAPI(
|
func NewRoomserverAPI(
|
||||||
|
@ -40,11 +42,19 @@ func NewRoomserverAPI(
|
||||||
a := &RoomserverInternalAPI{
|
a := &RoomserverInternalAPI{
|
||||||
DB: roomserverDB,
|
DB: roomserverDB,
|
||||||
Cfg: cfg,
|
Cfg: cfg,
|
||||||
Producer: producer,
|
|
||||||
Cache: caches,
|
Cache: caches,
|
||||||
ServerName: cfg.Matrix.ServerName,
|
ServerName: cfg.Matrix.ServerName,
|
||||||
KeyRing: keyRing,
|
KeyRing: keyRing,
|
||||||
|
Queryer: &query.Queryer{
|
||||||
|
DB: roomserverDB,
|
||||||
|
Cache: caches,
|
||||||
|
},
|
||||||
|
Inputer: &input.Inputer{
|
||||||
|
DB: roomserverDB,
|
||||||
OutputRoomEventTopic: outputRoomEventTopic,
|
OutputRoomEventTopic: outputRoomEventTopic,
|
||||||
|
Producer: producer,
|
||||||
|
ServerName: cfg.Matrix.ServerName,
|
||||||
|
},
|
||||||
// perform-er structs get initialised when we have a federation sender to use
|
// perform-er structs get initialised when we have a federation sender to use
|
||||||
}
|
}
|
||||||
return a
|
return a
|
||||||
|
@ -60,20 +70,20 @@ func (r *RoomserverInternalAPI) SetFederationSenderAPI(fsAPI fsAPI.FederationSen
|
||||||
DB: r.DB,
|
DB: r.DB,
|
||||||
Cfg: r.Cfg,
|
Cfg: r.Cfg,
|
||||||
FSAPI: r.fsAPI,
|
FSAPI: r.fsAPI,
|
||||||
RSAPI: r,
|
Inputer: r.Inputer,
|
||||||
}
|
}
|
||||||
r.Joiner = &perform.Joiner{
|
r.Joiner = &perform.Joiner{
|
||||||
ServerName: r.Cfg.Matrix.ServerName,
|
ServerName: r.Cfg.Matrix.ServerName,
|
||||||
Cfg: r.Cfg,
|
Cfg: r.Cfg,
|
||||||
DB: r.DB,
|
DB: r.DB,
|
||||||
FSAPI: r.fsAPI,
|
FSAPI: r.fsAPI,
|
||||||
RSAPI: r,
|
Inputer: r.Inputer,
|
||||||
}
|
}
|
||||||
r.Leaver = &perform.Leaver{
|
r.Leaver = &perform.Leaver{
|
||||||
Cfg: r.Cfg,
|
Cfg: r.Cfg,
|
||||||
DB: r.DB,
|
DB: r.DB,
|
||||||
FSAPI: r.fsAPI,
|
FSAPI: r.fsAPI,
|
||||||
RSAPI: r,
|
Inputer: r.Inputer,
|
||||||
}
|
}
|
||||||
r.Publisher = &perform.Publisher{
|
r.Publisher = &perform.Publisher{
|
||||||
DB: r.DB,
|
DB: r.DB,
|
||||||
|
@ -101,14 +111,6 @@ func (r *RoomserverInternalAPI) PerformInvite(
|
||||||
return r.WriteOutputEvents(req.Event.RoomID(), outputEvents)
|
return r.WriteOutputEvents(req.Event.RoomID(), outputEvents)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RoomserverInternalAPI) PerformJoin(
|
|
||||||
ctx context.Context,
|
|
||||||
req *api.PerformJoinRequest,
|
|
||||||
res *api.PerformJoinResponse,
|
|
||||||
) {
|
|
||||||
r.Joiner.PerformJoin(ctx, req, res)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *RoomserverInternalAPI) PerformLeave(
|
func (r *RoomserverInternalAPI) PerformLeave(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *api.PerformLeaveRequest,
|
req *api.PerformLeaveRequest,
|
||||||
|
@ -123,20 +125,3 @@ func (r *RoomserverInternalAPI) PerformLeave(
|
||||||
}
|
}
|
||||||
return r.WriteOutputEvents(req.RoomID, outputEvents)
|
return r.WriteOutputEvents(req.RoomID, outputEvents)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RoomserverInternalAPI) PerformPublish(
|
|
||||||
ctx context.Context,
|
|
||||||
req *api.PerformPublishRequest,
|
|
||||||
res *api.PerformPublishResponse,
|
|
||||||
) {
|
|
||||||
r.Publisher.PerformPublish(ctx, req, res)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Query a given amount (or less) of events prior to a given set of events.
|
|
||||||
func (r *RoomserverInternalAPI) PerformBackfill(
|
|
||||||
ctx context.Context,
|
|
||||||
request *api.PerformBackfillRequest,
|
|
||||||
response *api.PerformBackfillResponse,
|
|
||||||
) error {
|
|
||||||
return r.Backfiller.PerformBackfill(ctx, request, response)
|
|
||||||
}
|
|
||||||
|
|
|
@ -324,3 +324,56 @@ BFSLoop:
|
||||||
|
|
||||||
return resultNIDs, err
|
return resultNIDs, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func QueryLatestEventsAndState(
|
||||||
|
ctx context.Context, db storage.Database,
|
||||||
|
request *api.QueryLatestEventsAndStateRequest,
|
||||||
|
response *api.QueryLatestEventsAndStateResponse,
|
||||||
|
) error {
|
||||||
|
roomInfo, err := db.RoomInfo(ctx, request.RoomID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if roomInfo == nil || roomInfo.IsStub {
|
||||||
|
response.RoomExists = false
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
roomState := state.NewStateResolution(db, *roomInfo)
|
||||||
|
response.RoomExists = true
|
||||||
|
response.RoomVersion = roomInfo.RoomVersion
|
||||||
|
|
||||||
|
var currentStateSnapshotNID types.StateSnapshotNID
|
||||||
|
response.LatestEvents, currentStateSnapshotNID, response.Depth, err =
|
||||||
|
db.LatestEventIDs(ctx, roomInfo.RoomNID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var stateEntries []types.StateEntry
|
||||||
|
if len(request.StateToFetch) == 0 {
|
||||||
|
// Look up all room state.
|
||||||
|
stateEntries, err = roomState.LoadStateAtSnapshot(
|
||||||
|
ctx, currentStateSnapshotNID,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
// Look up the current state for the requested tuples.
|
||||||
|
stateEntries, err = roomState.LoadStateAtSnapshotForStringTuples(
|
||||||
|
ctx, currentStateSnapshotNID, request.StateToFetch,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
stateEvents, err := LoadStateEvents(ctx, db, stateEntries)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, event := range stateEvents {
|
||||||
|
response.StateEvents = append(response.StateEvents, event.Headered(roomInfo.RoomVersion))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
// Package input contains the code processes new room events
|
// Package input contains the code processes new room events
|
||||||
package internal
|
package input
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
@ -22,11 +22,22 @@ import (
|
||||||
|
|
||||||
"github.com/Shopify/sarama"
|
"github.com/Shopify/sarama"
|
||||||
"github.com/matrix-org/dendrite/roomserver/api"
|
"github.com/matrix-org/dendrite/roomserver/api"
|
||||||
|
"github.com/matrix-org/dendrite/roomserver/storage"
|
||||||
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Inputer struct {
|
||||||
|
DB storage.Database
|
||||||
|
Producer sarama.SyncProducer
|
||||||
|
ServerName gomatrixserverlib.ServerName
|
||||||
|
OutputRoomEventTopic string
|
||||||
|
|
||||||
|
mutexes sync.Map // room ID -> *sync.Mutex, protects calls to processRoomEvent
|
||||||
|
}
|
||||||
|
|
||||||
// WriteOutputEvents implements OutputRoomEventWriter
|
// WriteOutputEvents implements OutputRoomEventWriter
|
||||||
func (r *RoomserverInternalAPI) WriteOutputEvents(roomID string, updates []api.OutputEvent) error {
|
func (r *Inputer) WriteOutputEvents(roomID string, updates []api.OutputEvent) error {
|
||||||
messages := make([]*sarama.ProducerMessage, len(updates))
|
messages := make([]*sarama.ProducerMessage, len(updates))
|
||||||
for i := range updates {
|
for i := range updates {
|
||||||
value, err := json.Marshal(updates[i])
|
value, err := json.Marshal(updates[i])
|
||||||
|
@ -58,7 +69,7 @@ func (r *RoomserverInternalAPI) WriteOutputEvents(roomID string, updates []api.O
|
||||||
}
|
}
|
||||||
|
|
||||||
// InputRoomEvents implements api.RoomserverInternalAPI
|
// InputRoomEvents implements api.RoomserverInternalAPI
|
||||||
func (r *RoomserverInternalAPI) InputRoomEvents(
|
func (r *Inputer) InputRoomEvents(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
request *api.InputRoomEventsRequest,
|
request *api.InputRoomEventsRequest,
|
||||||
response *api.InputRoomEventsResponse,
|
response *api.InputRoomEventsResponse,
|
|
@ -14,7 +14,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package internal
|
package input
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
@ -36,7 +36,7 @@ import (
|
||||||
// state deltas when sending to kafka streams
|
// state deltas when sending to kafka streams
|
||||||
// TODO: Break up function - we should probably do transaction ID checks before calling this.
|
// TODO: Break up function - we should probably do transaction ID checks before calling this.
|
||||||
// nolint:gocyclo
|
// nolint:gocyclo
|
||||||
func (r *RoomserverInternalAPI) processRoomEvent(
|
func (r *Inputer) processRoomEvent(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
input api.InputRoomEvent,
|
input api.InputRoomEvent,
|
||||||
) (eventID string, err error) {
|
) (eventID string, err error) {
|
||||||
|
@ -141,7 +141,7 @@ func (r *RoomserverInternalAPI) processRoomEvent(
|
||||||
return event.EventID(), nil
|
return event.EventID(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RoomserverInternalAPI) calculateAndSetState(
|
func (r *Inputer) calculateAndSetState(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
input api.InputRoomEvent,
|
input api.InputRoomEvent,
|
||||||
roomInfo types.RoomInfo,
|
roomInfo types.RoomInfo,
|
|
@ -14,7 +14,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package internal
|
package input
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
@ -47,7 +47,7 @@ import (
|
||||||
// 7 <----- latest
|
// 7 <----- latest
|
||||||
//
|
//
|
||||||
// Can only be called once at a time
|
// Can only be called once at a time
|
||||||
func (r *RoomserverInternalAPI) updateLatestEvents(
|
func (r *Inputer) updateLatestEvents(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
roomInfo *types.RoomInfo,
|
roomInfo *types.RoomInfo,
|
||||||
stateAtEvent types.StateAtEvent,
|
stateAtEvent types.StateAtEvent,
|
||||||
|
@ -87,7 +87,7 @@ func (r *RoomserverInternalAPI) updateLatestEvents(
|
||||||
// when there are so many variables to pass around.
|
// when there are so many variables to pass around.
|
||||||
type latestEventsUpdater struct {
|
type latestEventsUpdater struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
api *RoomserverInternalAPI
|
api *Inputer
|
||||||
updater *shared.LatestEventsUpdater
|
updater *shared.LatestEventsUpdater
|
||||||
roomInfo *types.RoomInfo
|
roomInfo *types.RoomInfo
|
||||||
stateAtEvent types.StateAtEvent
|
stateAtEvent types.StateAtEvent
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package internal
|
package input
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
@ -29,7 +29,7 @@ import (
|
||||||
// user affected by a change in the current state of the room.
|
// user affected by a change in the current state of the room.
|
||||||
// Returns a list of output events to write to the kafka log to inform the
|
// Returns a list of output events to write to the kafka log to inform the
|
||||||
// consumers about the invites added or retired by the change in current state.
|
// consumers about the invites added or retired by the change in current state.
|
||||||
func (r *RoomserverInternalAPI) updateMemberships(
|
func (r *Inputer) updateMemberships(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
updater *shared.LatestEventsUpdater,
|
updater *shared.LatestEventsUpdater,
|
||||||
removed, added []types.StateEntry,
|
removed, added []types.StateEntry,
|
||||||
|
@ -78,7 +78,7 @@ func (r *RoomserverInternalAPI) updateMemberships(
|
||||||
return updates, nil
|
return updates, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RoomserverInternalAPI) updateMembership(
|
func (r *Inputer) updateMembership(
|
||||||
updater *shared.LatestEventsUpdater,
|
updater *shared.LatestEventsUpdater,
|
||||||
targetUserNID types.EventStateKeyNID,
|
targetUserNID types.EventStateKeyNID,
|
||||||
remove, add *gomatrixserverlib.Event,
|
remove, add *gomatrixserverlib.Event,
|
||||||
|
@ -133,11 +133,11 @@ func (r *RoomserverInternalAPI) updateMembership(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RoomserverInternalAPI) isLocalTarget(event *gomatrixserverlib.Event) bool {
|
func (r *Inputer) isLocalTarget(event *gomatrixserverlib.Event) bool {
|
||||||
isTargetLocalUser := false
|
isTargetLocalUser := false
|
||||||
if statekey := event.StateKey(); statekey != nil {
|
if statekey := event.StateKey(); statekey != nil {
|
||||||
_, domain, _ := gomatrixserverlib.SplitID('@', *statekey)
|
_, domain, _ := gomatrixserverlib.SplitID('@', *statekey)
|
||||||
isTargetLocalUser = domain == r.Cfg.Matrix.ServerName
|
isTargetLocalUser = domain == r.ServerName
|
||||||
}
|
}
|
||||||
return isTargetLocalUser
|
return isTargetLocalUser
|
||||||
}
|
}
|
|
@ -1,3 +1,17 @@
|
||||||
|
// Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
package perform
|
package perform
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,17 @@
|
||||||
|
// Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
package perform
|
package perform
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -8,6 +22,7 @@ import (
|
||||||
"github.com/matrix-org/dendrite/internal/config"
|
"github.com/matrix-org/dendrite/internal/config"
|
||||||
"github.com/matrix-org/dendrite/roomserver/api"
|
"github.com/matrix-org/dendrite/roomserver/api"
|
||||||
"github.com/matrix-org/dendrite/roomserver/internal/helpers"
|
"github.com/matrix-org/dendrite/roomserver/internal/helpers"
|
||||||
|
"github.com/matrix-org/dendrite/roomserver/internal/input"
|
||||||
"github.com/matrix-org/dendrite/roomserver/state"
|
"github.com/matrix-org/dendrite/roomserver/state"
|
||||||
"github.com/matrix-org/dendrite/roomserver/storage"
|
"github.com/matrix-org/dendrite/roomserver/storage"
|
||||||
"github.com/matrix-org/dendrite/roomserver/types"
|
"github.com/matrix-org/dendrite/roomserver/types"
|
||||||
|
@ -19,9 +34,7 @@ type Inviter struct {
|
||||||
DB storage.Database
|
DB storage.Database
|
||||||
Cfg *config.RoomServer
|
Cfg *config.RoomServer
|
||||||
FSAPI federationSenderAPI.FederationSenderInternalAPI
|
FSAPI federationSenderAPI.FederationSenderInternalAPI
|
||||||
|
Inputer *input.Inputer
|
||||||
// TODO FIXME: Remove this
|
|
||||||
RSAPI api.RoomserverInternalAPI
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint:gocyclo
|
// nolint:gocyclo
|
||||||
|
@ -170,7 +183,7 @@ func (r *Inviter) PerformInvite(
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
inputRes := &api.InputRoomEventsResponse{}
|
inputRes := &api.InputRoomEventsResponse{}
|
||||||
if err = r.RSAPI.InputRoomEvents(context.Background(), inputReq, inputRes); err != nil {
|
if err = r.Inputer.InputRoomEvents(context.Background(), inputReq, inputRes); err != nil {
|
||||||
return nil, fmt.Errorf("r.InputRoomEvents: %w", err)
|
return nil, fmt.Errorf("r.InputRoomEvents: %w", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,3 +1,17 @@
|
||||||
|
// Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
package perform
|
package perform
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -12,6 +26,7 @@ import (
|
||||||
"github.com/matrix-org/dendrite/internal/eventutil"
|
"github.com/matrix-org/dendrite/internal/eventutil"
|
||||||
"github.com/matrix-org/dendrite/roomserver/api"
|
"github.com/matrix-org/dendrite/roomserver/api"
|
||||||
"github.com/matrix-org/dendrite/roomserver/internal/helpers"
|
"github.com/matrix-org/dendrite/roomserver/internal/helpers"
|
||||||
|
"github.com/matrix-org/dendrite/roomserver/internal/input"
|
||||||
"github.com/matrix-org/dendrite/roomserver/storage"
|
"github.com/matrix-org/dendrite/roomserver/storage"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
@ -23,8 +38,7 @@ type Joiner struct {
|
||||||
FSAPI fsAPI.FederationSenderInternalAPI
|
FSAPI fsAPI.FederationSenderInternalAPI
|
||||||
DB storage.Database
|
DB storage.Database
|
||||||
|
|
||||||
// TODO FIXME: Remove this
|
Inputer *input.Inputer
|
||||||
RSAPI api.RoomserverInternalAPI
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PerformJoin handles joining matrix rooms, including over federation by talking to the federationsender.
|
// PerformJoin handles joining matrix rooms, including over federation by talking to the federationsender.
|
||||||
|
@ -201,15 +215,7 @@ func (r *Joiner) performJoinRoomByID(
|
||||||
// locally on the homeserver.
|
// locally on the homeserver.
|
||||||
// TODO: Check what happens if the room exists on the server
|
// TODO: Check what happens if the room exists on the server
|
||||||
// but everyone has since left. I suspect it does the wrong thing.
|
// but everyone has since left. I suspect it does the wrong thing.
|
||||||
buildRes := api.QueryLatestEventsAndStateResponse{}
|
event, buildRes, err := buildEvent(ctx, r.DB, r.Cfg.Matrix, &eb)
|
||||||
event, err := eventutil.BuildEvent(
|
|
||||||
ctx, // the request context
|
|
||||||
&eb, // the template join event
|
|
||||||
r.Cfg.Matrix, // the server configuration
|
|
||||||
time.Now(), // the event timestamp to use
|
|
||||||
r.RSAPI, // the roomserver API to use
|
|
||||||
&buildRes, // the query response
|
|
||||||
)
|
|
||||||
|
|
||||||
switch err {
|
switch err {
|
||||||
case nil:
|
case nil:
|
||||||
|
@ -241,7 +247,7 @@ func (r *Joiner) performJoinRoomByID(
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
inputRes := api.InputRoomEventsResponse{}
|
inputRes := api.InputRoomEventsResponse{}
|
||||||
if err = r.RSAPI.InputRoomEvents(ctx, &inputReq, &inputRes); err != nil {
|
if err = r.Inputer.InputRoomEvents(ctx, &inputReq, &inputRes); err != nil {
|
||||||
var notAllowed *gomatrixserverlib.NotAllowed
|
var notAllowed *gomatrixserverlib.NotAllowed
|
||||||
if errors.As(err, ¬Allowed) {
|
if errors.As(err, ¬Allowed) {
|
||||||
return "", &api.PerformError{
|
return "", &api.PerformError{
|
||||||
|
@ -306,3 +312,31 @@ func (r *Joiner) performFederatedJoinRoomByID(
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func buildEvent(
|
||||||
|
ctx context.Context, db storage.Database, cfg *config.Global, builder *gomatrixserverlib.EventBuilder,
|
||||||
|
) (*gomatrixserverlib.HeaderedEvent, *api.QueryLatestEventsAndStateResponse, error) {
|
||||||
|
eventsNeeded, err := gomatrixserverlib.StateNeededForEventBuilder(builder)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("gomatrixserverlib.StateNeededForEventBuilder: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(eventsNeeded.Tuples()) == 0 {
|
||||||
|
return nil, nil, errors.New("expecting state tuples for event builder, got none")
|
||||||
|
}
|
||||||
|
|
||||||
|
var queryRes api.QueryLatestEventsAndStateResponse
|
||||||
|
err = helpers.QueryLatestEventsAndState(ctx, db, &api.QueryLatestEventsAndStateRequest{
|
||||||
|
RoomID: builder.RoomID,
|
||||||
|
StateToFetch: eventsNeeded.Tuples(),
|
||||||
|
}, &queryRes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("QueryLatestEventsAndState: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ev, err := eventutil.BuildEvent(ctx, builder, cfg, time.Now(), &eventsNeeded, &queryRes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
return ev, &queryRes, nil
|
||||||
|
}
|
||||||
|
|
|
@ -1,16 +1,29 @@
|
||||||
|
// Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
package perform
|
package perform
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
fsAPI "github.com/matrix-org/dendrite/federationsender/api"
|
fsAPI "github.com/matrix-org/dendrite/federationsender/api"
|
||||||
"github.com/matrix-org/dendrite/internal/config"
|
"github.com/matrix-org/dendrite/internal/config"
|
||||||
"github.com/matrix-org/dendrite/internal/eventutil"
|
|
||||||
"github.com/matrix-org/dendrite/roomserver/api"
|
"github.com/matrix-org/dendrite/roomserver/api"
|
||||||
"github.com/matrix-org/dendrite/roomserver/internal/helpers"
|
"github.com/matrix-org/dendrite/roomserver/internal/helpers"
|
||||||
|
"github.com/matrix-org/dendrite/roomserver/internal/input"
|
||||||
"github.com/matrix-org/dendrite/roomserver/storage"
|
"github.com/matrix-org/dendrite/roomserver/storage"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
)
|
)
|
||||||
|
@ -20,8 +33,7 @@ type Leaver struct {
|
||||||
DB storage.Database
|
DB storage.Database
|
||||||
FSAPI fsAPI.FederationSenderInternalAPI
|
FSAPI fsAPI.FederationSenderInternalAPI
|
||||||
|
|
||||||
// TODO FIXME: Remove this
|
Inputer *input.Inputer
|
||||||
RSAPI api.RoomserverInternalAPI
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteOutputEvents implements OutputRoomEventWriter
|
// WriteOutputEvents implements OutputRoomEventWriter
|
||||||
|
@ -67,7 +79,7 @@ func (r *Leaver) performLeaveRoomByID(
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
latestRes := api.QueryLatestEventsAndStateResponse{}
|
latestRes := api.QueryLatestEventsAndStateResponse{}
|
||||||
if err = r.RSAPI.QueryLatestEventsAndState(ctx, &latestReq, &latestRes); err != nil {
|
if err = helpers.QueryLatestEventsAndState(ctx, r.DB, &latestReq, &latestRes); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !latestRes.RoomExists {
|
if !latestRes.RoomExists {
|
||||||
|
@ -108,15 +120,7 @@ func (r *Leaver) performLeaveRoomByID(
|
||||||
// a leave event.
|
// a leave event.
|
||||||
// TODO: Check what happens if the room exists on the server
|
// TODO: Check what happens if the room exists on the server
|
||||||
// but everyone has since left. I suspect it does the wrong thing.
|
// but everyone has since left. I suspect it does the wrong thing.
|
||||||
buildRes := api.QueryLatestEventsAndStateResponse{}
|
event, buildRes, err := buildEvent(ctx, r.DB, r.Cfg.Matrix, &eb)
|
||||||
event, err := eventutil.BuildEvent(
|
|
||||||
ctx, // the request context
|
|
||||||
&eb, // the template leave event
|
|
||||||
r.Cfg.Matrix, // the server configuration
|
|
||||||
time.Now(), // the event timestamp to use
|
|
||||||
r.RSAPI, // the roomserver API to use
|
|
||||||
&buildRes, // the query response
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("eventutil.BuildEvent: %w", err)
|
return nil, fmt.Errorf("eventutil.BuildEvent: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -135,7 +139,7 @@ func (r *Leaver) performLeaveRoomByID(
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
inputRes := api.InputRoomEventsResponse{}
|
inputRes := api.InputRoomEventsResponse{}
|
||||||
if err = r.RSAPI.InputRoomEvents(ctx, &inputReq, &inputRes); err != nil {
|
if err = r.Inputer.InputRoomEvents(ctx, &inputReq, &inputRes); err != nil {
|
||||||
return nil, fmt.Errorf("r.InputRoomEvents: %w", err)
|
return nil, fmt.Errorf("r.InputRoomEvents: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,17 @@
|
||||||
|
// Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
package perform
|
package perform
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
// Copyright 2017 Vector Creations Ltd
|
// Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
// Copyright 2018 New Vector Ltd
|
|
||||||
// Copyright 2019-2020 The Matrix.org Foundation C.I.C.
|
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -14,15 +12,17 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package internal
|
package query
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/internal/caching"
|
||||||
"github.com/matrix-org/dendrite/roomserver/api"
|
"github.com/matrix-org/dendrite/roomserver/api"
|
||||||
"github.com/matrix-org/dendrite/roomserver/internal/helpers"
|
"github.com/matrix-org/dendrite/roomserver/internal/helpers"
|
||||||
"github.com/matrix-org/dendrite/roomserver/state"
|
"github.com/matrix-org/dendrite/roomserver/state"
|
||||||
|
"github.com/matrix-org/dendrite/roomserver/storage"
|
||||||
"github.com/matrix-org/dendrite/roomserver/types"
|
"github.com/matrix-org/dendrite/roomserver/types"
|
||||||
"github.com/matrix-org/dendrite/roomserver/version"
|
"github.com/matrix-org/dendrite/roomserver/version"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
|
@ -30,62 +30,22 @@ import (
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Queryer struct {
|
||||||
|
DB storage.Database
|
||||||
|
Cache caching.RoomServerCaches
|
||||||
|
}
|
||||||
|
|
||||||
// QueryLatestEventsAndState implements api.RoomserverInternalAPI
|
// QueryLatestEventsAndState implements api.RoomserverInternalAPI
|
||||||
func (r *RoomserverInternalAPI) QueryLatestEventsAndState(
|
func (r *Queryer) QueryLatestEventsAndState(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
request *api.QueryLatestEventsAndStateRequest,
|
request *api.QueryLatestEventsAndStateRequest,
|
||||||
response *api.QueryLatestEventsAndStateResponse,
|
response *api.QueryLatestEventsAndStateResponse,
|
||||||
) error {
|
) error {
|
||||||
roomInfo, err := r.DB.RoomInfo(ctx, request.RoomID)
|
return helpers.QueryLatestEventsAndState(ctx, r.DB, request, response)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if roomInfo == nil || roomInfo.IsStub {
|
|
||||||
response.RoomExists = false
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
roomState := state.NewStateResolution(r.DB, *roomInfo)
|
|
||||||
response.RoomExists = true
|
|
||||||
response.RoomVersion = roomInfo.RoomVersion
|
|
||||||
|
|
||||||
var currentStateSnapshotNID types.StateSnapshotNID
|
|
||||||
response.LatestEvents, currentStateSnapshotNID, response.Depth, err =
|
|
||||||
r.DB.LatestEventIDs(ctx, roomInfo.RoomNID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var stateEntries []types.StateEntry
|
|
||||||
if len(request.StateToFetch) == 0 {
|
|
||||||
// Look up all room state.
|
|
||||||
stateEntries, err = roomState.LoadStateAtSnapshot(
|
|
||||||
ctx, currentStateSnapshotNID,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
// Look up the current state for the requested tuples.
|
|
||||||
stateEntries, err = roomState.LoadStateAtSnapshotForStringTuples(
|
|
||||||
ctx, currentStateSnapshotNID, request.StateToFetch,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
stateEvents, err := helpers.LoadStateEvents(ctx, r.DB, stateEntries)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, event := range stateEvents {
|
|
||||||
response.StateEvents = append(response.StateEvents, event.Headered(roomInfo.RoomVersion))
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryStateAfterEvents implements api.RoomserverInternalAPI
|
// QueryStateAfterEvents implements api.RoomserverInternalAPI
|
||||||
func (r *RoomserverInternalAPI) QueryStateAfterEvents(
|
func (r *Queryer) QueryStateAfterEvents(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
request *api.QueryStateAfterEventsRequest,
|
request *api.QueryStateAfterEventsRequest,
|
||||||
response *api.QueryStateAfterEventsResponse,
|
response *api.QueryStateAfterEventsResponse,
|
||||||
|
@ -134,7 +94,7 @@ func (r *RoomserverInternalAPI) QueryStateAfterEvents(
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryEventsByID implements api.RoomserverInternalAPI
|
// QueryEventsByID implements api.RoomserverInternalAPI
|
||||||
func (r *RoomserverInternalAPI) QueryEventsByID(
|
func (r *Queryer) QueryEventsByID(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
request *api.QueryEventsByIDRequest,
|
request *api.QueryEventsByIDRequest,
|
||||||
response *api.QueryEventsByIDResponse,
|
response *api.QueryEventsByIDResponse,
|
||||||
|
@ -167,7 +127,7 @@ func (r *RoomserverInternalAPI) QueryEventsByID(
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryMembershipForUser implements api.RoomserverInternalAPI
|
// QueryMembershipForUser implements api.RoomserverInternalAPI
|
||||||
func (r *RoomserverInternalAPI) QueryMembershipForUser(
|
func (r *Queryer) QueryMembershipForUser(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
request *api.QueryMembershipForUserRequest,
|
request *api.QueryMembershipForUserRequest,
|
||||||
response *api.QueryMembershipForUserResponse,
|
response *api.QueryMembershipForUserResponse,
|
||||||
|
@ -204,7 +164,7 @@ func (r *RoomserverInternalAPI) QueryMembershipForUser(
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryMembershipsForRoom implements api.RoomserverInternalAPI
|
// QueryMembershipsForRoom implements api.RoomserverInternalAPI
|
||||||
func (r *RoomserverInternalAPI) QueryMembershipsForRoom(
|
func (r *Queryer) QueryMembershipsForRoom(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
request *api.QueryMembershipsForRoomRequest,
|
request *api.QueryMembershipsForRoomRequest,
|
||||||
response *api.QueryMembershipsForRoomResponse,
|
response *api.QueryMembershipsForRoomResponse,
|
||||||
|
@ -260,7 +220,7 @@ func (r *RoomserverInternalAPI) QueryMembershipsForRoom(
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryServerAllowedToSeeEvent implements api.RoomserverInternalAPI
|
// QueryServerAllowedToSeeEvent implements api.RoomserverInternalAPI
|
||||||
func (r *RoomserverInternalAPI) QueryServerAllowedToSeeEvent(
|
func (r *Queryer) QueryServerAllowedToSeeEvent(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
request *api.QueryServerAllowedToSeeEventRequest,
|
request *api.QueryServerAllowedToSeeEventRequest,
|
||||||
response *api.QueryServerAllowedToSeeEventResponse,
|
response *api.QueryServerAllowedToSeeEventResponse,
|
||||||
|
@ -293,7 +253,7 @@ func (r *RoomserverInternalAPI) QueryServerAllowedToSeeEvent(
|
||||||
|
|
||||||
// QueryMissingEvents implements api.RoomserverInternalAPI
|
// QueryMissingEvents implements api.RoomserverInternalAPI
|
||||||
// nolint:gocyclo
|
// nolint:gocyclo
|
||||||
func (r *RoomserverInternalAPI) QueryMissingEvents(
|
func (r *Queryer) QueryMissingEvents(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
request *api.QueryMissingEventsRequest,
|
request *api.QueryMissingEventsRequest,
|
||||||
response *api.QueryMissingEventsResponse,
|
response *api.QueryMissingEventsResponse,
|
||||||
|
@ -352,7 +312,7 @@ func (r *RoomserverInternalAPI) QueryMissingEvents(
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryStateAndAuthChain implements api.RoomserverInternalAPI
|
// QueryStateAndAuthChain implements api.RoomserverInternalAPI
|
||||||
func (r *RoomserverInternalAPI) QueryStateAndAuthChain(
|
func (r *Queryer) QueryStateAndAuthChain(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
request *api.QueryStateAndAuthChainRequest,
|
request *api.QueryStateAndAuthChainRequest,
|
||||||
response *api.QueryStateAndAuthChainResponse,
|
response *api.QueryStateAndAuthChainResponse,
|
||||||
|
@ -405,7 +365,7 @@ func (r *RoomserverInternalAPI) QueryStateAndAuthChain(
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RoomserverInternalAPI) loadStateAtEventIDs(ctx context.Context, roomInfo types.RoomInfo, eventIDs []string) ([]gomatrixserverlib.Event, error) {
|
func (r *Queryer) loadStateAtEventIDs(ctx context.Context, roomInfo types.RoomInfo, eventIDs []string) ([]gomatrixserverlib.Event, error) {
|
||||||
roomState := state.NewStateResolution(r.DB, roomInfo)
|
roomState := state.NewStateResolution(r.DB, roomInfo)
|
||||||
prevStates, err := r.DB.StateAtEventIDs(ctx, eventIDs)
|
prevStates, err := r.DB.StateAtEventIDs(ctx, eventIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -482,7 +442,7 @@ func getAuthChain(
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryRoomVersionCapabilities implements api.RoomserverInternalAPI
|
// QueryRoomVersionCapabilities implements api.RoomserverInternalAPI
|
||||||
func (r *RoomserverInternalAPI) QueryRoomVersionCapabilities(
|
func (r *Queryer) QueryRoomVersionCapabilities(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
request *api.QueryRoomVersionCapabilitiesRequest,
|
request *api.QueryRoomVersionCapabilitiesRequest,
|
||||||
response *api.QueryRoomVersionCapabilitiesResponse,
|
response *api.QueryRoomVersionCapabilitiesResponse,
|
||||||
|
@ -500,7 +460,7 @@ func (r *RoomserverInternalAPI) QueryRoomVersionCapabilities(
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryRoomVersionCapabilities implements api.RoomserverInternalAPI
|
// QueryRoomVersionCapabilities implements api.RoomserverInternalAPI
|
||||||
func (r *RoomserverInternalAPI) QueryRoomVersionForRoom(
|
func (r *Queryer) QueryRoomVersionForRoom(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
request *api.QueryRoomVersionForRoomRequest,
|
request *api.QueryRoomVersionForRoomRequest,
|
||||||
response *api.QueryRoomVersionForRoomResponse,
|
response *api.QueryRoomVersionForRoomResponse,
|
||||||
|
@ -522,7 +482,7 @@ func (r *RoomserverInternalAPI) QueryRoomVersionForRoom(
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RoomserverInternalAPI) roomVersion(roomID string) (gomatrixserverlib.RoomVersion, error) {
|
func (r *Queryer) roomVersion(roomID string) (gomatrixserverlib.RoomVersion, error) {
|
||||||
var res api.QueryRoomVersionForRoomResponse
|
var res api.QueryRoomVersionForRoomResponse
|
||||||
err := r.QueryRoomVersionForRoom(context.Background(), &api.QueryRoomVersionForRoomRequest{
|
err := r.QueryRoomVersionForRoom(context.Background(), &api.QueryRoomVersionForRoomRequest{
|
||||||
RoomID: roomID,
|
RoomID: roomID,
|
||||||
|
@ -530,7 +490,7 @@ func (r *RoomserverInternalAPI) roomVersion(roomID string) (gomatrixserverlib.Ro
|
||||||
return res.RoomVersion, err
|
return res.RoomVersion, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RoomserverInternalAPI) QueryPublishedRooms(
|
func (r *Queryer) QueryPublishedRooms(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *api.QueryPublishedRoomsRequest,
|
req *api.QueryPublishedRoomsRequest,
|
||||||
res *api.QueryPublishedRoomsResponse,
|
res *api.QueryPublishedRoomsResponse,
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2017 Vector Creations Ltd
|
// Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package internal
|
package query
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
Loading…
Reference in New Issue