Fix keeping the index in sync when subdirectories are moved
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user