diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/common/get/GetServerPublicInformationOperationExecutor.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/common/get/GetServerPublicInformationOperationExecutor.java index 9b2d07595b22bb3e6aa1d1e67c3e8d3004d4393b..511c4ebf9dd97e2bd34d6d3a3c885f6dfb64aea6 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/common/get/GetServerPublicInformationOperationExecutor.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/common/get/GetServerPublicInformationOperationExecutor.java @@ -16,6 +16,7 @@ package ch.ethz.sis.openbis.generic.server.asapi.v3.executor.common.get; import java.util.Map; +import java.util.Properties; import java.util.TreeMap; import javax.annotation.Resource; @@ -51,12 +52,24 @@ public class GetServerPublicInformationOperationExecutor protected GetServerPublicInformationOperationResult doExecute(IOperationContext context, GetServerPublicInformationOperation operation) { Map<String, String> info = new TreeMap<>(); - info.put("authentication-service", configurer.getResolvedProps().getProperty(ComponentNames.AUTHENTICATION_SERVICE)); + final Properties props = configurer.getResolvedProps(); + info.put("authentication-service", props.getProperty(ComponentNames.AUTHENTICATION_SERVICE)); info.put("authentication-service.switch-aai.link", - configurer.getResolvedProps().getProperty(ComponentNames.AUTHENTICATION_SERVICE + "." + Constants.SWITCH_AAI_LINK)); + props.getProperty(ComponentNames.AUTHENTICATION_SERVICE + "." + Constants.SWITCH_AAI_LINK)); info.put("authentication-service.switch-aai.label", - configurer.getResolvedProps().getProperty(ComponentNames.AUTHENTICATION_SERVICE + "." + Constants.SWITCH_AAI_LABEL)); - info.put("openbis.support.email", configurer.getResolvedProps().getProperty(ComponentNames.OPENBIS_SUPPORT_EMAIL)); + props.getProperty(ComponentNames.AUTHENTICATION_SERVICE + "." + Constants.SWITCH_AAI_LABEL)); + info.put("openbis.support.email", props.getProperty(ComponentNames.OPENBIS_SUPPORT_EMAIL)); + + // Put all properties of the format "server-public-information.x", where x is the rest of the string + for (final Map.Entry<?, ?> propEntry : props.entrySet()) + { + final String key = (String) propEntry.getKey(); + if (key.startsWith(ComponentNames.SERVER_PUBLIC_INFORMATION)) + { + info.put(key, propEntry.getValue().toString()); + } + } + return new GetServerPublicInformationOperationResult(info); } diff --git a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/ComponentNames.java b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/ComponentNames.java index 6a8734a71639426b2b38e63019e7cdc6005718b1..e58f1ab03ca15bf1f737e55359eabe7fd9175be5 100644 --- a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/ComponentNames.java +++ b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/ComponentNames.java @@ -54,4 +54,6 @@ public final class ComponentNames public static final String JYTHON_EVALUATOR_POOL = "jython-evaluator-pool"; public static final String OPENBIS_SUPPORT_EMAIL = "openbis.support.email"; + + public static final String SERVER_PUBLIC_INFORMATION = "server-public-information."; } diff --git a/server-application-server/source/java/service.properties b/server-application-server/source/java/service.properties index b3b0ceced05362821b6b6e74d82cf627e88f09df..d7a8947b7b5b6353e71176bb2bef0a26804266c4 100644 --- a/server-application-server/source/java/service.properties +++ b/server-application-server/source/java/service.properties @@ -306,3 +306,10 @@ api.v3.transaction.participant.afs-server.url = http://localhost:8085/data-store # A timeout in seconds for the afs server operations. Default: 3600 # api.v3.transaction.participant.afs-server.timeout = + + +# +# Server public information (returned by the V3 API's getServerPublicInformation() method) +# + +server-public-information.afs-server.url = http://localhost:8085/data-store-server \ No newline at end of file diff --git a/ui-admin/index.html b/ui-admin/index.html index 55c8686f7de64fe84be81eafe69e99ac7faf352e..337d6d57109b8c3e3cce8457955ac811be55a3bb 100644 --- a/ui-admin/index.html +++ b/ui-admin/index.html @@ -42,7 +42,6 @@ <script src="/openbis/resources/api/data-store-server/api/jszip.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/streamsaver@2"></script> <script src="/openbis/resources/api/v3/require.js"></script> - <script src="/openbis/resources/api/data-store-server/api/server-data-store-facade.js"></script> </head> <body> <div id="app"></div> diff --git a/ui-admin/src/js/components/database/data-browser/DataBrowser.jsx b/ui-admin/src/js/components/database/data-browser/DataBrowser.jsx index da902e418871cb2f66b1002b1eae61d400e102c3..06c3328b4b048a2d5b1cc2050740defec1cffe1a 100644 --- a/ui-admin/src/js/components/database/data-browser/DataBrowser.jsx +++ b/ui-admin/src/js/components/database/data-browser/DataBrowser.jsx @@ -13,8 +13,6 @@ import DataBrowserController from '@src/js/components/database/data-browser/Data import messages from '@src/js/common/messages.js' import InfoBar from '@src/js/components/database/data-browser/InfoBar.jsx' -const HTTP_SERVER_URI = '/data-store-server' - const styles = theme => ({ columnFlexContainer: { flexDirection: 'column', @@ -251,11 +249,6 @@ class DataBrowser extends React.Component { this.controller = controller || new DataBrowserController(id) this.controller.attach(this) - this.datastoreServer = new DataStoreServer( - 'http://localhost:8085', - HTTP_SERVER_URI - ) - this.controller.setSessionToken(sessionToken) this.state = { viewType: props.viewType, @@ -461,7 +454,6 @@ class DataBrowser extends React.Component { onDownload={this.handleDownload} showInfo={showInfo} multiselectedFiles={multiselectedFiles} - datastoreServer={this.datastoreServer} sessionToken={sessionToken} owner={id} path={path} diff --git a/ui-admin/src/js/components/database/data-browser/DataBrowserController.js b/ui-admin/src/js/components/database/data-browser/DataBrowserController.js index 995aa16ed8dfb2347db2a0d339d96bd0aa62b7f5..ba17aa0134c1f5489e8b9940239839978894d392 100644 --- a/ui-admin/src/js/components/database/data-browser/DataBrowserController.js +++ b/ui-admin/src/js/components/database/data-browser/DataBrowserController.js @@ -16,6 +16,7 @@ import ComponentController from '@src/js/components/common/ComponentController.js' import autoBind from 'auto-bind' +import openbis from '@src/js/services/openbis.js' const CHUNK_SIZE = 1024 * 1024 // 1MiB @@ -31,50 +32,30 @@ export default class DataBrowserController extends ComponentController { this.fileNames = [] } - setSessionToken(sessionToken) { - this.component.datastoreServer.useSession(sessionToken) - } - - free() { - return new Promise((resolve, reject) => { - this.component.datastoreServer.free(this.owner, this.path) - .then((data) => { - if (!data.error) { - resolve(data); - } else { - reject(data.error) - } - }) - .catch((error) => { - if (error.message.includes('NoSuchFileException')) { - resolve([]) - } else { - reject(error) - } - }) - }) + async free() { + try { + return await openbis.free(this.owner, this.path); + } catch (error) { + if (error.message.includes('NoSuchFileException')) { + return [] + } else { + throw error + } + } } async listFiles(path) { // Use this.path if path is not specified const pathToList = path ? path : this.path - return new Promise((resolve, reject) => { - this.component.datastoreServer.list(this.owner, pathToList, false) - .then((data) => { - if (!data.error) { - resolve(data) - } else { - reject(data.error) - } - }) - .catch((error) => { - if (error.message.includes('NoSuchFileException')) { - resolve([]) - } else { - reject(error) - } - }) - }) + try { + return await openbis.list(this.owner, pathToList, false) + } catch (error) { + if (error.message.includes('NoSuchFileException')) { + return [] + } else { + throw error + } + } } async load() { @@ -90,14 +71,14 @@ export default class DataBrowserController extends ComponentController { } async createNewFolder(name) { - await this.component.datastoreServer.create(this.owner, this.path + name, true) + await openbis.create(this.owner, this.path + name, true) if (this.gridController) { await this.gridController.load() } } async rename(oldName, newName) { - await this.component.datastoreServer.move(this.owner, this.path + oldName, this.owner, this.path + newName) + await openbis.move(this.owner, this.path + oldName, this.owner, this.path + newName) if (this.gridController) { await this.gridController.load() } @@ -114,7 +95,7 @@ export default class DataBrowserController extends ComponentController { } async _delete(file) { - await this.component.datastoreServer.delete(this.owner, file.path) + await openbis.delete(this.owner, file.path) } async copy(files, newLocation) { @@ -130,7 +111,7 @@ export default class DataBrowserController extends ComponentController { async _copy(file, newLocation){ if (!this.isSubdirectory(file.path, newLocation)) { const cleanNewLocation = this._removeLeadingSlash(newLocation) + file.name - await this.component.datastoreServer.copy(this.owner, file.path, this.owner, cleanNewLocation) + await openbis.copy(this.owner, file.path, this.owner, cleanNewLocation) } } @@ -147,7 +128,7 @@ export default class DataBrowserController extends ComponentController { async _move(file, newLocation){ if (!this.isSubdirectory(file.path, newLocation)) { const cleanNewLocation = this._removeLeadingSlash(newLocation) + file.name - await this.component.datastoreServer.move(this.owner, file.path, this.owner, cleanNewLocation) + await openbis.move(this.owner, file.path, this.owner, cleanNewLocation) } } @@ -220,7 +201,7 @@ export default class DataBrowserController extends ComponentController { } async _uploadChunk(source, offset, data) { - return await this.component.datastoreServer.write(this.owner, source, offset, data) + return await openbis.write(this.owner, source, offset, data) } async _arrayBufferToBase64(buffer) { @@ -276,7 +257,7 @@ export default class DataBrowserController extends ComponentController { async _download(file, offset) { const limit = Math.min(CHUNK_SIZE, file.size - offset) - return await this.component.datastoreServer.read(this.owner, file.path, offset, limit) + return await openbis.read(this.owner, file.path, offset, limit) } _removeLeadingSlash(path) { diff --git a/ui-admin/src/js/components/database/data-browser/LeftToolbar.jsx b/ui-admin/src/js/components/database/data-browser/LeftToolbar.jsx index ab8dacbbe7415430f5b2bc7f93134fc11026b9ef..539619e3e05db4e744d014d93e24cffeb35d402b 100644 --- a/ui-admin/src/js/components/database/data-browser/LeftToolbar.jsx +++ b/ui-admin/src/js/components/database/data-browser/LeftToolbar.jsx @@ -216,7 +216,6 @@ class LeftToolbar extends React.Component { classes, buttonSize, multiselectedFiles, - datastoreServer, sessionToken, owner, path, @@ -356,7 +355,6 @@ class LeftToolbar extends React.Component { open={!!locationDialogMode} title={locationDialogMode === moveLocationMode ? messages.get(messages.MOVE) : messages.get(messages.COPY)} content={messages.get(messages.FILE_OR_FILES, multiselectedFiles.size)} - datastoreServer={datastoreServer} sessionToken={sessionToken} owner={owner} path={path} diff --git a/ui-admin/src/js/components/database/data-browser/LocationDialog.jsx b/ui-admin/src/js/components/database/data-browser/LocationDialog.jsx index a4332823449188aec55c2f2fe1aad3570a212c35..64a4f6997eb81b5af8c7313347af178259ee6a1e 100644 --- a/ui-admin/src/js/components/database/data-browser/LocationDialog.jsx +++ b/ui-admin/src/js/components/database/data-browser/LocationDialog.jsx @@ -45,12 +45,10 @@ class LocationDialog extends React.Component { super(props) autoBind(this) - const { path, sessionToken, datastoreServer, owner } = this.props + const { path, sessionToken, owner } = this.props this.controller = new DataBrowserController(owner) this.controller.attach(this) - this.datastoreServer = datastoreServer - this.controller.setSessionToken(sessionToken) this.state = { path, diff --git a/ui-admin/src/js/components/database/data-browser/Toolbar.jsx b/ui-admin/src/js/components/database/data-browser/Toolbar.jsx index bdd7be6d9089797dde61e7399bcdf25b38b9f1aa..88bd9f8e4cffb43393125448a7c6c614f21ff53b 100644 --- a/ui-admin/src/js/components/database/data-browser/Toolbar.jsx +++ b/ui-admin/src/js/components/database/data-browser/Toolbar.jsx @@ -52,7 +52,6 @@ class Toolbar extends React.Component { showInfo, onShowInfoChange, multiselectedFiles, - datastoreServer, sessionToken, owner, path, @@ -63,7 +62,6 @@ class Toolbar extends React.Component { <LeftToolbar buttonSize={buttonSize} multiselectedFiles={multiselectedFiles} - datastoreServer={datastoreServer} sessionToken={sessionToken} owner={owner} path={path} diff --git a/ui-admin/src/js/services/openbis/api.js b/ui-admin/src/js/services/openbis/api.js index e9061203f01497cdf0da408e629f1c6c1868ebcc..d79fc89e1d378fb298b26038aee61949f4ffe308 100644 --- a/ui-admin/src/js/services/openbis/api.js +++ b/ui-admin/src/js/services/openbis/api.js @@ -13,9 +13,21 @@ class Facade { requirejs( ['openbis', 'util/Json'], (openbis, stjs) => { - _this.v3 = new openbis() - _this.stjs = stjs - resolve() + new openbis().getServerPublicInformation() + .then(result => { + const afsServerUrlKey = 'server-public-information.afs-server.url' + const afsServerUrl = result[afsServerUrlKey] + if (afsServerUrl) { + _this.v3 = new openbis(null, afsServerUrl) + _this.stjs = stjs + resolve() + } else { + reject(new Error(afsServerUrlKey + ' is not set.')) + } + }, + error => { + reject(error) + }) }, error => { reject(error) @@ -248,6 +260,38 @@ class Facade { return this.promise(this.stjs.fromJson(jsonType, jsonObject)); } + list(owner, source, recursively) { + return this.promise(this.v3.getAfsServerFacade().list(owner, source, recursively)) + } + + read(owner, source, offset, limit) { + return this.promise(this.v3.getAfsServerFacade().read(owner, source, offset, limit)) + } + + write(owner, source, offset, data) { + return this.promise(this.v3.getAfsServerFacade().write(owner, source, offset, data)) + } + + delete(owner, source) { + return this.promise(this.v3.getAfsServerFacade().delete(owner, source)) + } + + copy(sourceOwner, source, targetOwner, target) { + return this.promise(this.v3.getAfsServerFacade().copy(sourceOwner, source, targetOwner, target)) + } + + move(sourceOwner, source, targetOwner, target) { + return this.promise(this.v3.getAfsServerFacade().move(sourceOwner, source, targetOwner, target)) + } + + create(owner, source, directory) { + return this.promise(this.v3.getAfsServerFacade().create(owner, source, directory)) + } + + free(owner, source) { + return this.promise(this.v3.getAfsServerFacade().free(owner, source)) + } + async executeService(id, options) { const scheduleResult = await this.executeOperations( [new dto.ExecuteCustomASServiceOperation(id, options)],