Skip to content

Commit

Permalink
HPCC-31213 Add plane name to MoveExternalFile
Browse files Browse the repository at this point in the history
The STD.File.MoveExternalFile moves files from one
landing zone folder to anothor. The existing method
can only specify a landing zone using host name. In
this PR, a landing zone can be specified by plane
name.

Signed-off-by: wangkx <[email protected]>
  • Loading branch information
wangkx committed Feb 2, 2024
1 parent b40ec6c commit 4c90087
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 20 deletions.
5 changes: 3 additions & 2 deletions ecllibrary/std/File.ecl
Original file line number Diff line number Diff line change
Expand Up @@ -358,9 +358,10 @@ EXPORT RfsAction(varstring server, varstring query) :=
* @param location The IP address of the remote machine.
* @param frompath The path/name of the file to move.
* @param topath The path/name of the target file.
* @param planename The name of the data plane containing the file.
*/
EXPORT MoveExternalFile(varstring location, varstring frompath, varstring topath) :=
lib_fileservices.FileServices.MoveExternalFile(location, frompath, topath);
EXPORT MoveExternalFile(varstring location, varstring frompath, varstring topath, varstring planename) :=
lib_fileservices.FileServices.MoveExternalFile(location, frompath, topath, planename);

/**
* Removes a single physical file from a remote machine. The
Expand Down
88 changes: 71 additions & 17 deletions plugins/fileservices/fileservices.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2726,15 +2726,19 @@ FILESERVICES_API char * FILESERVICES_CALL fsfResolveHostName(const char *hostna
return ret.detach();
}

static void checkExternalFileRights(ICodeContext *ctx, CDfsLogicalFileName &lfn, bool rd,bool wr)
static void checkExternalFileRights(ICodeContext *ctx,CDfsLogicalFileName &lfn,bool checkScopePermissions,bool rd,bool wr)
{
Linked<IUserDescriptor> udesc = ctx->queryUserDescriptor();
unsigned auditflags = 0;
if (rd)
auditflags |= (DALI_LDAP_AUDIT_REPORT|DALI_LDAP_READ_WANTED);
if (wr)
auditflags |= (DALI_LDAP_AUDIT_REPORT|DALI_LDAP_WRITE_WANTED);
SecAccessFlags perm = queryDistributedFileDirectory().getFilePermissions(lfn.get(),udesc,auditflags);
SecAccessFlags perm = SecAccess_Unavailable;
if (!checkScopePermissions)
perm = queryDistributedFileDirectory().getFilePermissions(lfn.get(),udesc,auditflags);
else
perm = queryDistributedFileDirectory().getFScopePermissions(lfn.get(),udesc,auditflags);
if (wr) {
if (!HASWRITEPERMISSION(perm)) {
throw MakeStringException(-1,"Write permission denied for %s", lfn.get());
Expand All @@ -2747,21 +2751,60 @@ static void checkExternalFileRights(ICodeContext *ctx, CDfsLogicalFileName &lfn,
}
}

FILESERVICES_API void FILESERVICES_CALL fsMoveExternalFile(ICodeContext * ctx,const char *location,const char *frompath,const char *topath)
static void checkExternalFilePath(ICodeContext *ctx,IPropertyTree *plane,const char *host,
const char *path,bool checkScopePermissionIfDir,bool rd,bool wr,RemoteFilename &rfn)
{
SocketEndpoint ep(location);
if (containsRelPaths(path)) //Detect a path like: a/../../../f
throw makeStringExceptionV(-1,"Invalid file path %s",path);

CDfsLogicalFileName dlfn;
if (plane)
{
//allow relative path if a plane name is specified.
if (isAbsolutePath(path))
{
const char *relativePath = getRelativePath(path,plane->queryProp("@prefix"));
if (nullptr == relativePath)
throw makeStringExceptionV(-1,"Invalid plane path %s.",path);
path = relativePath;
}
dlfn.setPlaneExternal(plane->queryProp("@name"),path);
}
else
dlfn.setExternal(host,path); //for backward compatibility
dlfn.getExternalFilename(rfn);

if (checkScopePermissionIfDir)
{
Owned<IFile> f = createIFile(rfn);
checkScopePermissionIfDir = f->isDirectory()==fileBool::foundYes;
}
checkExternalFileRights(ctx,dlfn,checkScopePermissionIfDir,rd,wr);
}

static IPropertyTree *checkPlaneOrHost(const char *planeName,const char *host)
{
if (!isEmptyString(planeName))
{
Owned<IPropertyTree> plane = getDropZonePlane(planeName); //Only support DropZone for now.
if (!plane)
throw makeStringExceptionV(-1,"DropZone %s not found.",planeName);
return plane.getClear();
}
SocketEndpoint ep(host);
if (ep.isNull())
throw MakeStringException(-1,"fsMoveExternalFile: Cannot resolve location %s",location);
CDfsLogicalFileName from;
from.setExternal(location,frompath);
CDfsLogicalFileName to;
to.setExternal(location,topath);
checkExternalFileRights(ctx,from,true,true);
checkExternalFileRights(ctx,to,false,true);
RemoteFilename fromrfn;
fromrfn.setPath(ep,frompath);
RemoteFilename torfn;
torfn.setPath(ep,topath);
throw makeStringExceptionV(-1,"Cannot resolve host %s",host);
return nullptr;
}

static void implementMoveExternalFile(ICodeContext *ctx,const char *location,
const char *frompath,const char *topath,const char *planename)
{
Owned<IPropertyTree> plane = checkPlaneOrHost(planename,location);
RemoteFilename fromrfn,torfn;
checkExternalFilePath(ctx,plane,location,frompath,true,true,true,fromrfn);
checkExternalFilePath(ctx,plane,location,topath,false,false,true,torfn);

Owned<IFile> fileto = createIFile(torfn);
if (fileto->exists())
throw MakeStringException(-1,"fsMoveExternalFile: Destination %s already exists", topath);
Expand All @@ -2774,14 +2817,25 @@ FILESERVICES_API void FILESERVICES_CALL fsMoveExternalFile(ICodeContext * ctx,c
AuditMessage(ctx,"MoveExternalFile",frompath,topath);
}

FILESERVICES_API void FILESERVICES_CALL fsMoveExternalFile(ICodeContext *ctx,const char *location,const char *frompath,const char *topath)
{
implementMoveExternalFile(ctx,location,frompath,topath,nullptr);
}

FILESERVICES_API void FILESERVICES_CALL fsMoveExternalFile_v2(ICodeContext *ctx,const char *location,
const char *frompath,const char *topath,const char *planename)
{
implementMoveExternalFile(ctx,location,frompath,topath,planename);
}

FILESERVICES_API void FILESERVICES_CALL fsDeleteExternalFile(ICodeContext * ctx,const char *location,const char *path)
{
SocketEndpoint ep(location);
if (ep.isNull())
throw MakeStringException(-1,"fsDeleteExternalFile: Cannot resolve location %s",location);
CDfsLogicalFileName lfn;
lfn.setExternal(location,path);
checkExternalFileRights(ctx,lfn,false,true);
checkExternalFileRights(ctx,lfn,false,false,true); //The path could be a directory. So, it may need to be checked as a scope. Will re-visit this when adding plane name here.
RemoteFilename rfn;
rfn.setPath(ep,path);
Owned<IFile> file = createIFile(rfn);
Expand All @@ -2805,7 +2859,7 @@ FILESERVICES_API void FILESERVICES_CALL fsCreateExternalDirectory(ICodeContext
if (isPathSepChar(path.charAt(path.length()-1)))
path.remove(path.length()-1, 1);
lfn.setExternal(location,path);
checkExternalFileRights(ctx,lfn,false,true);
checkExternalFileRights(ctx,lfn,false,false,true);
RemoteFilename rfn;
rfn.setPath(ep,path);
Owned<IFile> file = createIFile(rfn);
Expand Down
1 change: 1 addition & 0 deletions plugins/fileservices/fileservices.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ FILESERVICES_API void FILESERVICES_CALL fsRfsAction(const char *server, const ch
FILESERVICES_API char * FILESERVICES_CALL fsfGetHostName(const char *ipaddress);
FILESERVICES_API char * FILESERVICES_CALL fsfResolveHostName(const char *hostname);
FILESERVICES_API void FILESERVICES_CALL fsMoveExternalFile(ICodeContext * ctx,const char *location,const char *frompath,const char *topath);
FILESERVICES_API void FILESERVICES_CALL fsMoveExternalFile_v2(ICodeContext *ctx,const char *location,const char *frompath,const char *topath,const char *planename);
FILESERVICES_API void FILESERVICES_CALL fsDeleteExternalFile(ICodeContext * ctx,const char *location,const char *path);
FILESERVICES_API void FILESERVICES_CALL fsCreateExternalDirectory(ICodeContext * ctx,const char *location,const char *path);
FILESERVICES_API char * FILESERVICES_CALL fsfGetLogicalFileAttribute(ICodeContext * ctx,const char *lfn,const char *attrname);
Expand Down
2 changes: 1 addition & 1 deletion plugins/proxies/lib_fileservices.ecllib
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export FileServices := SERVICE : plugin('fileservices'), time
RfsAction( const varstring server, const varstring query): c,entrypoint='fsRfsAction';
varstring GetHostName( const varstring ipaddress ): c,entrypoint='fsfGetHostName';
varstring ResolveHostName( const varstring hostname ): c,entrypoint='fsfResolveHostName';
MoveExternalFile(const varstring location, const varstring frompath, const varstring topath): c,action,context,entrypoint='fsMoveExternalFile';
MoveExternalFile(const varstring location, const varstring frompath, const varstring topath, const varstring planename=''): c,action,context,entrypoint='fsMoveExternalFile_v2';
DeleteExternalFile(const varstring location, const varstring path): c,action,context,entrypoint='fsDeleteExternalFile';
CreateExternalDirectory(const varstring location, const varstring path): c,action,context,entrypoint='fsCreateExternalDirectory';
varstring GetLogicalFileAttribute(const varstring lfn,const varstring attrname) : c,context,entrypoint='fsfGetLogicalFileAttribute';
Expand Down

0 comments on commit 4c90087

Please sign in to comment.