Fix keeping the index in sync when subdirectories are moved

This commit is contained in:
André Duffeck
2022-05-10 10:36:40 +02:00
parent c474665753
commit e91318458d
7 changed files with 55 additions and 25 deletions
+3 -3
View File
@@ -157,14 +157,14 @@ func (i *Index) Purge(id *sprovider.ResourceId) error {
return i.bleveIndex.Delete(idToBleveId(id))
}
// Purge removes an entity from the index
func (i *Index) Move(ri *sprovider.ResourceInfo) error {
// Move update the path of an entry and all its children
func (i *Index) Move(ri *sprovider.ResourceInfo, fullPath string) error {
doc, err := i.getEntity(idToBleveId(ri.Id))
if err != nil {
return err
}
oldName := doc.Path
newName := utils.MakeRelativePath(ri.Path)
newName := utils.MakeRelativePath(fullPath)
doc, err = i.updateEntity(idToBleveId(ri.Id), func(doc *indexDocument) {
doc.Path = newName
@@ -45,7 +45,7 @@ var _ = Describe("Index", func() {
}
parentRef = &sprovider.Reference{
ResourceId: rootId,
Path: "./sudbir",
Path: "./my/sudbir",
}
parentRi = &sprovider.ResourceInfo{
Id: &sprovider.ResourceId{
@@ -59,7 +59,7 @@ var _ = Describe("Index", func() {
}
childRef = &sprovider.Reference{
ResourceId: rootId,
Path: "./sudbir/child.pdf",
Path: "./my/sudbir/child.pdf",
}
childRi = &sprovider.ResourceInfo{
Id: &sprovider.ResourceId{
@@ -349,7 +349,7 @@ var _ = Describe("Index", func() {
Expect(err).ToNot(HaveOccurred())
parentRi.Path = "newname"
err = i.Move(parentRi)
err = i.Move(parentRi, "./somewhere/else/newname")
Expect(err).ToNot(HaveOccurred())
assertDocCount(rootId, "subdir", 0)
@@ -365,7 +365,7 @@ var _ = Describe("Index", func() {
})
Expect(err).ToNot(HaveOccurred())
Expect(len(res.Matches)).To(Equal(1))
Expect(res.Matches[0].Entity.Ref.Path).To(Equal("./newname/child.pdf"))
Expect(res.Matches[0].Entity.Ref.Path).To(Equal("./somewhere/else/newname/child.pdf"))
})
})
})
@@ -65,13 +65,13 @@ func (_m *IndexClient) DocCount() (uint64, error) {
return r0, r1
}
// Move provides a mock function with given fields: ri
func (_m *IndexClient) Move(ri *providerv1beta1.ResourceInfo) error {
ret := _m.Called(ri)
// Move provides a mock function with given fields: ri, path
func (_m *IndexClient) Move(ri *providerv1beta1.ResourceInfo, path string) error {
ret := _m.Called(ri, path)
var r0 error
if rf, ok := ret.Get(0).(func(*providerv1beta1.ResourceInfo) error); ok {
r0 = rf(ri)
if rf, ok := ret.Get(0).(func(*providerv1beta1.ResourceInfo, string) error); ok {
r0 = rf(ri, path)
} else {
r0 = ret.Error(0)
}
@@ -6,6 +6,7 @@ import (
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
ctxpkg "github.com/cs3org/reva/v2/pkg/ctx"
"github.com/cs3org/reva/v2/pkg/events"
@@ -59,17 +60,25 @@ func (p *Provider) handleEvent(ev interface{}) {
p.logger.Error().Err(err).Msg("failed to stat the changed resource")
return
}
switch statRes.Status.Code {
case rpc.Code_CODE_OK:
err = p.indexClient.Move(statRes.Info)
if err != nil {
p.logger.Error().Err(err).Msg("failed to restore the changed resource in the index")
}
default:
if statRes.Status.Code != rpc.Code_CODE_OK {
p.logger.Error().Interface("statRes", statRes).Msg("failed to stat the changed resource")
return
}
gpRes, err := p.getPath(statRes.Info.Id, owner)
if err != nil {
p.logger.Error().Err(err).Interface("ref", ref).Msg("failed to get path for moved resource")
return
}
if gpRes.Status.Code != rpcv1beta1.Code_CODE_OK {
p.logger.Error().Interface("status", gpRes.Status).Interface("ref", ref).Msg("failed to get path for moved resource")
return
}
err = p.indexClient.Move(statRes.Info, gpRes.Path)
if err != nil {
p.logger.Error().Err(err).Msg("failed to restore the changed resource in the index")
}
return
case events.ContainerCreated:
ref = e.Ref
@@ -126,3 +135,20 @@ func (p *Provider) statResource(ref *provider.Reference, owner *user.User) (*pro
// Stat changed resource resource
return p.gwClient.Stat(ownerCtx, &provider.StatRequest{Ref: ref})
}
func (p *Provider) getPath(id *provider.ResourceId, owner *user.User) (*provider.GetPathResponse, error) {
// Get auth
ownerCtx := ctxpkg.ContextSetUser(context.Background(), owner)
authRes, err := p.gwClient.Authenticate(ownerCtx, &gateway.AuthenticateRequest{
Type: "machine",
ClientId: "userid:" + owner.Id.OpaqueId,
ClientSecret: p.machineAuthAPIKey,
})
if err != nil || authRes.GetStatus().GetCode() != rpc.Code_CODE_OK {
p.logger.Error().Err(err).Interface("authRes", authRes).Msg("error using machine auth")
}
ownerCtx = metadata.AppendToOutgoingContext(ownerCtx, ctxpkg.TokenHeader, authRes.Token)
// Stat changed resource resource
return p.gwClient.GetPath(ownerCtx, &provider.GetPathRequest{ResourceId: id})
}
@@ -97,7 +97,6 @@ var _ = Describe("Searchprovider", func() {
It("removes an entry from the index when the file has been deleted", func() {
called := false
gwClient.On("Stat", mock.Anything, mock.Anything).Return(&sprovider.StatResponse{
Status: status.NewNotFound(context.Background(), ""),
}, nil)
@@ -153,11 +152,16 @@ var _ = Describe("Searchprovider", func() {
It("indexes items when they are being moved", func() {
called := false
gwClient.On("GetPath", mock.Anything, mock.Anything).Return(&sprovider.GetPathResponse{
Status: status.NewOK(ctx),
Path: "./new/path.pdf",
}, nil)
indexClient.On("Move", mock.MatchedBy(func(riToIndex *sprovider.ResourceInfo) bool {
return riToIndex.Id.OpaqueId == ri.Id.OpaqueId
})).Return(nil).Run(func(args mock.Arguments) {
}), "./new/path.pdf").Return(nil).Run(func(args mock.Arguments) {
called = true
})
ref.Path = "./new/path.pdf"
eventsChan <- events.ItemMoved{
Ref: ref,
Executant: user.Id,
@@ -103,11 +103,11 @@ func (p *Provider) Search(ctx context.Context, req *searchsvc.SearchRequest) (*s
ResourceId: space.Root,
})
if err != nil {
p.logger.Error().Err(err).Str("space", space.Id.OpaqueId).Msg("failed to get patch for grant space root")
p.logger.Error().Err(err).Str("space", space.Id.OpaqueId).Msg("failed to get path for grant space root")
continue
}
if gpRes.Status.Code != rpcv1beta1.Code_CODE_OK {
p.logger.Error().Interface("status", gpRes.Status).Str("space", space.Id.OpaqueId).Msg("failed to get patch for grant space root")
p.logger.Error().Interface("status", gpRes.Status).Str("space", space.Id.OpaqueId).Msg("failed to get path for grant space root")
continue
}
mountpointPrefix = utils.MakeRelativePath(gpRes.Path)
+1 -1
View File
@@ -38,7 +38,7 @@ type ProviderClient interface {
type IndexClient interface {
Search(ctx context.Context, req *searchsvc.SearchIndexRequest) (*searchsvc.SearchIndexResponse, error)
Add(ref *providerv1beta1.Reference, ri *providerv1beta1.ResourceInfo) error
Move(ri *providerv1beta1.ResourceInfo) error
Move(ri *providerv1beta1.ResourceInfo, path string) error
Delete(ri *providerv1beta1.ResourceId) error
Restore(ri *providerv1beta1.ResourceId) error
Purge(ri *providerv1beta1.ResourceId) error