diff --git a/openbis/dist/server/service.properties b/openbis/dist/server/service.properties index a8107147edbea5d16925a5925874f0058baa2676..f8c3d9e88b0ca0e3c26cd587f140000132c1cb41 100644 --- a/openbis/dist/server/service.properties +++ b/openbis/dist/server/service.properties @@ -33,6 +33,9 @@ database-instance = TEST # Base URL of the Data Store Server data-store-server-base-url = https://localhost:8444 +# The URL of the CIFEX server +cifex-url = https://cifex.ethz.ch:443 + # Hibernate Search # The working directory. hibernate.search.index-base = ./indices diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java index 807c9bac0b5544581fd59c554262dd11580dfaa1..9ce4d92410bf1a3b88b2952d93f6b4a5b98d801f 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java @@ -433,4 +433,8 @@ public interface ICommonClientService extends IClientService { */ public List<DataSetType> listDataSetTypes() throws UserFailureException; + /** Uploads the specified data sets to the specified CIFEX server using the specified password. */ + public void uploadDataSets(List<String> dataSetCodes, String cifexURL, String password) + throws UserFailureException; + } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java index 412354b5d668eb557c58c3d0698935539aea60cf..219c0b3a621f692916e00432ef5fd5ebba50dbef 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java @@ -373,4 +373,8 @@ public interface ICommonClientServiceAsync extends IClientServiceAsync { /** @see ICommonClientService#listDataSetTypes() */ public void listDataSetTypes(AsyncCallback<List<DataSetType>> callback); + + /** @see ICommonClientService#uploadDataSets(List, String, String) */ + public void uploadDataSets(List<String> dataSetCodes, String cifexURL, String password, + AsyncCallback<Void> abstractAsyncCallback); } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java index 126b776587c9a7f457f45a217372a637359c5905..2b04cf16b6fce44ddead2a9d65404543d0dd37e5 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java @@ -310,10 +310,16 @@ public abstract class Dict { public static final String CONFIRM_DATASET_DELETION_MSG = "confirm_dataset_deletion_msg"; - // - // Sample Registration - // - + public static final String BUTTON_UPLOAD_DATASETS = "button_upload_datasets"; + + public static final String CONFIRM_DATASET_UPLOAD_TITLE = "confirm_dataset_upload_title"; + + public static final String CONFIRM_DATASET_UPLOAD_MSG = "confirm_dataset_upload_msg"; + + // + // Sample Registration + // + public static final String INSTANCE_SAMPLE = "instance_sample"; public static final String GENERATED_FROM_SAMPLE = "generated_from_sample"; diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/AbstractExternalDataGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/AbstractExternalDataGrid.java index eb275269f49ad3909ca57e6a9dc7f642ccbe22f5..77c754e90b045bf8266dc5011996e5b7ef7a9b94 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/AbstractExternalDataGrid.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/AbstractExternalDataGrid.java @@ -53,6 +53,31 @@ public abstract class AbstractExternalDataGrid extends AbstractSimpleBrowserGrid { public static final String GRID_POSTFIX = "-grid"; + private static abstract class AbstractConfirmationDialog extends Dialog + { + protected final IViewContext<?> viewContext; + + protected final List<String> dataSetCodes; + + protected final IBrowserGridActionInvoker invoker; + + AbstractConfirmationDialog(IViewContext<?> viewContext, List<ExternalData> dataSets, + IBrowserGridActionInvoker invoker, String titleKey) + { + this.viewContext = viewContext; + this.invoker = invoker; + dataSetCodes = new ArrayList<String>(); + for (ExternalData externalData : dataSets) + { + dataSetCodes.add(externalData.getCode()); + } + setHeading(viewContext.getMessage(titleKey)); + setButtons(Dialog.OKCANCEL); + setHideOnButtonClick(true); + setModal(true); + } + } + static final class DeletionCallback extends AbstractAsyncCallback<Void> { private final IBrowserGridActionInvoker invoker; @@ -70,28 +95,14 @@ public abstract class AbstractExternalDataGrid extends AbstractSimpleBrowserGrid } } - private static final class DeletionConfirmationDialog extends Dialog + private static final class DeletionConfirmationDialog extends AbstractConfirmationDialog { - private final IViewContext<?> viewContext; - - private final List<String> dataSetCodes; - - private final IBrowserGridActionInvoker invoker; - private final TextField<String> reason; public DeletionConfirmationDialog(IViewContext<?> viewContext, List<ExternalData> dataSets, IBrowserGridActionInvoker invoker) { - this.viewContext = viewContext; - this.invoker = invoker; - dataSetCodes = new ArrayList<String>(); - for (ExternalData externalData : dataSets) - { - dataSetCodes.add(externalData.getCode()); - } - setHeading(viewContext.getMessage(Dict.CONFIRM_DATASET_DELETION_TITLE)); - setButtons(Dialog.OKCANCEL); + super(viewContext, dataSets, invoker, Dict.CONFIRM_DATASET_DELETION_TITLE); addText(viewContext.getMessage(Dict.CONFIRM_DATASET_DELETION_MSG, dataSets.size())); reason = new TextField<String>(); reason.setSelectOnFocus(true); @@ -107,8 +118,6 @@ public abstract class AbstractExternalDataGrid extends AbstractSimpleBrowserGrid } }); add(reason); - setHideOnButtonClick(true); - setModal(true); } @Override @@ -123,6 +132,73 @@ public abstract class AbstractExternalDataGrid extends AbstractSimpleBrowserGrid } } + static final class UploadCallback extends AbstractAsyncCallback<Void> + { + private UploadCallback(IViewContext<?> viewContext) + { + super(viewContext); + } + + @Override + protected void process(Void result) + { + } + } + + private static final class UploadConfirmationDialog extends AbstractConfirmationDialog + { + private final String cifexURL; + private final TextField<String> password; + + public UploadConfirmationDialog(IViewContext<?> viewContext, List<ExternalData> dataSets, + IBrowserGridActionInvoker invoker) + { + super(viewContext, dataSets, invoker, Dict.CONFIRM_DATASET_UPLOAD_TITLE); + cifexURL = viewContext.getModel().getApplicationInfo().getCIFEXURL(); + addText(viewContext.getMessage(Dict.CONFIRM_DATASET_UPLOAD_MSG, dataSets.size(), cifexURL)); + password = new TextField<String>(); + password.setPassword(true); + password.setSelectOnFocus(true); + password.setHideLabel(true); + password.setWidth("100%"); + password.setMaxLength(50); + add(password); + } + + @Override + protected void onButtonPressed(Button button) + { + super.onButtonPressed(button); + if (button.getItemId().equals(Dialog.OK)) + { + viewContext.getCommonService().uploadDataSets(dataSetCodes, cifexURL, password.getValue(), + new UploadCallback(viewContext)); + } + } + } + + private abstract class AbstractDataSetAction extends SelectionListener<ButtonEvent> + { + @Override + public void componentSelected(ButtonEvent ce) + { + List<BaseEntityModel<ExternalData>> items = getSelectedItems(); + if (items.isEmpty() == false) + { + List<ExternalData> dataSets = new ArrayList<ExternalData>(); + for (BaseEntityModel<ExternalData> item : items) + { + dataSets.add(item.getBaseObject()); + } + IBrowserGridActionInvoker invoker = asActionInvoker(); + createDialog(dataSets, invoker).show(); + } + } + + protected abstract Dialog createDialog(List<ExternalData> dataSets, + IBrowserGridActionInvoker invoker); + } + protected AbstractExternalDataGrid(final IViewContext<ICommonClientServiceAsync> viewContext, String browserId) { @@ -135,29 +211,33 @@ public abstract class AbstractExternalDataGrid extends AbstractSimpleBrowserGrid DataSetUtils.showDataSet(rowItem, viewContext.getModel()); } }); - Button deleteButton = new Button(viewContext.getMessage(Dict.BUTTON_DELETE_DATASETS)); - deleteButton.addSelectionListener(new SelectionListener<ButtonEvent>() + addButton(Dict.BUTTON_DELETE_DATASETS, new AbstractDataSetAction() { @Override - public void componentSelected(ButtonEvent ce) + protected Dialog createDialog(List<ExternalData> dataSets, + IBrowserGridActionInvoker invoker) { - List<BaseEntityModel<ExternalData>> items = getSelectedItems(); - if (items.isEmpty() == false) - { - List<ExternalData> dataSets = new ArrayList<ExternalData>(); - for (BaseEntityModel<ExternalData> item : items) - { - dataSets.add(item.getBaseObject()); - } - IBrowserGridActionInvoker invoker = asActionInvoker(); - new DeletionConfirmationDialog(viewContext, dataSets, invoker).show(); - } - + return new DeletionConfirmationDialog(viewContext, dataSets, invoker); + } + }); + addButton(Dict.BUTTON_UPLOAD_DATASETS, new AbstractDataSetAction() + { + @Override + protected Dialog createDialog(List<ExternalData> dataSets, + IBrowserGridActionInvoker invoker) + { + return new UploadConfirmationDialog(viewContext, dataSets, invoker); } }); - pagingToolbar.add(new AdapterToolItem(deleteButton)); allowMultipleSelection(); } + + private void addButton(String labelKey, SelectionListener<ButtonEvent> action) + { + Button button = new Button(viewContext.getMessage(labelKey)); + button.addSelectionListener(action); + pagingToolbar.add(new AdapterToolItem(button)); + } @Override protected IColumnDefinitionKind<ExternalData>[] getStaticColumnsDefinition() diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ApplicationInfo.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ApplicationInfo.java index fa9a03d106753889393651deddf31d310ef3486f..900357ba2fe4bda92fe24dec64505dc5298d35b1 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ApplicationInfo.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ApplicationInfo.java @@ -26,6 +26,7 @@ import com.google.gwt.user.client.rpc.IsSerializable; public final class ApplicationInfo implements IsSerializable { private String version; + private String cifexURL; public final String getVersion() { @@ -37,4 +38,14 @@ public final class ApplicationInfo implements IsSerializable this.version = version; } + public void setCIFEXURL(String cifexURL) + { + this.cifexURL = cifexURL; + } + + public final String getCIFEXURL() + { + return cifexURL; + } + } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java index 35bd0fe7844f4eb455a007dd06ff0d34c8278172..186683f5550b459f903e636a94d0553712138255 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java @@ -125,16 +125,19 @@ public final class CommonClientService extends AbstractClientService implements ICommonClientService { private final ICommonServer commonServer; - private final String dataStoreBaseURL; + private String dataStoreBaseURL; - public CommonClientService(final ICommonServer commonServer, - final IRequestContextProvider requestContextProvider, - String dataStoreBaseURL) { - super(requestContextProvider); - this.commonServer = commonServer; - this.dataStoreBaseURL = dataStoreBaseURL + "/" - + DATA_STORE_SERVER_WEB_APPLICATION_NAME; - } + public CommonClientService(final ICommonServer commonServer, + final IRequestContextProvider requestContextProvider) + { + super(requestContextProvider); + this.commonServer = commonServer; + } + + public final void setDataStoreBaseURL(String dataStoreBaseURL) + { + this.dataStoreBaseURL = dataStoreBaseURL + "/" + DATA_STORE_SERVER_WEB_APPLICATION_NAME; + } @Override protected final IServer getServer() { @@ -946,6 +949,35 @@ public final class CommonClientService extends AbstractClientService implements } + public void uploadDataSets(List<String> dataSetCodes, String cifexURL, String password) + throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException + { + try + { + final String sessionToken = getSessionToken(); + commonServer.uploadDataSets(sessionToken, dataSetCodes, cifexURL, password); + } catch (final UserFailureException e) + { + throw UserFailureExceptionTranslator.translate(e); + } + } + + public void updateMaterial(String materialIdentifier, List<MaterialProperty> properties, + Date version) + throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException + { + try + { + final String sessionToken = getSessionToken(); + final MaterialIdentifier identifier = + MaterialIdentifier.tryParseIdentifier(materialIdentifier); + commonServer.editMaterial(sessionToken, identifier, properties, version); + } catch (final ch.systemsx.cisd.common.exceptions.UserFailureException e) + { + throw UserFailureExceptionTranslator.translate(e); + } + } + public void deleteDataSets(List<String> dataSetCodes, String reason) throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException { try { @@ -955,22 +987,7 @@ public final class CommonClientService extends AbstractClientService implements throw UserFailureExceptionTranslator.translate(e); } } - - public void updateMaterial(String materialIdentifier, - List<MaterialProperty> properties, Date version) - throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException { - try { - final String sessionToken = getSessionToken(); - final MaterialIdentifier identifier = MaterialIdentifier - .tryParseIdentifier(materialIdentifier); - commonServer.editMaterial(sessionToken, identifier, properties, - version); - } catch (final ch.systemsx.cisd.common.exceptions.UserFailureException e) { - throw UserFailureExceptionTranslator.translate(e); - } - - } - + public void updateSample( String sampleIdentifier, List<SampleProperty> properties, diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java index 01fcb06ebe57e72252ef29e8a8e76a89539c3511..fba8b36a1ab34e3986b429bd3ab34764ca8d8aa3 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java @@ -17,16 +17,12 @@ package ch.systemsx.cisd.openbis.generic.server; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.Date; -import java.util.LinkedHashSet; import java.util.List; -import java.util.Set; import org.springframework.dao.DataAccessException; -import ch.rinn.restrictions.Private; import ch.systemsx.cisd.authentication.IAuthenticationService; import ch.systemsx.cisd.authentication.ISessionManager; import ch.systemsx.cisd.authentication.Principal; @@ -49,12 +45,10 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.ISampleBO; import ch.systemsx.cisd.openbis.generic.server.business.bo.ISampleTable; import ch.systemsx.cisd.openbis.generic.server.business.bo.IVocabularyBO; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory; -import ch.systemsx.cisd.openbis.generic.server.dataaccess.IExternalDataDAO; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IHibernateSearchDAO; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IRoleAssignmentDAO; import ch.systemsx.cisd.openbis.generic.server.util.GroupIdentifierHelper; import ch.systemsx.cisd.openbis.generic.shared.ICommonServer; -import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetSearchCriteria; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentProperty; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentType; @@ -67,7 +61,6 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary; import ch.systemsx.cisd.openbis.generic.shared.dto.AttachmentPE; import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePE; -import ch.systemsx.cisd.openbis.generic.shared.dto.DataStoreServerSession; import ch.systemsx.cisd.openbis.generic.shared.dto.DataTypePE; import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE; import ch.systemsx.cisd.openbis.generic.shared.dto.EntityTypePE; @@ -104,11 +97,8 @@ import ch.systemsx.cisd.openbis.generic.shared.util.HibernateUtils; * * @author Franz-Josef Elmer */ -public final class CommonServer extends AbstractServer<ICommonServer> implements - ICommonServer { - @Private - static final String DELETION_DESCRIPTION = "single deletion"; - +public final class CommonServer extends AbstractServer<ICommonServer> implements ICommonServer +{ private final IAuthenticationService authenticationService; private final ICommonBusinessObjectFactory businessObjectFactory; @@ -577,59 +567,37 @@ public final class CommonServer extends AbstractServer<ICommonServer> implements } } - public void deleteDataSets(String sessionToken, List<String> dataSetCodes, - String reason) { - Session session = getSessionManager().getSession(sessionToken); - IExternalDataDAO externalDataDAO = getDAOFactory().getExternalDataDAO(); - List<ExternalDataPE> dataSets = new ArrayList<ExternalDataPE>(); - List<String> locations = new ArrayList<String>(); - for (String dataSetCode : dataSetCodes) { - ExternalDataPE dataSet = externalDataDAO - .tryToFindFullDataSetByCode(dataSetCode); - if (dataSet != null) { - dataSets.add(dataSet); - locations.add(dataSet.getLocation()); - } - } - assertDataSetsAreKnown(dataSets, locations); - - for (ExternalDataPE dataSet : dataSets) { - externalDataDAO.markAsDeleted(dataSet, session.tryGetPerson(), - DELETION_DESCRIPTION, reason); - } - Collection<DataStoreServerSession> sessions = dssSessionManager - .getSessions(); - for (DataStoreServerSession dssSession : sessions) { - dssSession.getService().deleteDataSets( - dssSession.getSessionToken(), locations); - } - } - - private void assertDataSetsAreKnown(List<ExternalDataPE> dataSets, - List<String> locations) { - Set<String> knownLocations = new LinkedHashSet<String>(); - Collection<DataStoreServerSession> sessions = dssSessionManager - .getSessions(); - for (DataStoreServerSession session : sessions) { - IDataStoreService service = session.getService(); - String dssSessionToken = session.getSessionToken(); - knownLocations.addAll(service.getKnownDataSets(dssSessionToken, - locations)); - } - List<String> unknownDataSets = new ArrayList<String>(); - for (ExternalDataPE dataSet : dataSets) { - if (knownLocations.contains(dataSet.getLocation()) == false) { - unknownDataSets.add(dataSet.getCode()); - } - } - if (unknownDataSets.isEmpty() == false) { - throw new UserFailureException( - "The following data sets are unknown by any registered Data Store Server. " - + "May be the responsible Data Store Server is not running.\n" - + unknownDataSets); - } - } - + public void deleteDataSets(String sessionToken, List<String> dataSetCodes, String reason) + { + Session session = getSessionManager().getSession(sessionToken); + try + { + IExternalDataTable externalDataTable = + businessObjectFactory.createExternalDataTable(session); + externalDataTable.loadByDataSetCodes(dataSetCodes); + externalDataTable.deleteLoadedDataSets(dssSessionManager, reason); + } catch (final DataAccessException ex) + { + throw createUserFailureException(ex); + } + } + + public void uploadDataSets(String sessionToken, List<String> dataSetCodes, String cifexURL, + String password) + { + Session session = getSessionManager().getSession(sessionToken); + try + { + IExternalDataTable externalDataTable = + businessObjectFactory.createExternalDataTable(session); + externalDataTable.loadByDataSetCodes(dataSetCodes); + externalDataTable.uploadLoadedDataSetsToCIFEX(dssSessionManager, cifexURL, password); + } catch (final DataAccessException ex) + { + throw createUserFailureException(ex); + } + } + public void editExperiment(String sessionToken, ExperimentIdentifier identifier, List<ExperimentProperty> properties, diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java index 915965eb48eb9cf835bdc14dc58aaf3f23eda8d6..ef782cd1d0c2e608a91739f7c878f92b5f9dd3b0 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java @@ -325,11 +325,16 @@ final class CommonServerLogger extends AbstractServerLogger implements dataSetCodes, reason); } - public void editMaterial(String sessionToken, - MaterialIdentifier identifier, List<MaterialProperty> properties, - Date version) { - logTracking(sessionToken, "edit_material", "MATERIAL(%s)", identifier); - + public void uploadDataSets(String sessionToken, List<String> dataSetCodes, String cifexURL, + String password) + { + logTracking(sessionToken, "upload_data_sets", "CODES(%s) CIFEX-URL(%s)", dataSetCodes, cifexURL); + } + + public void editMaterial(String sessionToken, MaterialIdentifier identifier, + List<MaterialProperty> properties, Date version) + { + logTracking(sessionToken, "edit_material", "MATERIAL(%s)", identifier); } public void editSample(String sessionToken, SampleIdentifier identifier, diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataTable.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataTable.java index 02dbcaf7ceb42e0358435e4dba25ffc8995c38c8..813b02203151ebac5c8548edf9d68087c743e662 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataTable.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataTable.java @@ -17,11 +17,20 @@ package ch.systemsx.cisd.openbis.generic.server.business.bo; import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashSet; import java.util.List; import java.util.Set; +import ch.rinn.restrictions.Private; +import ch.systemsx.cisd.common.exceptions.UserFailureException; +import ch.systemsx.cisd.openbis.generic.server.DataStoreServerSessionManager; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory; +import ch.systemsx.cisd.openbis.generic.server.dataaccess.IExternalDataDAO; +import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService; import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE; +import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetUploadContext; +import ch.systemsx.cisd.openbis.generic.shared.dto.DataStoreServerSession; import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE; import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE; import ch.systemsx.cisd.openbis.generic.shared.dto.ProcedurePE; @@ -44,6 +53,11 @@ import ch.systemsx.cisd.openbis.generic.shared.util.HibernateUtils; public final class ExternalDataTable extends AbstractExternalDataBusinessObject implements IExternalDataTable { + private static final String NEW_LINE = "\n"; + private static final int MAX_LENGTH_OF_CIFEX_COMMENT = 1000; + private static final String AND_MORE_TEMPLATE = "and %d more."; + @Private static final String DELETION_DESCRIPTION = "single deletion"; + private List<ExternalDataPE> externalData; public ExternalDataTable(final IDAOFactory daoFactory, final Session session) @@ -61,6 +75,20 @@ public final class ExternalDataTable extends AbstractExternalDataBusinessObject return externalData; } + public void loadByDataSetCodes(List<String> dataSetCodes) + { + IExternalDataDAO externalDataDAO = getExternalDataDAO(); + externalData = new ArrayList<ExternalDataPE>(); + for (String dataSetCode : dataSetCodes) + { + ExternalDataPE dataSet = externalDataDAO.tryToFindFullDataSetByCode(dataSetCode); + if (dataSet != null) + { + externalData.add(dataSet); + } + } + } + public final void loadBySampleIdentifier(final SampleIdentifier sampleIdentifier) { assert sampleIdentifier != null : "Unspecified sample identifier"; @@ -101,4 +129,100 @@ public final class ExternalDataTable extends AbstractExternalDataBusinessObject } } } + + public void deleteLoadedDataSets(DataStoreServerSessionManager dssSessionManager, String reason) + { + assertDataSetsAreKnown(dssSessionManager); + for (ExternalDataPE dataSet : externalData) + { + IExternalDataDAO externalDataDAO = getExternalDataDAO(); + externalDataDAO.markAsDeleted(dataSet, session.tryGetPerson(), DELETION_DESCRIPTION, reason); + } + Collection<DataStoreServerSession> sessions = dssSessionManager.getSessions(); + List<String> locations = getLocations(); + for (DataStoreServerSession dssSession : sessions) + { + dssSession.getService().deleteDataSets(dssSession.getSessionToken(), locations); + } + } + + public void uploadLoadedDataSetsToCIFEX(DataStoreServerSessionManager dssSessionManager, + String cifexURL, String password) + { + assertDataSetsAreKnown(dssSessionManager); + Collection<DataStoreServerSession> sessions = dssSessionManager.getSessions(); + List<String> locations = getLocations(); + DataSetUploadContext uploadContext = new DataSetUploadContext(); + uploadContext.setCifexURL(cifexURL); + uploadContext.setUserID(session.getUserName()); + uploadContext.setPassword(password); + uploadContext.setComment(createUploadComment()); + for (DataStoreServerSession dssSession : sessions) + { + dssSession.getService().uploadDataSetsToCIFEX(dssSession.getSessionToken(), locations, + uploadContext); + } + } + + private String createUploadComment() + { + StringBuilder builder = new StringBuilder(); + builder.append("Uploaded zip file contains the following data sets:"); + for (int i = 0, n = externalData.size(); i < n; i++) + { + builder.append(NEW_LINE); + String code = externalData.get(i).getCode(); + int length = builder.length() + code.length(); + if (i < n - 1) + { + length += NEW_LINE.length() + String.format(AND_MORE_TEMPLATE, n - i - 1).length(); + } + if (length < MAX_LENGTH_OF_CIFEX_COMMENT) + { + builder.append(code); + } else + { + builder.append(String.format(AND_MORE_TEMPLATE, n - i)); + } + } + return builder.toString(); + } + + private void assertDataSetsAreKnown(DataStoreServerSessionManager dssSessionManager) + { + List<String> locations = getLocations(); + Set<String> knownLocations = new LinkedHashSet<String>(); + Collection<DataStoreServerSession> sessions = dssSessionManager.getSessions(); + for (DataStoreServerSession dssSession : sessions) + { + IDataStoreService service = dssSession.getService(); + String dssSessionToken = dssSession.getSessionToken(); + knownLocations.addAll(service.getKnownDataSets(dssSessionToken, locations)); + } + List<String> unknownDataSets = new ArrayList<String>(); + for (ExternalDataPE dataSet : externalData) + { + if (knownLocations.contains(dataSet.getLocation()) == false) + { + unknownDataSets.add(dataSet.getCode()); + } + } + if (unknownDataSets.isEmpty() == false) + { + throw new UserFailureException( + "The following data sets are unknown by any registered Data Store Server. " + + "May be the responsible Data Store Server is not running.\n" + + unknownDataSets); + } + } + + private List<String> getLocations() + { + List<String> locations = new ArrayList<String>(); + for (ExternalDataPE dataSet : externalData) + { + locations.add(dataSet.getLocation()); + } + return locations; + } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IExternalDataTable.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IExternalDataTable.java index 8c4f278b537d829bd6464385d7b6326d229271f4..89452baaf84bdcc25e3b3b71b6e606fb7beb69ff 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IExternalDataTable.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IExternalDataTable.java @@ -18,6 +18,7 @@ package ch.systemsx.cisd.openbis.generic.server.business.bo; import java.util.List; +import ch.systemsx.cisd.openbis.generic.server.DataStoreServerSessionManager; import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier; @@ -29,7 +30,12 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier; */ public interface IExternalDataTable { - + /** + * Loads data sets specified by their codes. Data set codes will be ignored if no + * {@link ExternalDataPE} could be found. + */ + void loadByDataSetCodes(List<String> dataSetCodes); + /** * Loads the internal {@link ExternalDataPE} for given <var>identifier</var>. */ @@ -45,5 +51,9 @@ public interface IExternalDataTable * Returns the loaded {@link ExternalDataPE}. */ List<ExternalDataPE> getExternalData(); + + void deleteLoadedDataSets(DataStoreServerSessionManager dssSessionManager, String reason); + + void uploadLoadedDataSetsToCIFEX(DataStoreServerSessionManager dssSessionManager, String cifexURL, String password); } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java index 2f64236ae77a43fcc218ea71b93503d39b6aa47a..b083f232e16a325cb1d1dd0b8bc2d8d3223c84af 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java @@ -366,18 +366,25 @@ public interface ICommonServer extends IServer { @AuthorizationGuard(guardClass = DataSetCodePredicate.class) List<String> dataSetCodes, String reason); - /** - * Saves changed experiment. - */ - @Transactional - @RolesAllowed(RoleSet.USER) - public void editExperiment( - String sessionToken, - @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) ExperimentIdentifier experimentIdentifier, - List<ExperimentProperty> properties, - List<AttachmentPE> attachments, - @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) ProjectIdentifier newProjectIdentifier, - Date version); + /** + * Uploads specified data sets to CIFEX server of specified URL with specified password. + */ + @Transactional + @RolesAllowed(RoleSet.OBSERVER) + public void uploadDataSets(String sessionToken, List<String> dataSetCodes, String cifexURL, + String password); + + /** + * Saves changed experiment. + */ + @Transactional + @RolesAllowed(RoleSet.USER) + public void editExperiment(String sessionToken, + @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) + ExperimentIdentifier experimentIdentifier, List<ExperimentProperty> properties, + List<AttachmentPE> attachments, + @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) + ProjectIdentifier newProjectIdentifier, Date version); /** * Saves changed material. diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IDataStoreService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IDataStoreService.java index 844f1795c03824d2c2d9ba8eba74dac6a8b0adb1..ca85adb3529aba37ccd8f42847e7e15873e58a63 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IDataStoreService.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IDataStoreService.java @@ -19,6 +19,7 @@ package ch.systemsx.cisd.openbis.generic.shared; import java.util.List; import ch.systemsx.cisd.common.exceptions.InvalidAuthenticationException; +import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetUploadContext; /** * Service interface of Data Store Server. @@ -63,12 +64,12 @@ public interface IDataStoreService throws InvalidAuthenticationException; /** - * Uploads the specified data sets to CIFEX for the specified user (id and password) and with - * specified comment. + * Uploads the specified data sets to CIFEX. * * @param sessionToken Valid token to identify authorised access. + * @param context Context data needed for uploading. * @throws InvalidAuthenticationException if <code>sessionToken</code> is invalid. */ public void uploadDataSetsToCIFEX(String sessionToken, List<String> dataSetLocations, - String comment, String userID, String password) throws InvalidAuthenticationException; + DataSetUploadContext context) throws InvalidAuthenticationException; } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetUploadContext.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetUploadContext.java new file mode 100644 index 0000000000000000000000000000000000000000..019d96db8859b19ab91c15e0ec501de7b40029ca --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetUploadContext.java @@ -0,0 +1,79 @@ +/* + * Copyright 2009 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.generic.shared.dto; + +import java.io.Serializable; + +import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants; + +/** + * + * + * @author Franz-Josef Elmer + */ +public class DataSetUploadContext implements Serializable +{ + private static final long serialVersionUID = GenericSharedConstants.VERSION; + + private String cifexURL; + + private String userID; + + private String password; + + private String comment; + + public final String getCifexURL() + { + return cifexURL; + } + + public final void setCifexURL(String cifexURL) + { + this.cifexURL = cifexURL; + } + + public final String getUserID() + { + return userID; + } + + public final void setUserID(String userID) + { + this.userID = userID; + } + + public final String getPassword() + { + return password; + } + + public final void setPassword(String password) + { + this.password = password; + } + + public final String getComment() + { + return comment; + } + + public final void setComment(String comment) + { + this.comment = comment; + } +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/AbstractClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/AbstractClientService.java index 771c18e7639c6fc5a803752c8442295a4a24cff5..9588c01ed24c89b751d13f35a03725eaaa5fc264 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/AbstractClientService.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/AbstractClientService.java @@ -54,6 +54,8 @@ public abstract class AbstractClientService implements IClientService @Resource(name = "request-context-provider") private IRequestContextProvider requestContextProvider; + private String cifexURL; + protected AbstractClientService() { } @@ -63,6 +65,11 @@ public abstract class AbstractClientService implements IClientService this.requestContextProvider = requestContextProvider; } + public final void setCifexURL(String cifexURL) + { + this.cifexURL = cifexURL; + } + private final SessionContext createSessionContext(final Session session) { final SessionContext sessionContext = new SessionContext(); @@ -144,6 +151,7 @@ public abstract class AbstractClientService implements IClientService { final ApplicationInfo applicationInfo = new ApplicationInfo(); applicationInfo.setVersion(BuildAndEnvironmentInfo.INSTANCE.getFullVersion()); + applicationInfo.setCIFEXURL(cifexURL); return applicationInfo; } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js index 204534a0113a06b4449a1aaa960a8c3aee066dba..da4e551e22f8da43a1edd4828c7926ac593399c1 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js +++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js @@ -278,7 +278,10 @@ var common = { data_producer_code: "Producer", button_delete_datasets: "Delete", confirm_dataset_deletion_title: "Data Sets Deletion Confirmation", - confirm_dataset_deletion_msg: "You are deleting {0} data set(s). Please enter a reason:", + confirm_dataset_deletion_msg: "You are deleting {0} data set(s). Please, enter a reason:", + button_upload_datasets: "Upload to CIFEX", + confirm_dataset_upload_title: "Uploading Confirmation and Authentication", + confirm_dataset_upload_msg: "You are uploading {0} data set(s) to CIFEX ({1}). Please, enter your CIFEX password:", // diff --git a/openbis/source/java/genericApplicationContext.xml b/openbis/source/java/genericApplicationContext.xml index f2c99099d3c169e149b87527fde82cbafa7b2f63..2b6c496e7f05be0c9bebb42badb15e9ae36aec13 100644 --- a/openbis/source/java/genericApplicationContext.xml +++ b/openbis/source/java/genericApplicationContext.xml @@ -79,7 +79,8 @@ <bean id="common-service" class="ch.systemsx.cisd.openbis.generic.client.web.server.CommonClientService"> <constructor-arg ref="common-server" /> <constructor-arg ref="request-context-provider" /> - <constructor-arg value="${data-store-server-base-url}"/> + <property name="dataStoreBaseURL" value="${data-store-server-base-url}"/> + <property name="cifexURL" value="${cifex-url}"/> </bean> <!-- diff --git a/openbis/source/java/service.properties b/openbis/source/java/service.properties index d1d62a51c650db46e6fbb9b3453463a98943b1e4..cb65b4ea8d1a3cc22f054378577eb58d9580e933 100644 --- a/openbis/source/java/service.properties +++ b/openbis/source/java/service.properties @@ -36,6 +36,9 @@ database-instance = CISD # Base URL of the Data Store Server data-store-server-base-url = https://localhost:8889 +# The URL of the CIFEX server +cifex-url = https://cifex.ethz.ch:443 + # Hibernate Search # The working directory. hibernate.search.index-base = ./targets/indices diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientServiceTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientServiceTest.java index 3fb9cf11420f70428830768f6c8c565b61b64397..efbe36a83d2b691c6aec7753a5d9f65ff4bbe273 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientServiceTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientServiceTest.java @@ -64,6 +64,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityDataType; public final class CommonClientServiceTest extends AbstractClientServiceTest { private static final String DATA_STORE_BASE_URL = "baseURL"; + private static final String CIFEX_URL = "cifexURL"; private CommonClientService commonClientService; @@ -123,7 +124,9 @@ public final class CommonClientServiceTest extends AbstractClientServiceTest { super.setUp(); commonServer = context.mock(ICommonServer.class); - commonClientService = new CommonClientService(commonServer, requestContextProvider, DATA_STORE_BASE_URL); + commonClientService = new CommonClientService(commonServer, requestContextProvider); + commonClientService.setDataStoreBaseURL(DATA_STORE_BASE_URL); + commonClientService.setCifexURL(CIFEX_URL); } @Test diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java index 3b561de87186a187b38358662f7f7b0dd81ab29a..c36dfe32535d3960d0ec62f82f4a73d4813cdcd4 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java @@ -16,8 +16,6 @@ package ch.systemsx.cisd.openbis.generic.server; -import static ch.systemsx.cisd.openbis.generic.server.CommonServer.DELETION_DESCRIPTION; - import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -28,13 +26,11 @@ import org.jmock.Expectations; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; -import ch.rinn.restrictions.Friend; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.openbis.generic.server.business.bo.ICommonBusinessObjectFactory; import ch.systemsx.cisd.openbis.generic.shared.AbstractServerTestCase; import ch.systemsx.cisd.openbis.generic.shared.CommonTestUtils; import ch.systemsx.cisd.openbis.generic.shared.ICommonServer; -import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentProperty; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialIdentifier; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialProperty; @@ -42,7 +38,6 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleProperty; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary; import ch.systemsx.cisd.openbis.generic.shared.dto.AttachmentPE; -import ch.systemsx.cisd.openbis.generic.shared.dto.DataStoreServerSession; import ch.systemsx.cisd.openbis.generic.shared.dto.DataTypePE; import ch.systemsx.cisd.openbis.generic.shared.dto.EntityTypePE; import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE; @@ -70,7 +65,6 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind; * * @author Franz-Josef Elmer */ -@Friend(toClasses=CommonServer.class) public final class CommonServerTest extends AbstractServerTestCase { private static final String MATERIAL_TYPE_1 = "MATERIAL-TYPE-1"; @@ -91,8 +85,6 @@ public final class CommonServerTest extends AbstractServerTestCase private DataStoreServerSessionManager dssSessionManager; - private IDataStoreService dataStoreService; - private final ICommonServer createServer() { return new CommonServer(authenticationService, sessionManager, dssSessionManager, @@ -116,7 +108,6 @@ public final class CommonServerTest extends AbstractServerTestCase { super.setUp(); dssSessionManager = new DataStoreServerSessionManager(); - dataStoreService = context.mock(IDataStoreService.class); commonBusinessObjectFactory = context.mock(ICommonBusinessObjectFactory.class); } @@ -724,75 +715,6 @@ public final class CommonServerTest extends AbstractServerTestCase context.assertIsSatisfied(); } - @Test - public void testDeleteDataSetButDataStoreServerIsDown() - { - prepareGetSession(); - final ExternalDataPE d1 = createDataSet("d1"); - context.checking(new Expectations() - { - { - one(externalDataDAO).tryToFindFullDataSetByCode(d1.getCode()); - will(returnValue(d1)); - } - }); - - try - { - createServer().deleteDataSets(SESSION_TOKEN, Arrays.asList(d1.getCode()), ""); - fail("UserFailureException expected"); - } catch (UserFailureException e) - { - assertEquals( - "The following data sets are unknown by any registered Data Store Server. " - + "May be the responsible Data Store Server is not running.\n[d1]", e - .getMessage()); - } - - context.assertIsSatisfied(); - } - - @Test - public void testDeleteDataSetsButOneDataSetIsUnknown() - { - prepareGetSession(); - dssSessionManager.registerDataStoreServer(new DataStoreServerSession("url", - dataStoreService)); - final ExternalDataPE d1 = createDataSet("d1"); - final ExternalDataPE d2 = createDataSet("d2"); - context.checking(new Expectations() - { - { - one(externalDataDAO).tryToFindFullDataSetByCode(d1.getCode()); - will(returnValue(d1)); - - one(externalDataDAO).tryToFindFullDataSetByCode(d2.getCode()); - will(returnValue(d2)); - - List<String> locations = Arrays.asList(d1.getLocation(), d2.getLocation()); - one(dataStoreService).getKnownDataSets(with(any(String.class)), - with(equal(locations))); - will(returnValue(Arrays.asList(d1.getLocation()))); - - } - }); - - try - { - createServer().deleteDataSets(SESSION_TOKEN, Arrays.asList(d1.getCode(), d2.getCode()), - ""); - fail("UserFailureException expected"); - } catch (UserFailureException e) - { - assertEquals( - "The following data sets are unknown by any registered Data Store Server. " - + "May be the responsible Data Store Server is not running.\n[d2]", e - .getMessage()); - } - - context.assertIsSatisfied(); - } - @Test public void testEditMaterialNothingChanged() throws Exception { @@ -871,42 +793,42 @@ public final class CommonServerTest extends AbstractServerTestCase public void testDeleteDataSets() { prepareGetSession(); - dssSessionManager.registerDataStoreServer(new DataStoreServerSession("url", - dataStoreService)); - final ExternalDataPE d1 = createDataSet("d1"); - final ExternalDataPE d2 = createDataSet("d2"); + final List<String> dataSetCodes = Arrays.asList("a", "b"); context.checking(new Expectations() { { - one(externalDataDAO).tryToFindFullDataSetByCode(d1.getCode()); - will(returnValue(d1)); - - one(externalDataDAO).tryToFindFullDataSetByCode(d2.getCode()); - will(returnValue(d2)); - - List<String> locations = Arrays.asList(d1.getLocation(), d2.getLocation()); - one(dataStoreService).getKnownDataSets(with(any(String.class)), - with(equal(locations))); - will(returnValue(locations)); - - one(externalDataDAO).markAsDeleted(d1, SESSION.tryGetPerson(), DELETION_DESCRIPTION, "reason"); - one(externalDataDAO).markAsDeleted(d2, SESSION.tryGetPerson(), DELETION_DESCRIPTION, "reason"); - one(dataStoreService).deleteDataSets(with(any(String.class)), - with(equal(locations))); + one(commonBusinessObjectFactory).createExternalDataTable(SESSION); + will(returnValue(externalDataTable)); + + one(externalDataTable).loadByDataSetCodes(dataSetCodes); + one(externalDataTable).deleteLoadedDataSets(dssSessionManager, "reason"); } }); - createServer().deleteDataSets(SESSION_TOKEN, Arrays.asList(d1.getCode(), d2.getCode()), - "reason"); + createServer().deleteDataSets(SESSION_TOKEN, dataSetCodes, "reason"); context.assertIsSatisfied(); } - - private ExternalDataPE createDataSet(String code) + + @Test + public void testUploadDataSets() { - ExternalDataPE data = new ExternalDataPE(); - data.setCode(code); - data.setLocation("here/" + code); - return data; + prepareGetSession(); + final List<String> dataSetCodes = Arrays.asList("a", "b"); + context.checking(new Expectations() + { + { + one(commonBusinessObjectFactory).createExternalDataTable(SESSION); + will(returnValue(externalDataTable)); + + one(externalDataTable).loadByDataSetCodes(dataSetCodes); + one(externalDataTable).uploadLoadedDataSetsToCIFEX(dssSessionManager, "cifexURL", "pwd"); + } + }); + + createServer().uploadDataSets(SESSION_TOKEN, dataSetCodes, "cifexURL", "pwd"); + + context.assertIsSatisfied(); } + } diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataTableTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataTableTest.java index 4617845e5f59c6d7df0ef30676ae0049e8b42ab4..414b7ff748ffe50bfaf36166a8be6f29a85d85d6 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataTableTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataTableTest.java @@ -16,21 +16,29 @@ package ch.systemsx.cisd.openbis.generic.server.business.bo; +import static ch.systemsx.cisd.openbis.generic.server.business.bo.ExternalDataTable.DELETION_DESCRIPTION; + import java.util.Arrays; import java.util.HashSet; import java.util.List; import org.jmock.Expectations; +import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; +import ch.rinn.restrictions.Friend; import ch.systemsx.cisd.common.exceptions.UserFailureException; +import ch.systemsx.cisd.openbis.generic.server.DataStoreServerSessionManager; import ch.systemsx.cisd.openbis.generic.server.business.ManagerTestTool; +import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService; import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE; +import ch.systemsx.cisd.openbis.generic.shared.dto.DataStoreServerSession; import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE; import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE; import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE; import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE; import ch.systemsx.cisd.openbis.generic.shared.dto.HierarchyType; +import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE; import ch.systemsx.cisd.openbis.generic.shared.dto.ProcedurePE; import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE; import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE; @@ -45,14 +53,26 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier; * * @author Christian Ribeaud */ +@Friend(toClasses=ExternalDataTable.class) public final class ExternalDataTableTest extends AbstractBOTest { + private DataStoreServerSessionManager dssSessionManager; + private IDataStoreService dataStoreService; private final ExternalDataTable createExternalDataTable() { return new ExternalDataTable(daoFactory, ManagerTestTool.EXAMPLE_SESSION); } + @BeforeMethod + @Override + public void beforeMethod() + { + super.beforeMethod(); + dssSessionManager = new DataStoreServerSessionManager(); + dataStoreService = context.mock(IDataStoreService.class); + } + @Test public final void testLoadBySampleIdentifierWithNullSampleIdentifier() { @@ -193,4 +213,143 @@ public final class ExternalDataTableTest extends AbstractBOTest context.assertIsSatisfied(); } + + @Test + public void testDeleteLoadedDataSetsButDataStoreServerIsDown() + { + final ExternalDataPE d1 = createDataSet("d1"); + context.checking(new Expectations() + { + { + one(externalDataDAO).tryToFindFullDataSetByCode(d1.getCode()); + will(returnValue(d1)); + } + }); + + ExternalDataTable externalDataTable = createExternalDataTable(); + externalDataTable.loadByDataSetCodes(Arrays.asList(d1.getCode())); + try + { + externalDataTable.deleteLoadedDataSets(dssSessionManager, ""); + fail("UserFailureException expected"); + } catch (UserFailureException e) + { + assertEquals( + "The following data sets are unknown by any registered Data Store Server. " + + "May be the responsible Data Store Server is not running.\n[d1]", e + .getMessage()); + } + + context.assertIsSatisfied(); + } + + @Test + public void testLoadByDataSetCodes() + { + final ExternalDataPE d1 = createDataSet("d1"); + final ExternalDataPE d2 = createDataSet("d2"); + context.checking(new Expectations() + { + { + one(externalDataDAO).tryToFindFullDataSetByCode(d1.getCode()); + will(returnValue(d1)); + + one(externalDataDAO).tryToFindFullDataSetByCode(d2.getCode()); + will(returnValue(null)); + } + }); + + ExternalDataTable externalDataTable = createExternalDataTable(); + externalDataTable.loadByDataSetCodes(Arrays.asList(d1.getCode(), d2.getCode())); + + assertEquals(1, externalDataTable.getExternalData().size()); + assertSame(d1, externalDataTable.getExternalData().get(0)); + + context.assertIsSatisfied(); + } + + @Test + public void testDeleteLoadedDataSetsButOneDataSetIsUnknown() + { + dssSessionManager.registerDataStoreServer(new DataStoreServerSession("url", + dataStoreService)); + final ExternalDataPE d1 = createDataSet("d1"); + final ExternalDataPE d2 = createDataSet("d2"); + context.checking(new Expectations() + { + { + one(externalDataDAO).tryToFindFullDataSetByCode(d1.getCode()); + will(returnValue(d1)); + + one(externalDataDAO).tryToFindFullDataSetByCode(d2.getCode()); + will(returnValue(d2)); + + List<String> locations = Arrays.asList(d1.getLocation(), d2.getLocation()); + one(dataStoreService).getKnownDataSets(with(any(String.class)), + with(equal(locations))); + will(returnValue(Arrays.asList(d1.getLocation()))); + + } + }); + + ExternalDataTable externalDataTable = createExternalDataTable(); + externalDataTable.loadByDataSetCodes(Arrays.asList(d1.getCode(), d2.getCode())); + try + { + externalDataTable.deleteLoadedDataSets(dssSessionManager, ""); + fail("UserFailureException expected"); + } catch (UserFailureException e) + { + assertEquals( + "The following data sets are unknown by any registered Data Store Server. " + + "May be the responsible Data Store Server is not running.\n[d2]", e + .getMessage()); + } + + context.assertIsSatisfied(); + } + + @Test + public void testDeleteLoadedDataSets() + { + dssSessionManager.registerDataStoreServer(new DataStoreServerSession("url", + dataStoreService)); + final ExternalDataPE d1 = createDataSet("d1"); + final ExternalDataPE d2 = createDataSet("d2"); + context.checking(new Expectations() + { + { + one(externalDataDAO).tryToFindFullDataSetByCode(d1.getCode()); + will(returnValue(d1)); + + one(externalDataDAO).tryToFindFullDataSetByCode(d2.getCode()); + will(returnValue(d2)); + + List<String> locations = Arrays.asList(d1.getLocation(), d2.getLocation()); + one(dataStoreService).getKnownDataSets(with(any(String.class)), + with(equal(locations))); + will(returnValue(locations)); + + PersonPE person = ManagerTestTool.EXAMPLE_SESSION.tryGetPerson(); + one(externalDataDAO).markAsDeleted(d1, person, DELETION_DESCRIPTION, "reason"); + one(externalDataDAO).markAsDeleted(d2, person, DELETION_DESCRIPTION, "reason"); + one(dataStoreService).deleteDataSets(with(any(String.class)), + with(equal(locations))); + } + }); + + ExternalDataTable externalDataTable = createExternalDataTable(); + externalDataTable.loadByDataSetCodes(Arrays.asList(d1.getCode(), d2.getCode())); + externalDataTable.deleteLoadedDataSets(dssSessionManager, "reason"); + + context.assertIsSatisfied(); + } + + private ExternalDataPE createDataSet(String code) + { + ExternalDataPE data = new ExternalDataPE(); + data.setCode(code); + data.setLocation("here/" + code); + return data; + } } diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java.expected b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java.expected index b81a82be2b514c863f1f54cd9391b5e990715afd..a02048f244eb353fba6e800db9ea54805ed0f51f 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java.expected +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java.expected @@ -77,345 +77,352 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind; * @author Franz-Josef Elmer */ public interface ICommonServer extends IServer { - /** - * Returns all groups which belong to the specified database instance. * - * - * @return a sorted list of {@link GroupPE}. - */ - @Transactional(readOnly = true) - @RolesAllowed(RoleSet.OBSERVER) - @ReturnValueFilter(validatorClass = GroupValidator.class) - public List<GroupPE> listGroups(String sessionToken, - DatabaseInstanceIdentifier identifier); - - /** - * Registers a new group with specified code and optional description and - * group leader ID. - */ - @Transactional - @RolesAllowed(RoleSet.INSTANCE_ADMIN) - public void registerGroup(String sessionToken, String groupCode, - String descriptionOrNull, String groupLeaderOrNull); - - /** - * Returns all persons from current instance. - * - * @return a sorted list of {@link PersonPE}. - */ - @Transactional(readOnly = true) - @RolesAllowed(RoleSet.OBSERVER) - public List<PersonPE> listPersons(String sessionToken); - - /** - * Returns all projects. - * - * @return a sorted list of {@link ProjectPE}. - */ - @Transactional(readOnly = true) - @RolesAllowed(RoleSet.OBSERVER) - @ReturnValueFilter(validatorClass = ProjectValidator.class) - public List<ProjectPE> listProjects(String sessionToken); - - /** - * Registers a new person. - */ - @Transactional - @RolesAllowed(RoleSet.INSTANCE_ADMIN) - public void registerPerson(String sessionToken, String userID); - - /** - * Returns a list of all roles. - */ - @Transactional(readOnly = true) - @RolesAllowed(RoleSet.GROUP_ADMIN) - public List<RoleAssignmentPE> listRoles(String sessionToken); - - /** - * Registers a new group role. - */ - @Transactional - @RolesAllowed(RoleSet.GROUP_ADMIN) - public void registerGroupRole( - String sessionToken, - RoleCode roleCode, - @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) GroupIdentifier identifier, - String person); - - /** - * Registers a new instance role. - */ - @Transactional - @RolesAllowed(RoleSet.INSTANCE_ADMIN) - public void registerInstanceRole(String sessionToken, RoleCode roleCode, - String person); - - /** - * Deletes role described by given role code, group identifier and user id. - */ - @Transactional - @RolesAllowed(RoleSet.GROUP_ADMIN) - public void deleteGroupRole( - String sessionToken, - RoleCode roleCode, - @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) GroupIdentifier groupIdentifier, - String person); - - /** - * Deletes role described by given role code and user id. - */ - @Transactional - @RolesAllowed(RoleSet.INSTANCE_ADMIN) - public void deleteInstanceRole(String sessionToken, RoleCode roleCode, - String person); - - /** - * Lists sample types which are appropriate for listing. - * - * @return a sorted list of {@link SampleTypePE}. - */ - @Transactional(readOnly = true) - @RolesAllowed(RoleSet.OBSERVER) - public List<SampleTypePE> listSampleTypes(String sessionToken); - - /** - * Lists samples using given configuration. - * - * @return a sorted list of {@link SamplePE}. - */ - @Transactional(readOnly = true) - @RolesAllowed(RoleSet.OBSERVER) - public List<SamplePE> listSamples(final String sessionToken, - final ListSampleCriteriaDTO criteria); - - /** - * Lists experiments. - * - * @return a sorted list of {@link ExperimentPE}. - */ - @Transactional(readOnly = true) - @RolesAllowed(RoleSet.OBSERVER) - public List<ExperimentPE> listExperiments( - final String sessionToken, - ExperimentTypePE experimentType, - @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) ProjectIdentifier project); - - /** - * For given {@link SampleIdentifier} returns the corresponding list of - * {@link ExternalDataPE}. - * - * @return a sorted list of {@link ExternalDataPE}. - */ - @Transactional(readOnly = true) - @RolesAllowed(RoleSet.OBSERVER) - public List<ExternalDataPE> listExternalData( - final String sessionToken, - @AuthorizationGuard(guardClass = SampleOwnerIdentifierPredicate.class) final SampleIdentifier identifier); - - /** - * For given {@link ExperimentIdentifier} returns the corresponding list of - * {@link ExternalDataPE}. - * - * @return a sorted list of {@link ExternalDataPE}. - */ - @Transactional(readOnly = true) - @RolesAllowed(RoleSet.OBSERVER) - public List<ExternalDataPE> listExternalData( - final String sessionToken, - @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) final ExperimentIdentifier identifier); - - /** - * Performs an <i>Hibernate Search</i> based on given parameters. - */ - @Transactional(readOnly = true) - @RolesAllowed(RoleSet.OBSERVER) - @ReturnValueFilter(validatorClass = MatchingEntityValidator.class) - public List<SearchHit> listMatchingEntities(final String sessionToken, - final SearchableEntity[] searchableEntities, final String queryText); - - /** - * List experiment types. - * - * @return a sorted list of {@link ExperimentTypePE}. - */ - @Transactional(readOnly = true) - @RolesAllowed(RoleSet.OBSERVER) - public List<ExperimentTypePE> listExperimentTypes(String sessionToken); - - /** - * List property types. - * - * @return a sorted list of {@link PropertyTypePE}. - */ - @Transactional(readOnly = true) - @RolesAllowed(RoleSet.OBSERVER) - public List<PropertyTypePE> listPropertyTypes(final String sessionToken); - - /** - * Lists data types. - * - * @return a sorted list of {@link DataTypePE}. - */ - @Transactional(readOnly = true) - @RolesAllowed(RoleSet.OBSERVER) - public List<DataTypePE> listDataTypes(final String sessionToken); - - /** - * Lists vocabularies. - * - * @return a sorted list of {@link VocabularyPE}. - */ - @Transactional(readOnly = true) - @RolesAllowed(RoleSet.OBSERVER) - public List<VocabularyPE> listVocabularies(final String sessionToken, - final boolean withTerms, boolean excludeInternal); - - /** - * Registers given {@link PropertyType}. - */ - @Transactional - @RolesAllowed(RoleSet.INSTANCE_ADMIN) - public void registerPropertyType(final String sessionToken, - final PropertyType propertyType); - - /** - * Assigns property type to entity type. - */ - @Transactional - @RolesAllowed(RoleSet.INSTANCE_ADMIN) - public String assignPropertyType(final String sessionToken, - final EntityKind entityKind, final String propertyTypeCode, - final String entityTypeCode, final boolean isMandatory, - final String defaultValue); - - /** - * Registers given {@link Vocabulary}. - */ - @Transactional - @RolesAllowed(RoleSet.INSTANCE_ADMIN) - public void registerVocabulary(final String sessionToken, - final Vocabulary vocabulary); - - /** - * Registers new project. - */ - @Transactional - @RolesAllowed(RoleSet.GROUP_ADMIN) - public void registerProject( - String sessionToken, - @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) ProjectIdentifier projectIdentifier, - String description, String leaderId); - - /** - * Performs an <i>Hibernate Search</i> based on given parameters. - */ - @Transactional(readOnly = true) - @RolesAllowed(RoleSet.OBSERVER) - @ReturnValueFilter(validatorClass = ExternalDataValidator.class) - public List<ExternalDataPE> searchForDataSets(String sessionToken, - DataSetSearchCriteria criteria); - - /** - * List material types. - * - * @return a sorted list of {@link MaterialTypePE}. - */ - @Transactional(readOnly = true) - @RolesAllowed(RoleSet.OBSERVER) - public List<MaterialTypePE> listMaterialTypes(String sessionToken); - - /** - * Lists materials. - * - * @return a sorted list of {@link MaterialPE}. - */ - @Transactional(readOnly = true) - @RolesAllowed(RoleSet.OBSERVER) - public List<MaterialPE> listMaterials(String sessionToken, - MaterialTypePE materialType); - - /** - * Creates a new material type. - */ - @Transactional - @RolesAllowed(RoleSet.INSTANCE_ADMIN) - public void registerMaterialType(String sessionToken, - MaterialType entityType); - - /** - * Creates a new sample type. - */ - @Transactional - @RolesAllowed(RoleSet.INSTANCE_ADMIN) - public void registerSampleType(String sessionToken, SampleType entityType); - - /** - * Creates a new experiment type. - */ - @Transactional - @RolesAllowed(RoleSet.INSTANCE_ADMIN) - public void registerExperimentType(String sessionToken, - ExperimentType entityType); - - /** - * Deletes specified data sets. - */ - @Transactional - @RolesAllowed(RoleSet.GROUP_ADMIN) - public void deleteDataSets( - String sessionToken, - @AuthorizationGuard(guardClass = DataSetCodePredicate.class) List<String> dataSetCodes, - String reason); - - /** - * Saves changed experiment. - */ - @Transactional - @RolesAllowed(RoleSet.USER) - public void editExperiment( - String sessionToken, - @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) ExperimentIdentifier experimentIdentifier, - List<ExperimentProperty> properties, - List<AttachmentPE> attachments, - @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) ProjectIdentifier newProjectIdentifier, - Date version); - - /** - * Saves changed material. - */ - @Transactional - @RolesAllowed(RoleSet.INSTANCE_ADMIN) - public void editMaterial(String sessionToken, - MaterialIdentifier identifier, List<MaterialProperty> properties, - Date version); - - /** - * Saves changed sample. - */ - @Transactional - @RolesAllowed(RoleSet.USER) - public void editSample( - String sessionToken, - @AuthorizationGuard(guardClass = SampleOwnerIdentifierPredicate.class) SampleIdentifier identifier, - List<SampleProperty> properties, - @AuthorizationGuard(guardClass = NullableGroupIdentifierPredicate.class) ExperimentIdentifier experimentIdentifierOrNull, - Date version); - - /** - * Lists vocabulary terms of a given vocabulary. Includes terms usage - * statistics. - */ - @Transactional - @RolesAllowed(RoleSet.USER) - public List<VocabularyTermWithStats> listVocabularyTerms( - String sessionToken, Vocabulary vocabulary); - - /** - * List data set types. - * - * @return a sorted list of {@link DataSetTypePE}. - */ - @Transactional(readOnly = true) - @RolesAllowed(RoleSet.OBSERVER) - public List<DataSetTypePE> listDataSetTypes(String sessionToken); + /** + * Returns all groups which belong to the specified database instance. * + * + * @return a sorted list of {@link GroupPE}. + */ + @Transactional(readOnly = true) + @RolesAllowed(RoleSet.OBSERVER) + @ReturnValueFilter(validatorClass = GroupValidator.class) + public List<GroupPE> listGroups(String sessionToken, + DatabaseInstanceIdentifier identifier); + + /** + * Registers a new group with specified code and optional description and + * group leader ID. + */ + @Transactional + @RolesAllowed(RoleSet.INSTANCE_ADMIN) + public void registerGroup(String sessionToken, String groupCode, + String descriptionOrNull, String groupLeaderOrNull); + + /** + * Returns all persons from current instance. + * + * @return a sorted list of {@link PersonPE}. + */ + @Transactional(readOnly = true) + @RolesAllowed(RoleSet.OBSERVER) + public List<PersonPE> listPersons(String sessionToken); + + /** + * Returns all projects. + * + * @return a sorted list of {@link ProjectPE}. + */ + @Transactional(readOnly = true) + @RolesAllowed(RoleSet.OBSERVER) + @ReturnValueFilter(validatorClass = ProjectValidator.class) + public List<ProjectPE> listProjects(String sessionToken); + + /** + * Registers a new person. + */ + @Transactional + @RolesAllowed(RoleSet.INSTANCE_ADMIN) + public void registerPerson(String sessionToken, String userID); + + /** + * Returns a list of all roles. + */ + @Transactional(readOnly = true) + @RolesAllowed(RoleSet.GROUP_ADMIN) + public List<RoleAssignmentPE> listRoles(String sessionToken); + + /** + * Registers a new group role. + */ + @Transactional + @RolesAllowed(RoleSet.GROUP_ADMIN) + public void registerGroupRole( + String sessionToken, + RoleCode roleCode, + @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) GroupIdentifier identifier, + String person); + + /** + * Registers a new instance role. + */ + @Transactional + @RolesAllowed(RoleSet.INSTANCE_ADMIN) + public void registerInstanceRole(String sessionToken, RoleCode roleCode, + String person); + + /** + * Deletes role described by given role code, group identifier and user id. + */ + @Transactional + @RolesAllowed(RoleSet.GROUP_ADMIN) + public void deleteGroupRole( + String sessionToken, + RoleCode roleCode, + @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) GroupIdentifier groupIdentifier, + String person); + + /** + * Deletes role described by given role code and user id. + */ + @Transactional + @RolesAllowed(RoleSet.INSTANCE_ADMIN) + public void deleteInstanceRole(String sessionToken, RoleCode roleCode, + String person); + + /** + * Lists sample types which are appropriate for listing. + * + * @return a sorted list of {@link SampleTypePE}. + */ + @Transactional(readOnly = true) + @RolesAllowed(RoleSet.OBSERVER) + public List<SampleTypePE> listSampleTypes(String sessionToken); + + /** + * Lists samples using given configuration. + * + * @return a sorted list of {@link SamplePE}. + */ + @Transactional(readOnly = true) + @RolesAllowed(RoleSet.OBSERVER) + public List<SamplePE> listSamples(final String sessionToken, + final ListSampleCriteriaDTO criteria); + + /** + * Lists experiments. + * + * @return a sorted list of {@link ExperimentPE}. + */ + @Transactional(readOnly = true) + @RolesAllowed(RoleSet.OBSERVER) + public List<ExperimentPE> listExperiments( + final String sessionToken, + ExperimentTypePE experimentType, + @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) ProjectIdentifier project); + + /** + * For given {@link SampleIdentifier} returns the corresponding list of + * {@link ExternalDataPE}. + * + * @return a sorted list of {@link ExternalDataPE}. + */ + @Transactional(readOnly = true) + @RolesAllowed(RoleSet.OBSERVER) + public List<ExternalDataPE> listExternalData( + final String sessionToken, + @AuthorizationGuard(guardClass = SampleOwnerIdentifierPredicate.class) final SampleIdentifier identifier); + + /** + * For given {@link ExperimentIdentifier} returns the corresponding list of + * {@link ExternalDataPE}. + * + * @return a sorted list of {@link ExternalDataPE}. + */ + @Transactional(readOnly = true) + @RolesAllowed(RoleSet.OBSERVER) + public List<ExternalDataPE> listExternalData( + final String sessionToken, + @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) final ExperimentIdentifier identifier); + + /** + * Performs an <i>Hibernate Search</i> based on given parameters. + */ + @Transactional(readOnly = true) + @RolesAllowed(RoleSet.OBSERVER) + @ReturnValueFilter(validatorClass = MatchingEntityValidator.class) + public List<SearchHit> listMatchingEntities(final String sessionToken, + final SearchableEntity[] searchableEntities, final String queryText); + + /** + * List experiment types. + * + * @return a sorted list of {@link ExperimentTypePE}. + */ + @Transactional(readOnly = true) + @RolesAllowed(RoleSet.OBSERVER) + public List<ExperimentTypePE> listExperimentTypes(String sessionToken); + + /** + * List property types. + * + * @return a sorted list of {@link PropertyTypePE}. + */ + @Transactional(readOnly = true) + @RolesAllowed(RoleSet.OBSERVER) + public List<PropertyTypePE> listPropertyTypes(final String sessionToken); + + /** + * Lists data types. + * + * @return a sorted list of {@link DataTypePE}. + */ + @Transactional(readOnly = true) + @RolesAllowed(RoleSet.OBSERVER) + public List<DataTypePE> listDataTypes(final String sessionToken); + + /** + * Lists vocabularies. + * + * @return a sorted list of {@link VocabularyPE}. + */ + @Transactional(readOnly = true) + @RolesAllowed(RoleSet.OBSERVER) + public List<VocabularyPE> listVocabularies(final String sessionToken, + final boolean withTerms, boolean excludeInternal); + + /** + * Registers given {@link PropertyType}. + */ + @Transactional + @RolesAllowed(RoleSet.INSTANCE_ADMIN) + public void registerPropertyType(final String sessionToken, + final PropertyType propertyType); + + /** + * Assigns property type to entity type. + */ + @Transactional + @RolesAllowed(RoleSet.INSTANCE_ADMIN) + public String assignPropertyType(final String sessionToken, + final EntityKind entityKind, final String propertyTypeCode, + final String entityTypeCode, final boolean isMandatory, + final String defaultValue); + + /** + * Registers given {@link Vocabulary}. + */ + @Transactional + @RolesAllowed(RoleSet.INSTANCE_ADMIN) + public void registerVocabulary(final String sessionToken, + final Vocabulary vocabulary); + + /** + * Registers new project. + */ + @Transactional + @RolesAllowed(RoleSet.GROUP_ADMIN) + public void registerProject( + String sessionToken, + @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) ProjectIdentifier projectIdentifier, + String description, String leaderId); + + /** + * Performs an <i>Hibernate Search</i> based on given parameters. + */ + @Transactional(readOnly = true) + @RolesAllowed(RoleSet.OBSERVER) + @ReturnValueFilter(validatorClass = ExternalDataValidator.class) + public List<ExternalDataPE> searchForDataSets(String sessionToken, + DataSetSearchCriteria criteria); + + /** + * List material types. + * + * @return a sorted list of {@link MaterialTypePE}. + */ + @Transactional(readOnly = true) + @RolesAllowed(RoleSet.OBSERVER) + public List<MaterialTypePE> listMaterialTypes(String sessionToken); + + /** + * Lists materials. + * + * @return a sorted list of {@link MaterialPE}. + */ + @Transactional(readOnly = true) + @RolesAllowed(RoleSet.OBSERVER) + public List<MaterialPE> listMaterials(String sessionToken, + MaterialTypePE materialType); + + /** + * Creates a new material type. + */ + @Transactional + @RolesAllowed(RoleSet.INSTANCE_ADMIN) + public void registerMaterialType(String sessionToken, + MaterialType entityType); + + /** + * Creates a new sample type. + */ + @Transactional + @RolesAllowed(RoleSet.INSTANCE_ADMIN) + public void registerSampleType(String sessionToken, SampleType entityType); + + /** + * Creates a new experiment type. + */ + @Transactional + @RolesAllowed(RoleSet.INSTANCE_ADMIN) + public void registerExperimentType(String sessionToken, + ExperimentType entityType); + + /** + * Deletes specified data sets. + */ + @Transactional + @RolesAllowed(RoleSet.GROUP_ADMIN) + public void deleteDataSets( + String sessionToken, + @AuthorizationGuard(guardClass = DataSetCodePredicate.class) List<String> dataSetCodes, + String reason); + + /** + * Uploads specified data sets to CIFEX server of specified URL with specified password. + */ + @Transactional + @RolesAllowed(RoleSet.OBSERVER) + public void uploadDataSets(String sessionToken, List<String> dataSetCodes, String cifexURL, + String password); + + /** + * Saves changed experiment. + */ + @Transactional + @RolesAllowed(RoleSet.USER) + public void editExperiment(String sessionToken, + @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) + ExperimentIdentifier experimentIdentifier, List<ExperimentProperty> properties, + List<AttachmentPE> attachments, + @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) + ProjectIdentifier newProjectIdentifier, Date version); + + /** + * Saves changed material. + */ + @Transactional + @RolesAllowed(RoleSet.INSTANCE_ADMIN) + public void editMaterial(String sessionToken, + MaterialIdentifier identifier, List<MaterialProperty> properties, + Date version); + + /** + * Saves changed sample. + */ + @Transactional + @RolesAllowed(RoleSet.USER) + public void editSample( + String sessionToken, + @AuthorizationGuard(guardClass = SampleOwnerIdentifierPredicate.class) SampleIdentifier identifier, + List<SampleProperty> properties, + @AuthorizationGuard(guardClass = NullableGroupIdentifierPredicate.class) ExperimentIdentifier experimentIdentifierOrNull, + Date version); + + /** + * Lists vocabulary terms of a given vocabulary. Includes terms usage + * statistics. + */ + @Transactional + @RolesAllowed(RoleSet.USER) + public List<VocabularyTermWithStats> listVocabularyTerms( + String sessionToken, Vocabulary vocabulary); + + /** + * List data set types. + * + * @return a sorted list of {@link DataSetTypePE}. + */ + @Transactional(readOnly = true) + @RolesAllowed(RoleSet.OBSERVER) + public List<DataSetTypePE> listDataSetTypes(String sessionToken); }