Howto use our WebDAV Storages
1. Introduction: WebDAV
WebDAV (Web Distributed Authoring and Versioning) is an extension to the HTTP Protocol and allows users to collaboratively edit documents directly on a web server. We use the provided WebDAV storages for storing data files from within applications. More information about WebDAV can be found
here.
2. Introduction: the two WebDAV Storages Clipboard and OpStore
For persisting files that can be easily accessed and modified by everyone, two WebDAV storages are provided by the Controls Infrastructure Group: the temporary
"WebDAV Clipboard" and the permanent
"WebDAV OpStore". It is recommended to discuss usage scenarios with APP to decide, which of them fits best to the use case. Roughly the usage scenarios are as follows:
- Clipboard: should be used in most cases, will be wiped e.g. after a beamtime
- OpStore: used in specific cases in agreement with Operations, used e.g. for long-term storage of measurement data
3.1 Access to WebDAV from Linux
On the development cluster asl75x, you can easily use the file manager thunar (available from the menu: Applications -> File Manager). To navigate to a WebDAV directory, just copy one of the following lines to the address bar:
davs://clipboard.acc.gsi.de/dav/
davs://websvcpro.acc.gsi.de/public/opstore/
Once you open a WebDAV location in thunar, you see on the left side under "Network" and can easily bookmark / create a shortcut for both WebDAVs.
3.2 Access to WebDAV from Windows
?
3.3 Read-only access to WebDAV from everywhere
The simplest way of just viewing the contents of your WebDAV folder is just by using a Browser, e.g. Firefox. To access a WebDAV link, the URLs shown in 3.1. need to be modified to start with
https:// instead of davs:
E.g. type the following adress into your browser's navigation bar:
https://clipboard.acc.gsi.de/dav
4. How to use the WebDAV storages programmatically
4.1 Programmatic upload and download of a file
Simple up- and download
The simplest way of creating a folder and uploading and downloading a file looks as follows:
String testfolder = WebDavHelper.WebDavStorageLocation.OPSTORE.getPath() + "test/";
String filename = "testfile" + System.currentTimeMillis() + ".txt";
// create folder
System.out.println("*** Creating folder " + testfolder);
final ResourceItem folder = ResourceItemUtils.newResourceItem(ResourceType.WEBDAV, testfolder);
System.out.println("Creating folder successful? " + ResourceItemUtils.exists(folder) + "\n");
// create file
System.out.println("*** Creating file " + filename);
ResourceItem file = ResourceItemUtils.createFile(folder, filename);
System.out.println("Creating file successful? " + ResourceItemUtils.exists(file) + "\n");
System.out.println("*** Writing to file " + filename);
ResourceItemUtils.writeLinesToFile(file, List.of("Hello", "World"));
System.out.println("Writing to file successful? " + ((ResourceItemUtils.getSize(file) > 0) ? "y" : "n") + "\n");
// try to read the file
System.out.println("*** File contents: ");
List<String> contents = ResourceItemUtils.readLinesFromFile(file);
contents.forEach(s -> System.out.println(s));
Convenience methods: automatic creation of the folder structure
In addition, we provide some convenience methods for you.
If a file shall be created by a given URI using
ResourceItemUtils.createFile, all the missing folder structure in between will be automatically created for you. E.g.
ResourceItemUtils.createFile(ResourceItemUtils.newResourceItem(ResourceType.WEBDAV, WebDavHelper.WebDavStorageLocation.CLIPBOARD.getPath() + "DeviceAutomator/config/test.json"));
would create the folders
DeviceAutomator /config/ if they would not exist before.
Convenience methods: generated filenames
For automatic generation of filenames containing e.g. the timestamp or the hostname, we provide some convenience methods. Check out the
ResourceItemUtils.createDefaultSubPathAndFilename or
ResourceItemUtils.createSubPathAndFilename methods.
final String uriAsString = WebDavHelper.WebDavStorageLocation.CLIPBOARD.getPath() + ResourceItemUtils
.createDefaultSubPathAndFilename(applicationTitle, categoryDirectory, "", fileNameAndExtension);
final ResourceItem file = ResourceItemUtils.newResourceItem(ResourceType.WEBDAV, uriAsString);
return ResourceItemUtils.createFile(file, data);
Convenience methods: providing the file content while creating the file
All methods for creating a file are also provided in a version that directly gets the List
or byte[] to be written to the file. Thus the following code lines
String filename = WebDavHelper.WebDavStorageLocation.CLIPBOARD.getPath() + "/myapp/test.txt";
final ResourceItem file = ResourceItemUtils.newResourceItem(ResourceType.WEBDAV, filename);
ResourceItemUtils.createFile(file);
ResourceItemUtils.writeLinesToFile(file, List.of("Hello", "World"));
can be written simpler
ResourceItemUtils.createFile(file, List.of("Hello", "World"));
(similarly with byte[]).
4.2 Programmatic upload of an image
For uploading images, we provide a special utility class ScreenShotUtils in common-uilib-fx, that does convert a given Image to the necessary byte[] array and uploads a file for you.
final ResourceItem uploadedFile = ScreenShotUtils.convertAndUploadImageAndOpenInBrowser(
WebDavStorageLocation.CLIPBOARD,
applicationName, "screenshots", true,
getWellFormedFileName(FILE_NAME_FRAGMENT_SEPARATOR) + FILE_NAME_FRAGMENT_SEPARATOR, true,
PNG_SUFFIX, null, screenShotImage);
LOGGER.info(ScreenShotButtonResourceBundle.LANG_TEXT_SCREEN_SHOT_SUCCESS_UPLOAD,uploadedFile.getFullPathName());
Or there is even a ScreenShotButton in common-utils, that you can just use in your Application.
4.3 Upload and download by using the GSI version of the FileChooserFx that can deal with Filesystem and WebDAV resources seamlessly
The example is taken from the benno-app and has been slightly modified here:
@FXML
private void exportMadX() {
final ResourceItem initialDirectory =
ResourceItemUtils.newResourceItem(ResourceType.WEBDAV, WEBDAV_FOLDER + comboPattern.getValue() + "/");
final FileChooser fileChooser = new FileChooserImpl();
fileChooser.setTitle("Export MadX File");
fileChooser.setWebdavDirectories(Collections.singletonList(WEBDAV_FOLDER));
fileChooser.setInitialDirectory(initialDirectory);
String timeString = Instant.now().atZone(TIMEZONE_ID_APP).format(DATETIME_FORMATTER_EXPORT_FILE);
fileChooser.setInitialFileName(
"CUSTOM_" + comboPattern.getValue().replace(" ", "_").toUpperCase() + "_" + timeString + ".opt");
fileChooser.showSaveDialog(ApplicationBase.getPrimaryStage(), fileOptional -> {
if (!fileOptional.isEmpty()) {
physicsService.exportMadxStrengthFile(fileOptional.get());
}
});
}
@FXML
private void importMadX() {
final ResourceItem initialDirectory = ResourceItemUtils.newResourceItem(ResourceType.WEBDAV, WEBDAV_FOLDER);
final FileChooser fileChooser = new FileChooserImpl();
fileChooser.setTitle("Import MadX File");
fileChooser.setWebdavDirectories(Collections.singletonList(WEBDAV_FOLDER));
fileChooser.setInitialDirectory(initialDirectory);
fileChooser.showOpenDialog(ApplicationBase.getPrimaryStage(), fileOptional -> {
if (!fileOptional.isEmpty()) {
physicsService.importMadxStrengthFile(fileOptional.get());
updateChartThread("draw");
}
});
}
-- JuttaFitzek - 24 Feb 2023