Skip to content

Commit 49a7bc7

Browse files
committed
Optional support of WebDAV depth=infinity, bug fixes when adding files and in error propagation
1 parent 36d4f1c commit 49a7bc7

File tree

11 files changed

+110
-54
lines changed

11 files changed

+110
-54
lines changed

src/firefly/java/edu/caltech/ipac/firefly/data/WspaceMeta.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818
public class WspaceMeta implements Serializable {
1919

20+
2021
public static final String SEARCH_DIR = "searches";
2122
public static final String STAGING_DIR = "staging";
2223
public static final String CATALOGS = "catalogs";
@@ -40,12 +41,12 @@ public boolean isFile() {
4041
}
4142

4243
public enum Includes {
43-
NONE(false, 0), NONE_PROPS(true, 0), CHILDREN(false, 1), CHILDREN_PROPS(true, 1), ALL(false), ALL_PROPS(true, 1);
44-
public boolean inclProps = false;
45-
public int depth = 0;
44+
NONE(false, 0), NONE_PROPS(true, 0), CHILDREN(false, 1), CHILDREN_PROPS(true, 1), ALL(false), ALL_PROPS(true);
45+
public boolean inclProps = false; // include properties
46+
public int depth = 0; // desired depth, can be 0, 1, or Integer.MAX_VALUE for infinity (which might not be supported by WS server)
4647

4748
Includes(boolean b) {
48-
this(b, 1);
49+
this(b, Integer.MAX_VALUE);
4950
}
5051

5152
Includes(boolean b, int d) {

src/firefly/java/edu/caltech/ipac/firefly/server/LocalFSWorkspace.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public String getProp(PROPS prop) {
6464
if (propFound.equals(PROPS.ROOT_URL)) {
6565
propVal = WS_HOST_URL;
6666
} else if (propFound.equals(PROPS.ROOT_DIR)) {
67-
propVal = WS_ROOT_DIR;
67+
propVal = getWsHome();
6868
} else if (propFound.equals(PROPS.AUTH)) {
6969
propVal = "NONE";
7070
} else if (propFound.equals(PROPS.PROTOCOL)) {

src/firefly/java/edu/caltech/ipac/firefly/server/WebDAVWorkspaceManager.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ public String getProp(PROPS prop) {
5656
}
5757
if (propFound.equals(PROPS.ROOT_URL)) {
5858
propVal = WS_HOST_URL;
59-
// } else if (propFound.equals(PROPS.ROOT_DIR)) {
60-
// propVal = WS_ROOT_DIR;
59+
} else if (propFound.equals(PROPS.ROOT_DIR)) {
60+
propVal = getWsHome();
6161
} else if (propFound.equals(PROPS.AUTH)) {
6262
propVal = this.partition.name();
6363
} else if (propFound.equals(PROPS.PROTOCOL)) {
@@ -221,7 +221,11 @@ private static void simpleTest(WebDAVWorkspaceManager man) {
221221
man.setMeta(meta);
222222
man.setMeta(ufilePath, "added_by", man.userHome);
223223

224-
WspaceMeta meta2 = man.getMeta("/", WspaceMeta.Includes.ALL_PROPS);
225-
System.out.println(meta2.getNodesAsString());
224+
try {
225+
WspaceMeta meta2 = man.getMeta("/", WspaceMeta.Includes.ALL_PROPS);
226+
System.out.println(meta2.getNodesAsString());
227+
} catch (Exception e) {
228+
e.printStackTrace(System.err);
229+
}
226230
}
227231
}

src/firefly/java/edu/caltech/ipac/firefly/server/WebDAVWorkspaceManagerBase.java

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import org.apache.jackrabbit.webdav.xml.Namespace;
2424

2525
import java.io.*;
26-
import java.net.MalformedURLException;
2726
import java.net.URI;
2827
import java.net.URISyntaxException;
2928
import java.net.URLDecoder;
@@ -39,6 +38,7 @@
3938
public abstract class WebDAVWorkspaceManagerBase implements WorkspaceManager {
4039

4140
protected static String WS_HOST_URL = AppProperties.getProperty("workspace.host.url", "https://irsa.ipac.caltech.edu");
41+
private static boolean INFINITY_DEPTH_SUPPORTED = AppProperties.getBooleanProperty("workspace.propfind.infinity", true);
4242

4343
private static final Logger.LoggerImpl LOG = Logger.getLogger();
4444

@@ -100,7 +100,7 @@ private Namespace getNamespace() {
100100

101101

102102

103-
boolean exists(String relRemoteUri) {
103+
boolean exists(String relRemoteUri) throws WsException {
104104
return getMeta(relRemoteUri, WspaceMeta.Includes.NONE) != null;
105105
}
106106

@@ -169,8 +169,8 @@ public WsResponse davPut(File upload, String relPath, boolean overwrite, String
169169
return WsUtil.success(put.getStatusCode(), put.getStatusText(), newUrl);
170170
} catch (Exception e) {
171171
LOG.error(e, "Error while uploading file:" + upload.getPath());
172+
return WsUtil.error(500, "Error while uploading file:" + upload.getPath());
172173
}
173-
return WsUtil.error(500);
174174
}
175175

176176
private WsResponse davGet(File outfile, String fromPath) {
@@ -207,7 +207,7 @@ public PROTOCOL getProtocol() {
207207
}
208208

209209
@Override
210-
public WsResponse getList(String parentUri, int depth) {
210+
public WsResponse getList(String parentUri, int depth) throws WsException {
211211

212212
WspaceMeta.Includes prop = WspaceMeta.Includes.CHILDREN_PROPS;
213213

@@ -284,12 +284,13 @@ public WsResponse delete(String uri) {
284284
}
285285
} catch (Exception e) {
286286
LOG.error(e, "Error while deleting remote file:" + url);
287+
return WsUtil.error(e);
287288
}
288289
return WsUtil.success(200, "Deleted " + uri, uri);
289290
}
290291

291292
@Override
292-
public WsResponse createParent(String newRelPath) {
293+
public WsResponse createParent(String newRelPath) throws WsException {
293294
String[] parts = newRelPath.split("/");
294295
String cdir = "/";
295296
for (String s : parts) {
@@ -305,15 +306,15 @@ public WsResponse createParent(String newRelPath) {
305306
LOG.error("Unable to create directory:" + newRelPath + " -- " + mkcol.getStatusText());
306307
return WsUtil.error(mkcol, "Resource already exist");
307308
}
308-
} catch (URISyntaxException|MalformedURLException e) {
309+
} catch (URISyntaxException|IOException e) {
309310
return WsUtil.error(e);
310311
}
311312
}
312313
}
313314
return WsUtil.success(200, "Created", getResourceUrl(newRelPath));
314315
}
315316

316-
public WsResponse moveFile(String originalFileRelPath, String newPath, boolean overwrite) {
317+
public WsResponse moveFile(String originalFileRelPath, String newPath, boolean overwrite) throws WsException {
317318
WspaceMeta meta = new WspaceMeta(newPath);
318319
String parent = meta.getParentPath();
319320

@@ -326,14 +327,14 @@ public WsResponse moveFile(String originalFileRelPath, String newPath, boolean o
326327
MoveMethod move = new MoveMethod(getResourceUrl(originalFileRelPath), newUrl, overwrite);
327328
if (!executeMethod(move)) {
328329
// handle error
329-
LOG.error("Unable to move:" + originalFileRelPath + " based on url -- " +newUrl+" -- "+ move.getStatusText());
330+
LOG.error("Unable to move:" + originalFileRelPath + " based on url -- " + newUrl + " -- " + move.getStatusText());
330331
return WsUtil.error(move.getStatusCode(), move.getStatusLine().getReasonPhrase());
331332
}
332333
return WsUtil.success(move.getStatusCode(), move.getStatusText(), newUrl);
333334
}
334335

335336
@Override
336-
public WsResponse renameFile(String originalFileRelPath, String newfileName, boolean overwrite) {
337+
public WsResponse renameFile(String originalFileRelPath, String newfileName, boolean overwrite) throws WsException {
337338
WspaceMeta meta = new WspaceMeta(originalFileRelPath);
338339
String parent = meta.getParentPath();
339340

@@ -354,19 +355,20 @@ public WsResponse renameFile(String originalFileRelPath, String newfileName, boo
354355
return WsUtil.success(move.getStatusCode(), move.getStatusText(), newUrl);
355356
}
356357

357-
public WspaceMeta getMeta(String relPath) {
358-
return getMeta(relPath, WspaceMeta.Includes.ALL);
359-
}
358+
// public WspaceMeta getMeta(String relPath) {
359+
// return getMeta(relPath, WspaceMeta.Includes.ALL);
360+
// }
360361

361-
public WspaceMeta getMeta(String relPath, WspaceMeta.Includes includes) {
362+
public WspaceMeta getMeta(String relPath, WspaceMeta.Includes includes) throws WsException {
362363

363364
// this can be optimized by retrieving only the props we care for.
364365
DavMethod pFind = null;
365366
try {
367+
int depth = getDepth(includes);
366368
if (includes.inclProps) {
367-
pFind = new PropFindMethod(getResourceUrl(relPath), DavConstants.PROPFIND_ALL_PROP, includes.depth);
369+
pFind = new PropFindMethod(getResourceUrl(relPath), DavConstants.PROPFIND_ALL_PROP, depth);
368370
} else {
369-
pFind = new PropFindMethod(getResourceUrl(relPath), DavConstants.PROPFIND_BY_PROPERTY, includes.depth);
371+
pFind = new PropFindMethod(getResourceUrl(relPath), DavConstants.PROPFIND_BY_PROPERTY, depth);
370372
}
371373

372374
if (!executeMethod(pFind, false)) {
@@ -394,12 +396,16 @@ public WspaceMeta getMeta(String relPath, WspaceMeta.Includes includes) {
394396
return root;
395397
} catch (Exception e) {
396398
LOG.error(e, "Error while getting meta for:" + relPath);
399+
if (e instanceof WsException) {
400+
throw (WsException)e;
401+
} else {
402+
throw new WsException(e.getMessage(), e);
403+
}
397404
} finally {
398405
if (pFind != null) {
399406
pFind.releaseConnection();
400407
}
401408
}
402-
return null;
403409
}
404410

405411

@@ -488,7 +494,7 @@ private WspaceMeta convertToWspaceMeta(WspaceMeta meta, MultiStatusResponse res)
488494
} else if (name.equals(DavConstants.PROPERTY_GETCONTENTLENGTH)) {
489495
long size = Long.parseLong(v);
490496
meta.setSize(size);
491-
//meta.setIsFile(true); // WEBDAV/IRSA only set content length for files. // not WEBDav standard behaviour
497+
//meta.setIsFile(true); // not WEBDav standard behaviour, in WEBDAV/IRSA only files have content length
492498
} else if (name.equals(DavConstants.PROPERTY_GETCONTENTTYPE)) {
493499
meta.setContentType(v);
494500
} else if (p.getName().getNamespace().equals(namespace)) {
@@ -513,16 +519,16 @@ private void addToRoot(WspaceMeta root, MultiStatusResponse res) throws Unsuppor
513519
root.addChild(meta);
514520
}
515521
}
516-
boolean executeMethod(DavMethod method) {
522+
boolean executeMethod(DavMethod method) throws WsException {
517523
return executeMethod(method, true);
518524
}
519525

520-
private boolean executeMethod(DavMethod method, boolean releaseConnection) {
526+
private boolean executeMethod(DavMethod method, boolean releaseConnection) throws WsException {
521527
try {
522528
HttpServices.Status status = doExecuteMethod(method);
523529
return !status.isError();
524530
} catch (IOException e) {
525-
return false;
531+
throw new WsException(e.getMessage(), e);
526532
} finally {
527533
if (releaseConnection && method != null) {
528534
method.releaseConnection();
@@ -539,7 +545,7 @@ protected HttpServices.Status doExecuteMethod(DavMethod method) throws IOExcepti
539545
private WsResponse getResponse(String relPath){
540546
DavMethod pFind = null;
541547
try {
542-
pFind = new PropFindMethod(getResourceUrl(relPath), DavConstants.PROPFIND_BY_PROPERTY, WspaceMeta.Includes.ALL_PROPS.depth);
548+
pFind = new PropFindMethod(getResourceUrl(relPath), DavConstants.PROPFIND_BY_PROPERTY, getDepth(WspaceMeta.Includes.ALL_PROPS));
543549

544550

545551
if (!executeMethod(pFind, false)) {
@@ -552,12 +558,21 @@ private WsResponse getResponse(String relPath){
552558
return WsUtil.success(pFind.getStatusCode(), pFind.getStatusText(), pFind.getPath());
553559
} catch (Exception e) {
554560
LOG.error(e, "Error while getting meta for:" + relPath);
561+
return WsUtil.error(500, "Error while getting meta for:" + relPath);
555562
} finally {
556563
if (pFind != null) {
557564
pFind.releaseConnection();
558565
}
559566
}
560-
return new WsResponse();
567+
}
568+
569+
/**
570+
* Return allowed depth
571+
* @param includes
572+
* @return
573+
*/
574+
private int getDepth(WspaceMeta.Includes includes) {
575+
return includes.depth > 1 && !INFINITY_DEPTH_SUPPORTED ? 1: includes.depth;
561576
}
562577

563578
class WebDAVGetMethod extends DavMethodBase {

src/firefly/java/edu/caltech/ipac/firefly/server/rpc/UserServicesImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import edu.caltech.ipac.firefly.server.persistence.PreferencesDao;
1818
import edu.caltech.ipac.firefly.server.servlets.AnyFileDownload;
1919
import edu.caltech.ipac.firefly.server.util.StopWatch;
20+
import edu.caltech.ipac.firefly.server.ws.WsException;
2021
import edu.caltech.ipac.util.AppProperties;
2122
import edu.caltech.ipac.util.FileUtil;
2223
import edu.caltech.ipac.util.cache.Cache;
@@ -294,7 +295,7 @@ public List<Alert> getAlerts() throws RPCException {
294295
return new ArrayList<Alert>(alerts.values());
295296
}
296297

297-
public WspaceMeta getMeta(String relPath, WspaceMeta.Includes includes) {
298+
public WspaceMeta getMeta(String relPath, WspaceMeta.Includes includes) throws WsException {
298299
return ServerContext.getRequestOwner().getWsManager().getMeta(relPath, includes);
299300
}
300301

src/firefly/java/edu/caltech/ipac/firefly/server/security/JOSSOAdapter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ public void clearAuthInfo() {
277277
Cookie c = new Cookie(AUTH_KEY, "");
278278
c.setMaxAge(0);
279279
c.setValue(TO_BE_DELETE);
280-
c.setDomain(".ipac.caltech.edu");
280+
c.setDomain("ipac.caltech.edu");
281281
c.setPath("/");
282282
ServerContext.getRequestOwner().getRequestAgent().sendCookie(c);
283283
}

src/firefly/java/edu/caltech/ipac/firefly/server/ws/Workspaces.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public interface Workspaces {
9696
WsResponse moveFile(String originalFileRelPath, String newfilepath, boolean shouldOverwrite) throws WsException;
9797

9898

99-
WspaceMeta getMeta(String uri, WspaceMeta.Includes includes);
99+
WspaceMeta getMeta(String uri, WspaceMeta.Includes includes) throws WsException;
100100

101101
boolean setMeta(WspaceMeta... metas);
102102
}

src/firefly/java/edu/caltech/ipac/firefly/server/ws/WsException.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
* Created by ejoliet on 6/19/17.
77
*/
88
public class WsException extends IOException {
9-
public WsException(String s) {
10-
super(s);
9+
public WsException(String message) {
10+
super(message);
1111
}
12+
public WsException(String message, Throwable cause) {super(message, cause);}
1213
}

src/firefly/java/edu/caltech/ipac/firefly/server/ws/WsServerUtils.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,9 @@ public WsResponse move(WsServerParams wsParams) throws IOException {
112112
* @param wsParams see {@link edu.caltech.ipac.firefly.server.ws.WsServerParams}
113113
* @param level see {@link WspaceMeta.Includes}
114114
* @return list of metadata
115+
* @throws WsException on error
115116
*/
116-
public List<WspaceMeta> getMeta(WsServerParams wsParams, WspaceMeta.Includes level) {
117+
public List<WspaceMeta> getMeta(WsServerParams wsParams, WspaceMeta.Includes level) throws IOException {
117118
WorkspaceManager wsm = getWsManager(wsParams);
118119

119120
WspaceMeta meta = wsm.getMeta(wsParams.getRelPath(), level);
@@ -126,7 +127,7 @@ public List<WspaceMeta> getMeta(WsServerParams wsParams, WspaceMeta.Includes lev
126127
* @param wsParams parameters
127128
* @return see {@link WspaceMeta}
128129
*/
129-
public WspaceMeta getMeta(WsServerParams wsParams) {
130+
public WspaceMeta getMeta(WsServerParams wsParams) throws IOException {
130131
WorkspaceManager wsm = getWsManager(wsParams);
131132

132133
WspaceMeta meta = wsm.getMeta(wsParams.getRelPath(), WspaceMeta.Includes.ALL);

src/firefly/js/ui/WorkspaceViewer.jsx

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import {dispatchWorkspaceCreatePath,
1111
dispatchWorkspaceUpdate,
1212
getWorkspaceErrorMsg,
1313
getWorkspaceList, getFolderUnderLevel,
14-
getWorkspacePath, isWsFolder, WS_SERVER_PARAM, WS_HOME, WORKSPACE_LIST_UPDATE} from '../visualize/WorkspaceCntlr.js';
14+
getWorkspacePath, isAccessWorkspace, isWsFolder,
15+
WS_SERVER_PARAM, WS_HOME, WORKSPACE_IN_LOADING, WORKSPACE_LIST_UPDATE} from '../visualize/WorkspaceCntlr.js';
1516
import {CompleteButton} from './CompleteButton.jsx';
1617
import {dispatchShowDialog, dispatchHideDialog, isDialogVisible} from '../core/ComponentCntlr.js';
1718
import {PopupPanel} from './PopupPanel.jsx';
@@ -113,8 +114,10 @@ export const WorkspaceViewField = memo( (props) => {
113114
}
114115
};
115116

116-
return (<WorkspaceView {...{...viewProps, selectedItem: viewProps.value}}
117-
onClickItem={onClickItem}/>); // get key from FilePicker
117+
return (
118+
<WorkspaceView {...{...viewProps, selectedItem: viewProps.value}}
119+
onClickItem={onClickItem}/>
120+
);
118121
});
119122

120123

@@ -176,7 +179,7 @@ WorkspacePickerPopup.propTypes = {
176179
export function showWorkspaceDialog({onComplete, value, fieldKey}) {
177180
dispatchAddActionWatcher({
178181
id: 'workspaceRead',
179-
actions:[WORKSPACE_LIST_UPDATE, ComponentCntlr.HIDE_DIALOG],
182+
actions:[WORKSPACE_IN_LOADING, WORKSPACE_LIST_UPDATE, ComponentCntlr.HIDE_DIALOG],
180183
callback: (a , cancelSelf) => {
181184
switch (a.type) {
182185
case ComponentCntlr.HIDE_DIALOG:
@@ -185,6 +188,10 @@ export function showWorkspaceDialog({onComplete, value, fieldKey}) {
185188
cancelSelf();
186189
}
187190
break;
191+
case WORKSPACE_IN_LOADING:
192+
if (!isDialogVisible(workspacePopupId)) return;
193+
showWorkspaceAsPopup({onComplete, value, fieldKey});
194+
break;
188195
case WORKSPACE_LIST_UPDATE:
189196
const newList = getWorkspaceList() || [];
190197
if (isEmpty(newList)) {
@@ -412,8 +419,8 @@ export function workspacePopupMsg(msg, title) {
412419
*/
413420
function showWorkspaceAsPopup({onComplete, value, fieldKey=workspaceUploadDef.file.fkey}) {
414421
const newList = getWorkspaceList() || [];
415-
const dialogWidth = 500;
416-
const dialogHeight = 350;
422+
const dialogWidth = 650;
423+
const dialogHeight = 400;
417424
const popupPanelResizableStyle = {
418425
width: dialogWidth,
419426
height: dialogHeight,
@@ -436,17 +443,19 @@ function showWorkspaceAsPopup({onComplete, value, fieldKey=workspaceUploadDef.fi
436443
};
437444

438445
const startWorkspaceReadPopup = () => {
446+
const showMask = isAccessWorkspace();
439447
const popup = (
440448
<PopupPanel title={'Read file from workspace'}>
441449
<div style={popupPanelResizableStyle}>
442-
<FieldGroup style={{height: 'calc(100% - 80px)', width: '100%'}}
450+
<FieldGroup style={{height: 'calc(100% - 80px)', width: '100%', position: 'relative'}}
443451
groupKey={workspacePopupGroup} keepState={true}>
444452
<div style={style}>
445453
<WorkspaceViewField fieldKey={fieldKey}
446454
files={newList}
447455
keepSelect={true}
448456
initialState={{value, validator: isWsFolder(false)}}/>
449457
</div>
458+
{showMask && <div className='loading-mask' style={Object.assign({}, style, {top:0, marginTop: 0})}/>}
450459
</FieldGroup>
451460

452461
<div style={{display: 'flex', justifyContent: 'space-between',

0 commit comments

Comments
 (0)