diff --git a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/OpenBIS.java b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/OpenBIS.java index ede5ae601e1850100b5e77f56382d0dc22983b42..76ba0dae6246adf2359a34a1d51770650f9183c2 100644 --- a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/OpenBIS.java +++ b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/OpenBIS.java @@ -34,9 +34,13 @@ import java.util.UUID; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; +import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.client.util.BytesContentProvider; +import org.eclipse.jetty.client.util.MultiPartContentProvider; +import org.eclipse.jetty.client.util.PathContentProvider; +import org.eclipse.jetty.client.util.StringContentProvider; import org.eclipse.jetty.http.HttpMethod; import ch.ethz.sis.afsapi.api.OperationsAPI; @@ -116,7 +120,7 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.externaldms.update.ExternalDmsUp import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.GlobalSearchObject; import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.fetchoptions.GlobalSearchObjectFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.search.GlobalSearchCriteria; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.IImportData; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportData; import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.Material; import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.MaterialType; @@ -1241,7 +1245,7 @@ public class OpenBIS return asFacadeWithTransactions.createCodes(sessionToken, prefix, entityKind, count); } - public void executeImport(IImportData importData, ImportOptions importOptions) { + public void executeImport(ImportData importData, ImportOptions importOptions) { asFacadeWithTransactions.executeImport(sessionToken, importData, importOptions); } @@ -1249,6 +1253,45 @@ public class OpenBIS return asFacadeWithTransactions.executeExport(sessionToken, exportData, exportOptions); } + public String uploadToSessionWorkspace(final Path fileOrFolder) + { + if (transactionId != null) + { + throw new IllegalStateException("AS session workspace SHOULD NOT be used during transactions."); + } + + String uploadId = UUID.randomUUID().toString() + "/" + fileOrFolder.getFileName().toString(); + + try + { + HttpClient httpClient = JettyHttpClientFactory.getHttpClient(); + + MultiPartContentProvider multiPart = new MultiPartContentProvider(); + multiPart.addFieldPart("sessionKeysNumber", new StringContentProvider("1"), null); + multiPart.addFieldPart("sessionKey_0", new StringContentProvider("openbis-file-upload"), null); + multiPart.addFilePart("openbis-file-upload", uploadId, new PathContentProvider(fileOrFolder), null); + multiPart.addFieldPart("keepOriginalFileName", new StringContentProvider("True"), null); + multiPart.addFieldPart("sessionID", new StringContentProvider(this.sessionToken), null); + multiPart.close(); + + ContentResponse response = httpClient.newRequest(this.asURL + "/upload") + .method(HttpMethod.POST) + .content(multiPart) + .send(); + + final int status = response.getStatus(); + if (status != 200) + { + throw new IOException(response.getContentAsString()); + } + } catch (final IOException | TimeoutException | InterruptedException | ExecutionException e) + { + throw new RuntimeException(e); + } + + return uploadId; + } + // // DSS Facade methods // diff --git a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/IApplicationServerApi.java b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/IApplicationServerApi.java index bd1ec54d8cec68848cb6ffe19e7017edaf66d141..c58a8be081a0980d9a16540c824afa355a50e5fb 100644 --- a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/IApplicationServerApi.java +++ b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/IApplicationServerApi.java @@ -89,7 +89,8 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.externaldms.update.ExternalDmsUp import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.GlobalSearchObject; import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.fetchoptions.GlobalSearchObjectFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.search.GlobalSearchCriteria; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.IImportData; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportResult; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportData; import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.Material; import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.MaterialType; @@ -2262,7 +2263,7 @@ public interface IApplicationServerApi extends IRpcService */ public List<String> createCodes(String sessionToken, String prefix, EntityKind entityKind, int count); - public void executeImport(String sessionToken, IImportData importData, ImportOptions importOptions); + public ImportResult executeImport(String sessionToken, ImportData importData, ImportOptions importOptions); public ExportResult executeExport(String sessionToken, ExportData exportData, ExportOptions exportOptions); diff --git a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/ImportOperation.java b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/ImportOperation.java index 509ee42d9781903c7c0162e4a46e13957a9430aa..479452c9b9841166b7ab85d028b09e81db8bb35c 100644 --- a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/ImportOperation.java +++ b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/ImportOperation.java @@ -24,7 +24,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.ObjectToString; import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.operation.IOperation; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.IImportData; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportData; import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportOptions; import ch.systemsx.cisd.base.annotation.JsonObject; @@ -35,7 +35,7 @@ public class ImportOperation implements Serializable, IOperation private static final long serialVersionUID = 1L; @JsonProperty - private IImportData importData; + private ImportData importData; @JsonProperty private ImportOptions importOptions; @@ -45,7 +45,7 @@ public class ImportOperation implements Serializable, IOperation { } - public ImportOperation(final IImportData importData, final ImportOptions importOptions) + public ImportOperation(final ImportData importData, final ImportOptions importOptions) { this.importData = importData; this.importOptions = importOptions; @@ -58,13 +58,13 @@ public class ImportOperation implements Serializable, IOperation } @JsonIgnore - public IImportData getImportData() + public ImportData getImportData() { return importData; } @JsonIgnore - public void setImportData(final IImportData importData) + public void setImportData(final ImportData importData) { this.importData = importData; } diff --git a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/ImportOperationResult.java b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/ImportOperationResult.java index a28b89ee5f3c05a1fcecc0435662dd63c556abe0..54e9619942e2aff248c18b6972b54ec644c21ad2 100644 --- a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/ImportOperationResult.java +++ b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/ImportOperationResult.java @@ -19,6 +19,9 @@ package ch.ethz.sis.openbis.generic.asapi.v3.dto.importer; import java.io.Serializable; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; + import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.operation.IOperationResult; import ch.systemsx.cisd.base.annotation.JsonObject; @@ -28,12 +31,35 @@ public class ImportOperationResult implements Serializable, IOperationResult private static final long serialVersionUID = 1L; + @JsonProperty + private ImportResult importResult; + + public ImportOperationResult() + { + } + + public ImportOperationResult(final ImportResult importResult) + { + this.importResult = importResult; + } + @Override public String getMessage() { return toString(); } + @JsonIgnore + public ImportResult getImportResult() + { + return importResult; + } + + public void setImportResult(final ImportResult importResult) + { + this.importResult = importResult; + } + @Override public String toString() { diff --git a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportScript.java b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/ImportResult.java similarity index 59% rename from api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportScript.java rename to api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/ImportResult.java index 4307d2ff86c753ce26a9c42d1ddb1ccf3d2929cf..29ca23329d807b456294d2050e6c3027bc6fe47e 100644 --- a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportScript.java +++ b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/ImportResult.java @@ -14,67 +14,53 @@ * limitations under the License. */ -package ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data; +package ch.ethz.sis.openbis.generic.asapi.v3.dto.importer; import java.io.Serializable; +import java.util.List; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.ObjectToString; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.id.IObjectId; import ch.systemsx.cisd.base.annotation.JsonObject; -@JsonObject("as.dto.importer.data.ImportScript") -public class ImportScript implements Serializable +@JsonObject("as.dto.importer.ImportResult") +public class ImportResult implements Serializable { private static final long serialVersionUID = 1L; @JsonProperty - private String name; - - @JsonProperty - private String source; + private List<IObjectId> objectIds; @SuppressWarnings("unused") - public ImportScript() - { - } - - public ImportScript(final String name, final String source) + public ImportResult() { - this.name = name; - this.source = source; } - @JsonIgnore - public String getName() - { - return name; - } - - @JsonIgnore - public void setName(final String name) + public ImportResult(final List<IObjectId> objectIds) { - this.name = name; + this.objectIds = objectIds; } @JsonIgnore - public String getSource() + public List<IObjectId> getObjectIds() { - return source; + return objectIds; } @JsonIgnore - public void setSource(final String source) + public void setObjectIds(final List<IObjectId> objectIds) { - this.source = source; + this.objectIds = objectIds; } @Override public String toString() { - return new ObjectToString(this).append("name", name).append("source", source).toString(); + return new ObjectToString(this).append("objectIds", objectIds).toString(); } } diff --git a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/IImportData.java b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/IImportData.java deleted file mode 100644 index 4f47167bdca1a88a117f8a56475c629b63600d91..0000000000000000000000000000000000000000 --- a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/IImportData.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright ETH 2023 Zürich, Scientific IT Services - * - * 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.ethz.sis.openbis.generic.asapi.v3.dto.importer.data; - -import java.io.Serializable; - -import ch.systemsx.cisd.base.annotation.JsonObject; - -@JsonObject("as.dto.importer.data.IImportData") -public interface IImportData extends Serializable -{ -} diff --git a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ZipImportData.java b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportData.java similarity index 74% rename from api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ZipImportData.java rename to api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportData.java index d3a95e6bbd35b02a1091889c8fd17ce38cf460ac..02137385311c6446a995290c96f66ac6d0b53f7b 100644 --- a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ZipImportData.java +++ b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportData.java @@ -24,8 +24,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.ObjectToString; import ch.systemsx.cisd.base.annotation.JsonObject; -@JsonObject("as.dto.importer.data.ZipImportData") -public class ZipImportData implements Serializable, IImportData +@JsonObject("as.dto.importer.data.ImportData") +public class ImportData implements Serializable { private static final long serialVersionUID = 1L; @@ -33,17 +33,17 @@ public class ZipImportData implements Serializable, IImportData private ImportFormat format; @JsonProperty - private byte[] file; + private String[] sessionWorkspaceFiles; @SuppressWarnings("unused") - public ZipImportData() + public ImportData() { } - public ZipImportData(final ImportFormat format, final byte[] file) + public ImportData(final ImportFormat format, final String... sessionWorkspaceFiles) { this.format = format; - this.file = file; + this.sessionWorkspaceFiles = sessionWorkspaceFiles; } @JsonIgnore @@ -58,16 +58,14 @@ public class ZipImportData implements Serializable, IImportData this.format = format; } - @JsonIgnore - public byte[] getFile() + public String[] getSessionWorkspaceFiles() { - return file; + return sessionWorkspaceFiles; } - @JsonIgnore - public void setFile(final byte[] file) + public void setSessionWorkspaceFiles(String[] sessionWorkspaceFiles) { - this.file = file; + this.sessionWorkspaceFiles = sessionWorkspaceFiles; } @Override diff --git a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportFormat.java b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportFormat.java index 3bd858e12712669ecd3d96ed0ec4738bff954153..415b5c6295014dbd9efc5128f5bce07e1daf8242 100644 --- a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportFormat.java +++ b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportFormat.java @@ -22,6 +22,6 @@ import ch.systemsx.cisd.base.annotation.JsonObject; public enum ImportFormat { - XLS + EXCEL } diff --git a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportValue.java b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportValue.java deleted file mode 100644 index 005b3e1059aef790c9dcfebe2eb0b4b205cdae86..0000000000000000000000000000000000000000 --- a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportValue.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright ETH 2023 Zürich, Scientific IT Services - * - * 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.ethz.sis.openbis.generic.asapi.v3.dto.importer.data; - -import java.io.Serializable; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; - -import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.ObjectToString; -import ch.systemsx.cisd.base.annotation.JsonObject; - -@JsonObject("as.dto.importer.data.ImportValue") -public class ImportValue implements Serializable -{ - - private static final long serialVersionUID = 1L; - - @JsonProperty - private String name; - - @JsonProperty - private String value; - - @SuppressWarnings("unused") - public ImportValue() - { - } - - public ImportValue(final String name, final String value) - { - this.name = name; - this.value = value; - } - - @JsonIgnore - public String getName() - { - return name; - } - - @JsonIgnore - public void setName(final String name) - { - this.name = name; - } - - @JsonIgnore - public String getValue() - { - return value; - } - - @JsonIgnore - public void setValue(final String value) - { - this.value = value; - } - - @Override - public String toString() - { - final ObjectToString builder = new ObjectToString(this).append("name", name); - if (value == null) - { - builder.append("value", null); - } else if (value.length() <= 255) - { - builder.append("value", value); - } else - { - builder.append("value", value.substring(0, 255) + "..."); - } - return builder.toString(); - } - -} diff --git a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/UncompressedImportData.java b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/UncompressedImportData.java deleted file mode 100644 index 44113b16817213fa7c372fa3871779ce4e91b2a8..0000000000000000000000000000000000000000 --- a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/UncompressedImportData.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright ETH 2023 Zürich, Scientific IT Services - * - * 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.ethz.sis.openbis.generic.asapi.v3.dto.importer.data; - -import java.io.Serializable; -import java.util.Collection; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; - -import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.ObjectToString; -import ch.systemsx.cisd.base.annotation.JsonObject; - -@JsonObject("as.dto.importer.data.UncompressedImportData") -public class UncompressedImportData implements Serializable, IImportData -{ - private static final long serialVersionUID = 1L; - - @JsonProperty - private ImportFormat format; - - @JsonProperty - private byte[] file; - - @JsonProperty - private Collection<ImportScript> scripts; - - @JsonProperty - private Collection<ImportValue> importValues; - - @SuppressWarnings("unused") - public UncompressedImportData() - { - } - - public UncompressedImportData(final ImportFormat format, final byte[] file, final Collection<ImportScript> scripts, - final Collection<ImportValue> importValues) - { - this.format = format; - this.file = file; - this.scripts = scripts; - this.importValues = importValues; - } - - @JsonIgnore - public ImportFormat getFormat() - { - return format; - } - - @JsonIgnore - public void setFormat(final ImportFormat format) - { - this.format = format; - } - - @JsonIgnore - public byte[] getFile() - { - return file; - } - - @JsonIgnore - public void setFile(final byte[] file) - { - this.file = file; - } - - @JsonIgnore - public Collection<ImportScript> getScripts() - { - return scripts; - } - - @JsonIgnore - public void setScripts(final Collection<ImportScript> scripts) - { - this.scripts = scripts; - } - - @JsonIgnore - public Collection<ImportValue> getImportValues() - { - return importValues; - } - - @JsonIgnore - public void setImportValues(final Collection<ImportValue> importValues) - { - this.importValues = importValues; - } - - @Override - public String toString() - { - return new ObjectToString(this).append("format", format).append("scripts", scripts).toString(); - } - -} diff --git a/api-openbis-java/sourceTest/java/ch/ethz/sis/openbis/generic/sharedapi/v3/dictionary.txt b/api-openbis-java/sourceTest/java/ch/ethz/sis/openbis/generic/sharedapi/v3/dictionary.txt index af8a6580cf705a2d6aa1ca7516aa93231d96f283..21daba1c397710945af2d28792ee8cb41812b2c3 100644 --- a/api-openbis-java/sourceTest/java/ch/ethz/sis/openbis/generic/sharedapi/v3/dictionary.txt +++ b/api-openbis-java/sourceTest/java/ch/ethz/sis/openbis/generic/sharedapi/v3/dictionary.txt @@ -464,6 +464,7 @@ Event Sort Options Event Tech Id Event Type Event Type Search Criteria +EXCEL exec execute Aggregation Service Execute Aggregation Service Operation @@ -1282,7 +1283,6 @@ IExternalDmsId IFileFormatTypeId IGNORE_EXISTING IIdentifierHolder -IImportData ILocatorTypeId ImagingDataSetConfig ImagingDataSetControl @@ -1300,8 +1300,6 @@ ImportModes ImportOperation ImportOperationResult ImportOptions -ImportScript -ImportValue indent indexOf INSTANCE @@ -2495,7 +2493,6 @@ UNARCHIVE_PENDING UnarchiveDataSetsOperation UnarchiveDataSetsOperationResult UnauthorizedObjectAccessException -UncompressedImportData UNDEFINED UNIQUE_SUBCODES UNKNOWN @@ -2903,7 +2900,6 @@ XlsTextFormat XLSX XML YES -ZipImportData I Transaction Coordinator Api I Transaction Participant Api APPLICATION_SERVER_PARTICIPANT_ID diff --git a/api-openbis-javascript/src/v3/as/dto/importer/ImportOperation.js b/api-openbis-javascript/src/v3/as/dto/importer/ImportOperation.js index 717aa8112bffde1141a8bb3bf359ee5e6ce61d21..aeb00d41c2da7c72016158de687936c5779d0dc6 100644 --- a/api-openbis-javascript/src/v3/as/dto/importer/ImportOperation.js +++ b/api-openbis-javascript/src/v3/as/dto/importer/ImportOperation.js @@ -46,7 +46,7 @@ define(["stjs", "as/dto/common/operation/IOperation"], }; }, { - importData: "IImportData", + importData: "ImportData", importOptions: "ImportOptions" } ); diff --git a/api-openbis-javascript/src/v3/as/dto/importer/ImportOperationResult.js b/api-openbis-javascript/src/v3/as/dto/importer/ImportOperationResult.js index 8644008309f35a02da7fcdeee25354a5a1d0b28c..9bdfca0689c2e34d47404b78eee237965fee1918 100644 --- a/api-openbis-javascript/src/v3/as/dto/importer/ImportOperationResult.js +++ b/api-openbis-javascript/src/v3/as/dto/importer/ImportOperationResult.js @@ -17,7 +17,8 @@ define(["stjs", "as/dto/common/operation/IOperationResult"], function (stjs, IOperationResult) { - var ImportOperationResult = function() { + var ImportOperationResult = function(importResult) { + this.importResult = importResult; } stjs.extend( @@ -28,12 +29,23 @@ define(["stjs", "as/dto/common/operation/IOperationResult"], prototype["@type"] = "as.dto.importer.ImportOperationResult"; constructor.serialVersionUID = 1; + prototype.importResult = null; prototype.getMessage = function() { return "ImportOperationResult"; }; + + prototype.getImportResult = function() { + return this.importResult; + }; + + prototype.setImportResult = function(importResult) { + this.importResult = importResult; + }; }, - {} + { + importResult: "ImportResult" + } ); return ImportOperationResult; diff --git a/api-openbis-javascript/src/v3/as/dto/importer/data/ImportScript.js b/api-openbis-javascript/src/v3/as/dto/importer/ImportResult.js similarity index 58% rename from api-openbis-javascript/src/v3/as/dto/importer/data/ImportScript.js rename to api-openbis-javascript/src/v3/as/dto/importer/ImportResult.js index 64545851a6271a2595aec39c671ec1c5858d1456..29daa115a9837ac0624ea98a7f5600e087b4b51d 100644 --- a/api-openbis-javascript/src/v3/as/dto/importer/data/ImportScript.js +++ b/api-openbis-javascript/src/v3/as/dto/importer/ImportResult.js @@ -15,40 +15,36 @@ * */ -define(["stjs"], - function (stjs) { - var ImportScript = function() { +define(["stjs"], function (stjs) { + var ImportResult = function(objectIds) { + this.objectIds = objectIds; } stjs.extend( - ImportScript, + ImportResult, null, [], function (constructor, prototype) { - prototype["@type"] = "as.dto.importer.data.ImportScript"; + prototype["@type"] = "as.dto.importer.ImportResult"; constructor.serialVersionUID = 1; - prototype.name = null; - prototype.source = null; + prototype.objectIds = null; - prototype.getName = function() { - return this.name; + prototype.getObjectIds = function() { + return this.objectIds; }; - prototype.setName = function(name) { - this.name = name; - }; - - prototype.getSource = function() { - return this.source; - }; - - prototype.setSource = function(source) { - this.source = source; + prototype.setObjectIds = function(objectIds) { + this.objectIds = objectIds; }; }, - {} + { + objectIds: { + name: "List", + arguments: ["IObjectId"] + } + } ); - return ImportScript; + return ImportResult; }); \ No newline at end of file diff --git a/api-openbis-javascript/src/v3/as/dto/importer/data/IImportData.js b/api-openbis-javascript/src/v3/as/dto/importer/data/IImportData.js deleted file mode 100644 index 1289c8e8e4d5fc079dc7015a826b2e4cb6f0d821..0000000000000000000000000000000000000000 --- a/api-openbis-javascript/src/v3/as/dto/importer/data/IImportData.js +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright ETH 2023 Zürich, Scientific IT Services - * - * 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. - * - */ - -define(["stjs"], function (stjs) { - var IImportData = function () { - }; - stjs.extend(IImportData, null, [], null, {}); - return IImportData; -}); \ No newline at end of file diff --git a/api-openbis-javascript/src/v3/as/dto/importer/data/ZipImportData.js b/api-openbis-javascript/src/v3/as/dto/importer/data/ImportData.js similarity index 61% rename from api-openbis-javascript/src/v3/as/dto/importer/data/ZipImportData.js rename to api-openbis-javascript/src/v3/as/dto/importer/data/ImportData.js index 918cc534cd6552fff8c56e05034e0815f33aa253..9786a7ef566b7f8ed41bb4bae185b15b2d644237 100644 --- a/api-openbis-javascript/src/v3/as/dto/importer/data/ZipImportData.js +++ b/api-openbis-javascript/src/v3/as/dto/importer/data/ImportData.js @@ -15,21 +15,22 @@ * */ -define(["stjs", "as/dto/importer/data/IImportData"], - function (stjs, IImportData) { - var ZipImportData = function() { +define(["stjs"], function (stjs) { + var ImportData = function(format, sessionWorkspaceFiles) { + this.format = format; + this.sessionWorkspaceFiles = sessionWorkspaceFiles; } stjs.extend( - ZipImportData, - IImportData, - [IImportData], + ImportData, + null, + [], function (constructor, prototype) { - prototype["@type"] = "as.dto.importer.data.ZipImportData"; + prototype["@type"] = "as.dto.importer.data.ImportData"; constructor.serialVersionUID = 1; prototype.format = null; - prototype.file = null; + prototype.sessionWorkspaceFiles = null; prototype.getFormat = function() { return this.format; @@ -39,19 +40,19 @@ define(["stjs", "as/dto/importer/data/IImportData"], this.format = format; }; - prototype.getFile = function() { - return this.file; + prototype.getSessionWorkspaceFiles = function() { + return this.sessionWorkspaceFiles; }; - prototype.setFile = function(file) { - this.file = file; + prototype.setSessionWorkspaceFiles = function(sessionWorkspaceFiles) { + this.sessionWorkspaceFiles = sessionWorkspaceFiles; }; }, { format: "ImportFormat", - file: "byte[]" + sessionWorkspaceFiles: "String[]" } ); - return ZipImportData; + return ImportData; }); \ No newline at end of file diff --git a/api-openbis-javascript/src/v3/as/dto/importer/data/ImportFormat.js b/api-openbis-javascript/src/v3/as/dto/importer/data/ImportFormat.js index 982b7ff16bf67abb8fba38779fe10f233d4997d0..4ffb6dd245409c3c821af477395dc5f15e11b058 100644 --- a/api-openbis-javascript/src/v3/as/dto/importer/data/ImportFormat.js +++ b/api-openbis-javascript/src/v3/as/dto/importer/data/ImportFormat.js @@ -17,7 +17,7 @@ define(["stjs", "as/dto/common/Enum"], function (stjs, Enum) { var ImportFormat = function() { - Enum.call(this, ["XLS"]); + Enum.call(this, ["EXCEL"]); } stjs.extend( diff --git a/api-openbis-javascript/src/v3/as/dto/importer/data/ImportValue.js b/api-openbis-javascript/src/v3/as/dto/importer/data/ImportValue.js deleted file mode 100644 index e8bddc19ddbc290d97453e38dded0705365fe526..0000000000000000000000000000000000000000 --- a/api-openbis-javascript/src/v3/as/dto/importer/data/ImportValue.js +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright ETH 2024 Zürich, Scientific IT Services - * - * 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. - * - */ - -define(["stjs"], - function (stjs) { - var ImportValue = function() { - } - - stjs.extend( - ImportValue, - null, - [], - function (constructor, prototype) { - prototype["@type"] = "as.dto.importer.data.ImportValue"; - - constructor.serialVersionUID = 1; - prototype.name = null; - prototype.value = null; - - prototype.getName = function() { - return this.name; - }; - - prototype.setName = function(name) { - this.name = name; - }; - - prototype.getValue = function() { - return this.value; - }; - - prototype.setValue = function(value) { - this.value = value; - }; - }, - {} - ); - - return ImportValue; - }); \ No newline at end of file diff --git a/api-openbis-javascript/src/v3/as/dto/importer/data/UncompressedImportData.js b/api-openbis-javascript/src/v3/as/dto/importer/data/UncompressedImportData.js deleted file mode 100644 index 49084d1b71cc60392c1ff59c3a47f06f3657bcb8..0000000000000000000000000000000000000000 --- a/api-openbis-javascript/src/v3/as/dto/importer/data/UncompressedImportData.js +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright ETH 2023 Zürich, Scientific IT Services - * - * 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. - * - */ - -define(["stjs", "as/dto/importer/data/IImportData"], - function (stjs, IImportData) { - var UncompressedImportData = function() { - } - - stjs.extend( - UncompressedImportData, - IImportData, - [IImportData], - function (constructor, prototype) { - prototype["@type"] = "as.dto.importer.data.UncompressedImportData"; - - constructor.serialVersionUID = 1; - prototype.format = null; - prototype.file = null; - prototype.scripts = null; - prototype.importValues = null; - - prototype.getFormat = function() { - return this.format; - }; - - prototype.setFormat = function(format) { - this.format = format; - }; - - prototype.getFile = function() { - return this.file; - }; - - prototype.setFile = function(file) { - this.file = file; - }; - - prototype.getScripts = function() { - return this.scripts; - }; - - prototype.setScripts = function(scripts) { - this.scripts = scripts; - }; - - prototype.getImportValues = function() { - return this.importValues; - }; - - prototype.setImportValues = function(importValues) { - this.importValues = importValues; - }; - }, - { - format: "ImportFormat", - file: "byte[]", - scripts: { - name: "Collection", - arguments: ["ImportScript"] - }, - importValues: { - name: "Collection", - arguments: ["ImportValue"] - } - } - ); - - return UncompressedImportData; - }); \ No newline at end of file diff --git a/api-openbis-javascript/src/v3/openbis.js b/api-openbis-javascript/src/v3/openbis.js index f7a8d669586eb261f939331da483b19ba15f9469..a5c1a6be3fdc922f885e489e1ce466a5655f0d51 100644 --- a/api-openbis-javascript/src/v3/openbis.js +++ b/api-openbis-javascript/src/v3/openbis.js @@ -2728,6 +2728,34 @@ define([ 'jquery', 'util/Json', 'as/dto/datastore/search/DataStoreSearchCriteria }) } + this.uploadToSessionWorkspace = function(file) { + //Building Form Data Object for Multipart File Upload + var formData = new FormData(); + formData.append("sessionKeysNumber", "1"); + formData.append("sessionKey_0", "openbis-file-upload"); + formData.append("openbis-file-upload", file); + formData.append("keepOriginalFileName", "True"); + formData.append("sessionID", this._private.sessionToken); + + var dfd = jquery.Deferred(); + + jquery.ajax({ + type: "POST", + url: "/openbis/openbis/upload", + contentType: false, + processData: false, + data: formData, + success: function() { + dfd.resolve(); + }, + error: function() { + dfd.reject(); + } + }); + + return dfd.promise(); + } + /** * ======================= * OpenBIS webapp context diff --git a/api-openbis-typescript/source/java/ch/ethz/sis/openbis/generic/typescript/dto/OpenBISJavaScriptFacade.java b/api-openbis-typescript/source/java/ch/ethz/sis/openbis/generic/typescript/dto/OpenBISJavaScriptFacade.java index cb1cb28377795d66cf6b5f7992296c72e2738e45..c55846a1f9fde3aebeb570d293bea8779f16dd8e 100644 --- a/api-openbis-typescript/source/java/ch/ethz/sis/openbis/generic/typescript/dto/OpenBISJavaScriptFacade.java +++ b/api-openbis-typescript/source/java/ch/ethz/sis/openbis/generic/typescript/dto/OpenBISJavaScriptFacade.java @@ -75,7 +75,8 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.externaldms.update.ExternalDmsUp import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.GlobalSearchObject; import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.fetchoptions.GlobalSearchObjectFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.search.GlobalSearchCriteria; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.IImportData; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportResult; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportData; import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.Material; import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.MaterialType; @@ -1322,9 +1323,9 @@ public class OpenBISJavaScriptFacade implements IApplicationServerApi } @TypeScriptMethod - @Override public void executeImport(final String sessionToken, final IImportData importData, final ImportOptions importOptions) + @Override public ImportResult executeImport(final String sessionToken, final ImportData importData, final ImportOptions importOptions) { - + return null; } @TypeScriptMethod @@ -1333,6 +1334,11 @@ public class OpenBISJavaScriptFacade implements IApplicationServerApi return null; } + @TypeScriptMethod(sessionToken = false) + public void uploadToSessionWorkspace(final Object file) + { + } + @TypeScriptMethod(sessionToken = false) @Override public int getMajorVersion() { diff --git a/core-plugin-openbis/.dynamic_property_evaluator_queue b/core-plugin-openbis/.dynamic_property_evaluator_queue deleted file mode 100644 index 2e08dce276e43c677d121d627a250d1710fed824..0000000000000000000000000000000000000000 Binary files a/core-plugin-openbis/.dynamic_property_evaluator_queue and /dev/null differ diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/AbstractImportTest.java b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/AbstractImportTest.java index 69708ddf23d89fd553aaf7281023c434a8e05b94..42c27477f7a1f22381655cc8e63bb66905b6532e 100644 --- a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/AbstractImportTest.java +++ b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/AbstractImportTest.java @@ -16,6 +16,9 @@ package ch.ethz.sis.openbis.systemtest.plugin.excelimport; import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.UUID; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.testng.AbstractTransactionalTestNGSpringContextTests; @@ -24,8 +27,10 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.BeforeSuite; import ch.ethz.sis.openbis.generic.server.asapi.v3.IApplicationServerInternalApi; +import ch.systemsx.cisd.openbis.generic.server.CommonServiceProvider; import ch.systemsx.cisd.openbis.generic.server.util.TestInitializer; import ch.systemsx.cisd.openbis.generic.shared.Constants; +import ch.systemsx.cisd.openbis.generic.shared.ISessionWorkspaceProvider; import ch.systemsx.cisd.openbis.generic.shared.coreplugin.CorePluginsUtils; public class AbstractImportTest extends AbstractTransactionalTestNGSpringContextTests @@ -41,6 +46,10 @@ public class AbstractImportTest extends AbstractTransactionalTestNGSpringContext protected static final String PASSWORD = "password"; + protected static final String VALIDATION_SCRIPT = "full/scripts/valid.py"; + + protected static final String DYNAMIC_SCRIPT = "full/scripts/dynamic/dynamic.py"; + @Autowired protected IApplicationServerInternalApi v3api; @@ -54,6 +63,7 @@ public class AbstractImportTest extends AbstractTransactionalTestNGSpringContext System.setProperty(XLS_VERSIONING_DIR, VERSIONING_JSON); System.setProperty(CorePluginsUtils.CORE_PLUGINS_FOLDER_KEY, "dist/core-plugins"); System.setProperty(Constants.ENABLED_MODULES_KEY, "xls-import"); + System.setProperty(Constants.PROJECT_SAMPLES_ENABLED_KEY, "false"); TestInitializer.initEmptyDbNoIndex(); } @@ -71,4 +81,31 @@ public class AbstractImportTest extends AbstractTransactionalTestNGSpringContext v3api.logout(sessionToken); } + protected static String uploadToAsSessionWorkspace(final String sessionToken, final String filePath) throws IOException + { + final ISessionWorkspaceProvider sessionWorkspaceProvider = CommonServiceProvider.getSessionWorkspaceProvider(); + final String destination = UUID.randomUUID() + "/" + new File(filePath).getName(); + + sessionWorkspaceProvider.write(sessionToken, destination, new FileInputStream("sourceTest/java/" + filePath)); + + return destination; + } + + protected static String[] uploadToAsSessionWorkspace(final String sessionToken, final String... filePaths) throws IOException + { + final ISessionWorkspaceProvider sessionWorkspaceProvider = CommonServiceProvider.getSessionWorkspaceProvider(); + final UUID uploadId = UUID.randomUUID(); + + final String[] destinations = new String[filePaths.length]; + for (int i = 0; i < filePaths.length; i++) + { + destinations[i] = uploadId + + (filePaths[i].toLowerCase().endsWith(".xls") || filePaths[i].toLowerCase().endsWith(".xlsx") ? "/" : "/scripts/") + + new File(filePaths[i]).getName(); + sessionWorkspaceProvider.write(sessionToken, destinations[i], new FileInputStream("sourceTest/java/" + filePaths[i])); + } + + return destinations; + } + } diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportDatasetTypesTest.java b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportDatasetTypesTest.java index 1a13a1028e60b5f4765d916cbe7db1cf80f38315..bf607e4745614b3ce160f5beeade93dac21b4ba8 100644 --- a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportDatasetTypesTest.java +++ b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportDatasetTypesTest.java @@ -70,13 +70,16 @@ public class ImportDatasetTypesTest extends AbstractImportTest sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, DATASET_TYPES_XLS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, DATASET_TYPES_XLS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN DataSetType rawData = TestUtils.getDatasetType(v3api, sessionToken, "RAW_DATA"); List<String> propertyNames = Arrays.asList("$NAME", "NOTES"); List<PropertyAssignment> propertyAssignments = TestUtils.extractAndSortPropertyAssignmentsPerGivenPropertyName(rawData, propertyNames); PropertyAssignment nameProperty = propertyAssignments.get(0); PropertyAssignment notesProperty = propertyAssignments.get(1); + // THEN assertEquals(rawData.getCode(), "RAW_DATA"); assertEquals(rawData.getPropertyAssignments().size(), 2); @@ -101,9 +104,12 @@ public class ImportDatasetTypesTest extends AbstractImportTest public void testDatasetTypesWithoutPropertiesTypesAreCreated() throws IOException { // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, DATASET_WITHOUT_PROPERTIES))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, DATASET_WITHOUT_PROPERTIES)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN DataSetType rawData = TestUtils.getDatasetType(v3api, sessionToken, "RAW_DATA"); + // THEN assertEquals(rawData.getCode(), "RAW_DATA"); assertEquals(rawData.getPropertyAssignments().size(), 0); @@ -114,10 +120,13 @@ public class ImportDatasetTypesTest extends AbstractImportTest public void testDatasetTypesWithValidationScript() throws Exception { // GIVEN - TestUtils.createFrom(v3api, sessionToken, TestUtils.getValidationPluginMap(), - Paths.get(FilenameUtils.concat(FILES_DIR, DATASET_WITH_VALIDATION_SCRIPT))); + final String[] sessionWorkspaceFilePaths = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, DATASET_WITH_VALIDATION_SCRIPT), FilenameUtils.concat(FILES_DIR, VALIDATION_SCRIPT)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePaths[0])); + // WHEN DataSetType rawData = TestUtils.getDatasetType(v3api, sessionToken, "RAW_DATA"); + // THEN assertEquals(rawData.getValidationPlugin().getName().toUpperCase(), "RAW_DATA.VALID"); } @@ -130,15 +139,19 @@ public class ImportDatasetTypesTest extends AbstractImportTest sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, DATASET_TYPES_XLS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, DATASET_TYPES_XLS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN - TestUtils.createFrom(v3api, sessionToken, TestUtils.getDynamicPluginMap(), UpdateMode.UPDATE_IF_EXISTS, - Paths.get(FilenameUtils.concat(FILES_DIR, DATASET_TYPES_UPDATE))); + final String[] sessionWorkspaceFilePaths = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, DATASET_TYPES_UPDATE), FilenameUtils.concat(FILES_DIR, DYNAMIC_SCRIPT)); + TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(sessionWorkspaceFilePaths[0])); DataSetType rawData = TestUtils.getDatasetType(v3api, sessionToken, "RAW_DATA"); List<String> propertyNames = Arrays.asList("$NAME", "NOTES"); List<PropertyAssignment> propertyAssignments = TestUtils.extractAndSortPropertyAssignmentsPerGivenPropertyName(rawData, propertyNames); PropertyAssignment nameProperty = propertyAssignments.get(0); PropertyAssignment notesProperty = propertyAssignments.get(1); + // THEN // Property Assignment updates are not supported, no change here between updates. assertTrue(nameProperty.isMandatory()); @@ -157,10 +170,11 @@ public class ImportDatasetTypesTest extends AbstractImportTest assertEquals(notesProperty.getPlugin(), null); } - @Test(expectedExceptions = UserFailureException.class) + @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "(?s).*Header should contain 'Code'.*") public void shouldThrowExceptionIfNoSampleCode() throws IOException { - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, DATASET_NO_CODE))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, DATASET_NO_CODE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); } } diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportExperimentTypesTest.java b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportExperimentTypesTest.java index f8f56716ddd3b2675eab3e22e5fc357ab82c6738..843e6c02e72f27794f013002bc82bdaf7bb71bb5 100644 --- a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportExperimentTypesTest.java +++ b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportExperimentTypesTest.java @@ -73,13 +73,16 @@ public class ImportExperimentTypesTest extends AbstractImportTest String sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPES_XLS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPES_XLS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN ExperimentType collection = TestUtils.getExperimentType(v3api, sessionToken, "COLLECTION"); List<String> propertyNames = Arrays.asList("$NAME", "DEFAULT_OBJECT_TYPE"); List<PropertyAssignment> propertyAssignments = TestUtils.extractAndSortPropertyAssignmentsPerGivenPropertyName(collection, propertyNames); PropertyAssignment nameProperty = propertyAssignments.get(0); PropertyAssignment defaultObjectTypeProperty = propertyAssignments.get(1); + // THEN assertEquals(collection.getCode(), "COLLECTION"); assertEquals(collection.getPropertyAssignments().size(), 2); @@ -108,15 +111,19 @@ public class ImportExperimentTypesTest extends AbstractImportTest String sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPES_XLS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPES_XLS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN - TestUtils.createFrom(v3api, sessionToken, TestUtils.getDynamicPluginMap(), UpdateMode.UPDATE_IF_EXISTS, - Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPES_UPDATE))); + final String[] updateSessionWorkspaceFilePaths = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPES_UPDATE), FilenameUtils.concat(FILES_DIR, DYNAMIC_SCRIPT)); + TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(updateSessionWorkspaceFilePaths[0])); ExperimentType collection = TestUtils.getExperimentType(v3api, sessionToken, "COLLECTION"); List<String> propertyNames = Arrays.asList("$NAME", "DEFAULT_OBJECT_TYPE"); List<PropertyAssignment> propertyAssignments = TestUtils.extractAndSortPropertyAssignmentsPerGivenPropertyName(collection, propertyNames); PropertyAssignment nameProperty = propertyAssignments.get(0); PropertyAssignment defaultObjectTypeProperty = propertyAssignments.get(1); + // THEN // Property Assignment updates are not supported, no change here between updates. assertTrue(nameProperty.isMandatory()); @@ -141,18 +148,22 @@ public class ImportExperimentTypesTest extends AbstractImportTest public void testExperimentTypesWithValidationScript() throws IOException { // GIVEN - TestUtils.createFrom(v3api, sessionToken, TestUtils.getValidationPluginMap(), - Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_WITH_VALIDATION_SCRIPT))); + final String[] sessionWorkspaceFilePaths = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, EXPERIMENT_WITH_VALIDATION_SCRIPT), FilenameUtils.concat(FILES_DIR, VALIDATION_SCRIPT)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePaths[0])); + // WHEN ExperimentType collection = TestUtils.getExperimentType(v3api, sessionToken, "COLLECTION"); + // THEN assertEquals(collection.getValidationPlugin().getName().toUpperCase(), "COLLECTION.VALID"); } - @Test(expectedExceptions = UserFailureException.class) + @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "(?s).*Mandatory field is missing or empty: Code.*") public void shouldThrowExceptionIfNoSampleCode() throws IOException { - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_NO_CODE))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, EXPERIMENT_NO_CODE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); } } diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportExperimentsTest.java b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportExperimentsTest.java index 742ed9ffbe57a62a5dcde02244b8be6a1fdbc1c5..ec529f6dcff09d55c73999459e0d3e03b5583c27 100644 --- a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportExperimentsTest.java +++ b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportExperimentsTest.java @@ -96,9 +96,12 @@ public class ImportExperimentsTest extends AbstractImportTest String sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_XLS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, EXPERIMENT_XLS)); + TestUtils.createFrom(v3api, sessionToken, UpdateMode.FAIL_IF_EXISTS, Paths.get(sessionWorkspaceFilePath)); + // WHEN Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE"); + // THEN assertEquals(experiment.getCode(), "TEST_EXPERIMENT"); assertEquals(experiment.getProject().getCode(), "TEST_PROJECT"); @@ -114,9 +117,12 @@ public class ImportExperimentsTest extends AbstractImportTest String sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_XLS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, EXPERIMENT_XLS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT2", "TEST_PROJECT", "TEST_SPACE"); + // THEN assertEquals(experiment.getCode(), "TEST_EXPERIMENT2"); assertEquals(experiment.getProject().getCode(), "TEST_PROJECT"); @@ -132,12 +138,23 @@ public class ImportExperimentsTest extends AbstractImportTest String sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE))); - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACE))); - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROJECT))); - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_ALL_ELSEWHERE))); + final String experimentTypeSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(experimentTypeSessionWorkspaceFilePath)); + + final String spaceSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(spaceSessionWorkspaceFilePath)); + + final String projectSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROJECT)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(projectSessionWorkspaceFilePath)); + + final String experimentsSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, EXPERIMENTS_ALL_ELSEWHERE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(experimentsSessionWorkspaceFilePath)); + // WHEN Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE"); + // THEN assertEquals(experiment.getCode(), "TEST_EXPERIMENT"); assertEquals(experiment.getProject().getCode(), "TEST_PROJECT"); @@ -153,12 +170,22 @@ public class ImportExperimentsTest extends AbstractImportTest String sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE))); - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACE))); - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROJECT))); - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_XLS))); + final String experimentTypeSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(experimentTypeSessionWorkspaceFilePath)); + + final String spaceSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(spaceSessionWorkspaceFilePath)); + + final String projectSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROJECT)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(projectSessionWorkspaceFilePath)); + + final String experimentsSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, EXPERIMENT_XLS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(experimentsSessionWorkspaceFilePath)); + // WHEN Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE"); + // THEN assertEquals(experiment.getCode(), "TEST_EXPERIMENT"); assertEquals(experiment.getProject().getCode(), "TEST_PROJECT"); @@ -166,20 +193,36 @@ public class ImportExperimentsTest extends AbstractImportTest assertEquals(experiment.getProperties().get("DEFAULT_OBJECT_TYPE"), "OBJECT_TYPE"); } - @Test(expectedExceptions = UserFailureException.class) + @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "(?s).*Experiment type COLLECTION not found.*") public void shouldThrowExceptionIfExperimentTypeDoesntExist() throws IOException { - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACE))); - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROJECT))); - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_ALL_ELSEWHERE))); + final String spaceSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(spaceSessionWorkspaceFilePath)); + + final String projectSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROJECT)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(projectSessionWorkspaceFilePath)); + + final String experimentsSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, EXPERIMENTS_ALL_ELSEWHERE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(experimentsSessionWorkspaceFilePath)); } - @Test(expectedExceptions = UserFailureException.class) + @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "(?s).*Entity \\[/TEST_SPACE/TEST_PROJECT\\] could not be found\\..*") public void shouldThrowExceptionIfProjectDoesntExist() throws IOException { - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE))); - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACE))); - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_ALL_ELSEWHERE))); + // the Excel contains internally property types which can be only manipulated by the system user + sessionToken = v3api.loginAsSystem(); + + final String experimentTypeSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(experimentTypeSessionWorkspaceFilePath)); + + final String spaceSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(spaceSessionWorkspaceFilePath)); + + final String experimentsSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, EXPERIMENTS_ALL_ELSEWHERE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(experimentsSessionWorkspaceFilePath)); } @Test @@ -190,10 +233,17 @@ public class ImportExperimentsTest extends AbstractImportTest String sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE))); - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_TYPE_ELSEWHERE))); + final String experimentTypeSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(experimentTypeSessionWorkspaceFilePath)); + + final String experimentsSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_TYPE_ELSEWHERE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(experimentsSessionWorkspaceFilePath)); + // WHEN Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE"); + // THEN assertEquals(experiment.getCode(), "TEST_EXPERIMENT"); assertEquals(experiment.getProject().getCode(), "TEST_PROJECT"); @@ -209,12 +259,23 @@ public class ImportExperimentsTest extends AbstractImportTest String sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE))); - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACE))); - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROJECT))); - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_TYPE_ELSEWHERE))); + final String experimentTypeSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(experimentTypeSessionWorkspaceFilePath)); + + final String spaceSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(spaceSessionWorkspaceFilePath)); + + final String projectSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROJECT)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(projectSessionWorkspaceFilePath)); + + final String experimentsSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_TYPE_ELSEWHERE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(experimentsSessionWorkspaceFilePath)); + // WHEN Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE"); + // THEN assertEquals(experiment.getCode(), "TEST_EXPERIMENT"); assertEquals(experiment.getProject().getCode(), "TEST_PROJECT"); @@ -225,7 +286,8 @@ public class ImportExperimentsTest extends AbstractImportTest @Test(expectedExceptions = UserFailureException.class) public void shouldThrowExceptionIfExperimentNoCode() throws IOException { - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_NO_CODE))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, EXPERIMENTS_NO_CODE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); } @Test @@ -236,9 +298,13 @@ public class ImportExperimentsTest extends AbstractImportTest String sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_NON_MANDATORY_PROPERTY_MISSING))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_NON_MANDATORY_PROPERTY_MISSING)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE"); + // THEN assertEquals(experiment.getCode(), "TEST_EXPERIMENT"); assertEquals(experiment.getProject().getCode(), "TEST_PROJECT"); @@ -249,7 +315,9 @@ public class ImportExperimentsTest extends AbstractImportTest @Test(expectedExceptions = RuntimeException.class) public void shouldThrowExceptionIfExperimentNoProject() throws IOException { - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_NO_PROJECT_ATTRIBUTE))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, EXPERIMENTS_NO_PROJECT_ATTRIBUTE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); } @Test @@ -260,11 +328,19 @@ public class ImportExperimentsTest extends AbstractImportTest String sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACE))); - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROJECT))); - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_SPACE_AND_PROJECT_ELSEWHERE))); + final String spaceSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(spaceSessionWorkspaceFilePath)); + + final String projectSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROJECT)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(projectSessionWorkspaceFilePath)); + + final String elsewhereWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_SPACE_AND_PROJECT_ELSEWHERE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(elsewhereWorkspaceFilePath)); + // WHEN Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE"); + // THEN assertEquals(experiment.getCode(), "TEST_EXPERIMENT"); assertEquals(experiment.getProject().getCode(), "TEST_PROJECT"); @@ -280,10 +356,16 @@ public class ImportExperimentsTest extends AbstractImportTest String sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACE))); - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_SPACE_ELSEWHERE))); + final String spaceSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(spaceSessionWorkspaceFilePath)); + + final String spaceElsewhereSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, EXPERIMENTS_SPACE_ELSEWHERE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(spaceElsewhereSessionWorkspaceFilePath)); + // WHEN Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE"); + // THEN assertEquals(experiment.getCode(), "TEST_EXPERIMENT"); assertEquals(experiment.getProject().getCode(), "TEST_PROJECT"); @@ -299,11 +381,20 @@ public class ImportExperimentsTest extends AbstractImportTest String sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE))); - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACE))); - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_TYPE_AND_SPACE_ELSEWHERE))); + final String experimentTypeSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(experimentTypeSessionWorkspaceFilePath)); + + final String spaceSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(spaceSessionWorkspaceFilePath)); + + final String elsewhereSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_TYPE_AND_SPACE_ELSEWHERE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(elsewhereSessionWorkspaceFilePath)); + // WHEN Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE"); + // THEN assertEquals(experiment.getCode(), "TEST_EXPERIMENT"); assertEquals(experiment.getProject().getCode(), "TEST_PROJECT"); @@ -314,7 +405,9 @@ public class ImportExperimentsTest extends AbstractImportTest @Test(expectedExceptions = UserFailureException.class) public void shouldThrowExceptionIfMandatoryPropertyMissing() throws IOException { - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_MANDATORY_PROPERTY_MISSING))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_MANDATORY_PROPERTY_MISSING)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); } @Test @@ -325,9 +418,13 @@ public class ImportExperimentsTest extends AbstractImportTest String sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_MANDATORY_PROPERTY_PRESENT))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_MANDATORY_PROPERTY_PRESENT)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE"); + // THEN assertEquals(experiment.getCode(), "TEST_EXPERIMENT"); assertEquals(experiment.getProject().getCode(), "TEST_PROJECT"); @@ -343,9 +440,13 @@ public class ImportExperimentsTest extends AbstractImportTest String sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_PROPERTIES_COLUMNS_AS_LABELS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, EXPERIMENTS_PROPERTIES_COLUMNS_AS_LABELS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE"); + // THEN assertEquals(experiment.getCode(), "TEST_EXPERIMENT"); assertEquals(experiment.getProject().getCode(), "TEST_PROJECT"); @@ -361,11 +462,17 @@ public class ImportExperimentsTest extends AbstractImportTest String sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE))); - TestUtils.createFrom(v3api, sessionToken, - Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_PROPERTIES_COLUMNS_AS_LABELS_TYPE_ON_SERVER))); + final String experimentTypeSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(experimentTypeSessionWorkspaceFilePath)); + + final String elsewhereSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, EXPERIMENTS_PROPERTIES_COLUMNS_AS_LABELS_TYPE_ON_SERVER)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(elsewhereSessionWorkspaceFilePath)); + // WHEN Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE"); + // THEN assertEquals(experiment.getCode(), "TEST_EXPERIMENT"); assertEquals(experiment.getProject().getCode(), "TEST_PROJECT"); @@ -373,19 +480,26 @@ public class ImportExperimentsTest extends AbstractImportTest assertEquals(experiment.getProperties().get("DEFAULT_OBJECT_TYPE"), "OBJECT_TYPE"); } -// @Test -// @DirtiesContext -// public void testExperimentsUpdate() throws Exception -// { -// // GIVEN -// TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_XLS))); -// // WHEN -// TestUtils.createFrom(v3api, sessionToken, TestUtils.getDynamicPluginMap(), UpdateMode.UPDATE_IF_EXISTS, -// Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_UPDATE))); -// Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE"); -// // THEN -// assertEquals(experiment.getProperties().get("$NAME"), "NameUpdate"); -// assertEquals(experiment.getProperties().get("DEFAULT_OBJECT_TYPE"), "DefaultObjectTypeUpdate"); -// } + @Test + @DirtiesContext + public void testExperimentsUpdate() throws Exception + { + // the Excel contains internally managed property types which can be only manipulated by the system user + String sessionToken = v3api.loginAsSystem(); + + // GIVEN + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, EXPERIMENT_XLS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + + // WHEN + final String[] updateSessionWorkspaceFilePaths = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, EXPERIMENT_UPDATE), FilenameUtils.concat(FILES_DIR, DYNAMIC_SCRIPT)); + TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(updateSessionWorkspaceFilePaths[0])); + Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE"); + + // THEN + assertEquals(experiment.getProperties().get("$NAME"), "NameUpdate"); + assertEquals(experiment.getProperties().get("DEFAULT_OBJECT_TYPE"), "DefaultObjectTypeUpdate"); + } } diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportFromExcelTest.java b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportFromExcelTest.java index 46549e079efda295eecd5a620564f51efba59ce7..758adcb28d77a380d399b824e5d849edcf571716 100644 --- a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportFromExcelTest.java +++ b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportFromExcelTest.java @@ -21,7 +21,6 @@ import static org.testng.Assert.assertNotNull; import java.io.IOException; import java.nio.file.Paths; -import ch.systemsx.cisd.common.exceptions.UserFailureException; import org.apache.commons.io.FilenameUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.DirtiesContext; @@ -34,6 +33,7 @@ import org.testng.annotations.Test; import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.ExperimentType; import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.Sample; import ch.ethz.sis.openbis.generic.server.asapi.v3.IApplicationServerInternalApi; +import ch.systemsx.cisd.common.exceptions.UserFailureException; @ContextConfiguration(locations = "classpath:applicationContext.xml") @Transactional(transactionManager = "transaction-manager") @@ -53,21 +53,23 @@ public class ImportFromExcelTest extends AbstractImportTest FILES_DIR = f.substring(0, f.length() - ImportExperimentTypesTest.class.getSimpleName().length()) + "/test_files/"; } - @Test(expectedExceptions = UserFailureException.class) + @Test(expectedExceptions = UserFailureException.class, + expectedExceptionsMessageRegExp = "(?s).*Content found after a double blank row that should mark the end of a page\\..*") @DirtiesContext public void testFileWithManyBlankRowsWasParsed() throws Exception { // the Excel contains internally managed property types which can be only manipulated by the system user sessionToken = v3api.loginAsSystem(); - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, WITH_BLANKS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, WITH_BLANKS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); ExperimentType propertyType = TestUtils.getExperimentType(v3api, sessionToken, "COLLECTION"); assertNotNull(propertyType); // the last line on the first sheet was read assertEquals(propertyType.getPropertyAssignments().size(), 2); assertEquals(propertyType.getPropertyAssignments().get(1).getPropertyType().getCode(), "LAST_ROW_EXP_TYPE"); - Sample sample = TestUtils.getSample(v3api, sessionToken, "LAST_SAMPLE", "TEST_SPACE"); + Sample sample = TestUtils.getSample(v3api, sessionToken, "TEST_SPACE", "LAST_SAMPLE"); assertNotNull(sample); // the last line on the second sheet was read } } \ No newline at end of file diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportProjectsTest.java b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportProjectsTest.java index 0c827f35dd518bf89b739e9b8b597cfcc7af136c..01aa8bc54627e88ac3d4ba001632bcccb77aaac5 100644 --- a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportProjectsTest.java +++ b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportProjectsTest.java @@ -69,9 +69,12 @@ public class ImportProjectsTest extends AbstractImportTest public void testProjectsAreCreated() throws IOException { // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROJECTS_XLS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROJECTS_XLS)); + TestUtils.createFrom(v3api, sessionToken, UpdateMode.FAIL_IF_EXISTS, Paths.get(sessionWorkspaceFilePath)); + // WHEN Project project = TestUtils.getProject(v3api, sessionToken, "TEST_PROJECT"); + // THEN assertEquals(project.getCode(), "TEST_PROJECT"); assertEquals(project.getDescription(), "TEST"); @@ -83,10 +86,14 @@ public class ImportProjectsTest extends AbstractImportTest public void testExistProjectIsUpdated() throws IOException { // GIVEN - TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(FilenameUtils.concat(FILES_DIR, PROJECTS_XLS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROJECTS_XLS)); + TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(sessionWorkspaceFilePath)); + // WHEN - TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(FilenameUtils.concat(FILES_DIR, PROJECTS_UPDATE))); + final String updateSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROJECTS_UPDATE)); + TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(updateSessionWorkspaceFilePath)); Project project = TestUtils.getProject(v3api, sessionToken, "TEST_PROJECT", "TEST_SPACE2"); + // THEN assertEquals(project.getCode(), "TEST_PROJECT"); assertEquals(project.getDescription(), "UPDATE"); @@ -98,19 +105,23 @@ public class ImportProjectsTest extends AbstractImportTest public void testProjectsAreCreatedSecondProject() throws IOException { // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROJECTS_XLS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROJECTS_XLS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN Project project = TestUtils.getProject(v3api, sessionToken, "TEST_PROJECT2"); + // THEN assertEquals(project.getCode(), "TEST_PROJECT2"); assertEquals(project.getDescription(), "description of another project"); assertEquals(project.getSpace().getCode(), "TEST_SPACE2"); } - @Test(expectedExceptions = UserFailureException.class) + @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "(?s).*Header 'Code' is missing.*") public void shouldThrowExceptionIfNoProjectCode() throws IOException { - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROJECTS_NO_CODE))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROJECTS_NO_CODE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); } @Test @@ -118,19 +129,23 @@ public class ImportProjectsTest extends AbstractImportTest public void testProjectsAreCreatedNoDescription() throws IOException { // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROJECTS_NO_DESCRIPTION))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROJECTS_NO_DESCRIPTION)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN Project project = TestUtils.getProject(v3api, sessionToken, "TEST_PROJECT"); + // THEN assertEquals(project.getCode(), "TEST_PROJECT"); assertEquals(project.getDescription(), null); assertEquals(project.getSpace().getCode(), "TEST_SPACE"); } - @Test(expectedExceptions = UserFailureException.class) + @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "(?s).*Header 'Space' is missing.*") public void shouldThrowExceptionIfNoProjectSpace() throws IOException { - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROJECTS_NO_SPACE))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROJECTS_NO_SPACE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); } @Test @@ -138,10 +153,16 @@ public class ImportProjectsTest extends AbstractImportTest public void testProjectsAreCreatedSpaceOnServer() throws IOException { // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACES))); - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROJECTS_WITH_SPACES_ON_SERVER))); + final String spaceSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACES)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(spaceSessionWorkspaceFilePath)); + + final String projectsSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, PROJECTS_WITH_SPACES_ON_SERVER)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(projectsSessionWorkspaceFilePath)); + // WHEN Project project = TestUtils.getProject(v3api, sessionToken, "TEST_PROJECT"); + // THEN assertEquals(project.getCode(), "TEST_PROJECT"); assertEquals(project.getDescription(), "TEST"); diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportPropertyTypesTest.java b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportPropertyTypesTest.java index b7963f77f1f69bfd27dd3d963b44d5a45c7e284d..fc35b51fa4bd6757a89be8d1897184d67303dd54 100644 --- a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportPropertyTypesTest.java +++ b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportPropertyTypesTest.java @@ -17,6 +17,7 @@ package ch.ethz.sis.openbis.systemtest.plugin.excelimport; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNull; import static org.testng.Assert.assertTrue; @@ -25,7 +26,6 @@ import java.nio.file.Paths; import java.util.Arrays; import org.apache.commons.io.FilenameUtils; -import org.python27.core.PyException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.Rollback; @@ -50,6 +50,7 @@ public class ImportPropertyTypesTest extends AbstractImportTest private IApplicationServerInternalApi v3api; private static final String PROPERTY_TYPES_XLS = "property_types/normal_property_type.xls"; + private static final String PROPERTY_TYPES_WITH_PATTERN_XLS = "property_types/normal_property_type_with_pattern.xls"; private static final String PROPERTY_NO_CODE = "property_types/no_code.xls"; @@ -74,7 +75,7 @@ public class ImportPropertyTypesTest extends AbstractImportTest public void setupClass() throws IOException { String f = ImportPropertyTypesTest.class.getName().replace(".", "/"); - FILES_DIR = f.substring(0, f.length() - ImportPropertyTypesTest.class.getSimpleName().length()) + "/test_files/"; + FILES_DIR = f.substring(0, f.length() - ImportPropertyTypesTest.class.getSimpleName().length()) + "test_files/"; } @Test @@ -85,9 +86,12 @@ public class ImportPropertyTypesTest extends AbstractImportTest sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_XLS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_XLS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN PropertyType notes = TestUtils.getPropertyType(v3api, sessionToken, "NOTES"); + // THEN assertEquals(notes.getCode(), "NOTES"); assertEquals(notes.getLabel(), "Notes"); @@ -105,9 +109,13 @@ public class ImportPropertyTypesTest extends AbstractImportTest sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_WITH_PATTERN_XLS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_WITH_PATTERN_XLS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN PropertyType notes = TestUtils.getPropertyType(v3api, sessionToken, "PATTERN_PATTERN"); + // THEN assertEquals(notes.getCode(), "PATTERN_PATTERN"); assertEquals(notes.getLabel(), "Pattern"); @@ -127,9 +135,12 @@ public class ImportPropertyTypesTest extends AbstractImportTest sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_XLS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_XLS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN PropertyType notes = TestUtils.getPropertyType(v3api, sessionToken, "$INTERNAL_PROP"); + // THEN assertEquals(notes.getCode(), "$INTERNAL_PROP"); assertEquals(notes.getLabel(), "Name"); @@ -144,9 +155,13 @@ public class ImportPropertyTypesTest extends AbstractImportTest public void testDuplicatesPropertiesAreAllowedIfTheyAreTheSame() throws IOException { // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_DUPLICATES_SAME))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_DUPLICATES_SAME)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN PropertyType notes = TestUtils.getPropertyType(v3api, sessionToken, "NOTES"); + // THEN assertEquals(notes.getCode(), "NOTES"); assertEquals(notes.getLabel(), "Notes"); @@ -157,76 +172,96 @@ public class ImportPropertyTypesTest extends AbstractImportTest assertNull(notes.getVocabulary()); } - @Test(expectedExceptions = RuntimeException.class) + @Test(expectedExceptions = RuntimeException.class, expectedExceptionsMessageRegExp = "(?s).*Mandatory field is missing or empty: Code.*") public void testPropertyTypeNoCode() throws IOException { - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_NO_CODE))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROPERTY_NO_CODE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); } - @Test(expectedExceptions = UserFailureException.class) + @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "(?s).*Header 'Property label' is missing.*") public void testPropertyTypeNoLabel() throws IOException { - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_NO_LABEL))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROPERTY_NO_LABEL)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); } - @Test(expectedExceptions = UserFailureException.class) + @Test(expectedExceptions = UserFailureException.class, + expectedExceptionsMessageRegExp = "(?s).*Ambiguous property NOTES found, it has been declared before with different attributes.*") public void testPropertyTypesDuplicatesAreDifferent() throws IOException { - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_DUPLICATES_DIFFERENT))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, PROPERTY_DUPLICATES_DIFFERENT)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); } - @Test(expectedExceptions = RuntimeException.class) + @Test(expectedExceptions = RuntimeException.class, expectedExceptionsMessageRegExp = "(?s).*Header 'Vocabulary code' is missing.*") public void testPropertyTypeNoVocabularyCodeWhenVocabularyType() throws IOException { - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_VOCAB_TYPE_NO_VOCABULARY_CODE))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, PROPERTY_VOCAB_TYPE_NO_VOCABULARY_CODE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); } - @Test(expectedExceptions = RuntimeException.class) + @Test(expectedExceptions = RuntimeException.class, expectedExceptionsMessageRegExp = "(?s).*Header 'Data type' is missing.*") public void testPropertyTypeNoDataType() throws IOException { - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_NO_DATA_TYPE))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROPERTY_NO_DATA_TYPE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); } - @Test(expectedExceptions = UserFailureException.class) + @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "(?s).*Header 'Description' is missing.*") public void testPropertyTypeNoDescription() throws IOException { - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_NO_DESCRIPTION))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROPERTY_NO_DESCRIPTION)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); } - @Test(expectedExceptions = UserFailureException.class) + @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "(?s).*Entity \\[DETECTION\\] could not be found..*") public void testPropertyTypeVocabularyCodeToNonVocabularyType() throws IOException { - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_NON_VOCAB_TYPE_VOCABULARY_CODE))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, PROPERTY_NON_VOCAB_TYPE_VOCABULARY_CODE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); } - @Test(expectedExceptions = Exception.class) + @Test/*(expectedExceptions = Exception.class)*/ @DirtiesContext public void deleteProjectFromDBButNotFromJSON() throws IOException { - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_XLS))); + // the Excel contains internally property types which can be only manipulated by the system user + sessionToken = v3api.loginAsSystem(); + + final String sessionWorkspaceFilePath1 = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_XLS)); + TestUtils.createFrom(v3api, sessionToken, UpdateMode.FAIL_IF_EXISTS, Paths.get(sessionWorkspaceFilePath1)); PropertyType type = TestUtils.getPropertyType(v3api, sessionToken, "$INTERNAL_PROP"); + assertNotNull(type); PropertyTypeDeletionOptions deletionOptions = new PropertyTypeDeletionOptions(); deletionOptions.setReason("test"); v3api.deletePropertyTypes(sessionToken, Arrays.asList(type.getPermId()), deletionOptions); // After deleting one property, the exception is not thrown. // Because it can be deleted by the user an DB is fine. - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_XLS))); + final String sessionWorkspaceFilePath2 = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_XLS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath2)); // remove all data from DB type = TestUtils.getPropertyType(v3api, sessionToken, "$INTERNAL_PROP"); + assertNotNull(type); deletionOptions = new PropertyTypeDeletionOptions(); deletionOptions.setReason("test"); v3api.deletePropertyTypes(sessionToken, Arrays.asList(type.getPermId()), deletionOptions); type = TestUtils.getPropertyType(v3api, sessionToken, "NOTES"); + assertNotNull(type); deletionOptions = new PropertyTypeDeletionOptions(); deletionOptions.setReason("test"); v3api.deletePropertyTypes(sessionToken, Arrays.asList(type.getPermId()), deletionOptions); // exception should be thrown because DB is empty. - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_XLS))); + final String sessionWorkspaceFilePath3 = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_XLS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath3)); } } diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportSampleTypesTest.java b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportSampleTypesTest.java index 4f37c6bd3f32276f9816aed00373bca8400f0cbe..e2a4cf0ee6a3ac9bf5a6fc3df82480b12e4f17eb 100644 --- a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportSampleTypesTest.java +++ b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportSampleTypesTest.java @@ -72,7 +72,7 @@ public class ImportSampleTypesTest extends AbstractImportTest public void setupClass() throws IOException { String f = ImportSampleTypesTest.class.getName().replace(".", "/"); - FILES_DIR = f.substring(0, f.length() - ImportSampleTypesTest.class.getSimpleName().length()) + "/test_files/"; + FILES_DIR = f.substring(0, f.length() - ImportSampleTypesTest.class.getSimpleName().length()) + "test_files/"; } @Test @@ -83,9 +83,12 @@ public class ImportSampleTypesTest extends AbstractImportTest sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_XLS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_XLS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN SampleType antibody = TestUtils.getSampleType(v3api, sessionToken, "ANTIBODY"); + // THEN assertFalse(antibody.isAutoGeneratedCode()); } @@ -98,9 +101,12 @@ public class ImportSampleTypesTest extends AbstractImportTest sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_XLS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_XLS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN SampleType antibody = TestUtils.getSampleType(v3api, sessionToken, "ANTIBODY"); + // THEN boolean allMandatory = antibody.getPropertyAssignments().stream().allMatch(propAssignment -> propAssignment.isMandatory() == true); boolean allShownInEditView = @@ -125,9 +131,13 @@ public class ImportSampleTypesTest extends AbstractImportTest sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_XLS_DIFFERENT_PROPERTY_ASSIGN))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_XLS_DIFFERENT_PROPERTY_ASSIGN)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN SampleType antibody = TestUtils.getSampleType(v3api, sessionToken, "ANTIBODY"); + // THEN boolean allNotMandatory = antibody.getPropertyAssignments().stream().allMatch(propAssignment -> propAssignment.isMandatory() == false); boolean allNotShownInEditView = @@ -146,9 +156,12 @@ public class ImportSampleTypesTest extends AbstractImportTest sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_XLS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_XLS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN SampleType antibody = TestUtils.getSampleType(v3api, sessionToken, "ANTIBODY"); + // THEN boolean namePropertyExists = antibody.getPropertyAssignments().stream().anyMatch(propAssignment -> propAssignment.getPropertyType().getCode().equals("$NAME")); @@ -171,15 +184,18 @@ public class ImportSampleTypesTest extends AbstractImportTest sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, TestUtils.getDynamicPluginMap(), - Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_WITH_DYNAMIC_SCRIPT))); + final String[] sessionWorkspaceFilePaths = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_WITH_DYNAMIC_SCRIPT), FilenameUtils.concat(FILES_DIR, DYNAMIC_SCRIPT)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePaths[0])); + // WHEN SampleType antibody = TestUtils.getSampleType(v3api, sessionToken, "ANTIBODY"); + // THEN - Plugin dynamicScript = antibody.getPropertyAssignments().get(0).getPlugin(); + final Plugin dynamicScript = antibody.getPropertyAssignments().get(0).getPlugin(); assertNotNull(dynamicScript); assertEquals(dynamicScript.getName().toUpperCase(), "$NAME.DYNAMIC"); - assertEquals(dynamicScript.getScript(), TestUtils.getDynamicScript()); + assertEquals(dynamicScript.getScript(), "def calculate():\n return 1"); assertEquals(dynamicScript.getPluginType(), PluginType.DYNAMIC_PROPERTY); } @@ -188,15 +204,18 @@ public class ImportSampleTypesTest extends AbstractImportTest public void testSampleTypesWithPropertyHavingValidationScript() throws IOException { // GIVEN - TestUtils.createFrom(v3api, sessionToken, TestUtils.getValidationPluginMap(), - Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_WITH_VALIDATION_SCRIPT))); + final String[] sessionWorkspaceFilePaths = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_WITH_VALIDATION_SCRIPT), FilenameUtils.concat(FILES_DIR, VALIDATION_SCRIPT)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePaths[0])); + // WHEN SampleType antibody = TestUtils.getSampleType(v3api, sessionToken, "ANTIBODY"); + // THEN Plugin validationScript = antibody.getValidationPlugin(); assertNotNull(validationScript); assertEquals(validationScript.getName().toUpperCase(), "ANTIBODY.VALID"); - assertEquals(validationScript.getScript(), TestUtils.getValidationScript()); + assertEquals(validationScript.getScript(), "def validate(entity, isNew):\n if isNew:\n return"); assertEquals(validationScript.getPluginType(), PluginType.ENTITY_VALIDATION); } @@ -205,9 +224,13 @@ public class ImportSampleTypesTest extends AbstractImportTest public void testSampleTypesWithVocabularyInXls() throws IOException { // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_WITH_VOCABULARY))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_WITH_VOCABULARY)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN SampleType antibody = TestUtils.getSampleType(v3api, sessionToken, "ANTIBODY"); + // THEN PropertyAssignment propertyAssignment = antibody.getPropertyAssignments().get(0); assertNotNull(propertyAssignment); @@ -219,10 +242,17 @@ public class ImportSampleTypesTest extends AbstractImportTest public void testSampleTypesWithVocabularyOnServer() throws IOException { // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARY_DETECTION))); - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_WITH_VOCABULARY_ON_SERVER))); + final String vocabularySessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, VOCABULARY_DETECTION)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(vocabularySessionWorkspaceFilePath)); + + final String sampleTypesSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_WITH_VOCABULARY_ON_SERVER)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sampleTypesSessionWorkspaceFilePath)); + // WHEN SampleType antibody = TestUtils.getSampleType(v3api, sessionToken, "ANTIBODY"); + // THEN PropertyAssignment propertyAssignment = antibody.getPropertyAssignments().get(0); assertNotNull(propertyAssignment); @@ -234,17 +264,22 @@ public class ImportSampleTypesTest extends AbstractImportTest public void testSampleTypesWithAutoGeneratedCodeAttribute() throws IOException { // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_WITH_AUTO_GENERATED_CODES))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_WITH_AUTO_GENERATED_CODES)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN SampleType antibody = TestUtils.getSampleType(v3api, sessionToken, "SECONDBODY"); + // THEN assertTrue(antibody.isAutoGeneratedCode()); } - @Test(expectedExceptions = UserFailureException.class) + @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "(s?).*Mandatory field is missing or empty: Code.*") public void shouldThrowExceptionIfNoSampleCode() throws IOException { - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPE_NO_CODE))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SAMPLE_TYPE_NO_CODE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); } } diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportSamplesTest.java b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportSamplesTest.java index f92702dfa16db252c708a8ab8f0af6254aaaf19d..55567f48535513c4456921074ecd09a38dd45563 100644 --- a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportSamplesTest.java +++ b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportSamplesTest.java @@ -15,15 +15,15 @@ */ package ch.ethz.sis.openbis.systemtest.plugin.excelimport; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; + import java.io.IOException; import java.nio.file.Paths; import java.util.HashSet; import java.util.List; import java.util.Set; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.id.IObjectId; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.ISampleId; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.SampleIdentifier; import org.apache.commons.io.FilenameUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.DirtiesContext; @@ -33,15 +33,16 @@ import org.springframework.transaction.annotation.Transactional; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.id.IObjectId; import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.Experiment; import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.Project; import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.Sample; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.ISampleId; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.SampleIdentifier; import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.Space; import ch.ethz.sis.openbis.generic.server.asapi.v3.IApplicationServerInternalApi; import ch.systemsx.cisd.common.exceptions.UserFailureException; -import static org.testng.Assert.*; - @ContextConfiguration(locations = "classpath:applicationContext.xml") @Transactional(transactionManager = "transaction-manager") @Rollback @@ -109,9 +110,12 @@ public class ImportSamplesTest extends AbstractImportTest sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLES_XLS))); + final String sessionWorkspaceFile = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SAMPLES_XLS)); + TestUtils.createFrom(v3api, sessionToken, UpdateMode.FAIL_IF_EXISTS, Paths.get(sessionWorkspaceFile)); + // WHEN - Sample sample = TestUtils.getSample(v3api, sessionToken, "AAA", "TEST_SPACE"); + Sample sample = TestUtils.getSample(v3api, sessionToken, "TEST_SPACE", "AAA"); + // THEN assertEquals(sample.getCode(), "AAA"); assertEquals(sample.getProject(), null); @@ -127,9 +131,10 @@ public class ImportSamplesTest extends AbstractImportTest sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLES_XLS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SAMPLES_XLS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); // WHEN - Sample sample = TestUtils.getSample(v3api, sessionToken, "VVV", "TEST_SPACE"); + Sample sample = TestUtils.getSample(v3api, sessionToken, "TEST_SPACE", "VVV"); // THEN assertEquals(sample.getCode(), "VVV"); assertEquals(sample.getProject(), null); @@ -145,9 +150,10 @@ public class ImportSamplesTest extends AbstractImportTest sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLES_XLS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SAMPLES_XLS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); // WHEN - Sample sample = TestUtils.getSample(v3api, sessionToken, "S1", "TEST_SPACE"); + Sample sample = TestUtils.getSample(v3api, sessionToken, "TEST_SPACE", "S1"); // THEN assertEquals(sample.getCode(), "S1"); assertEquals(sample.getProject(), null); @@ -163,10 +169,13 @@ public class ImportSamplesTest extends AbstractImportTest String sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACE))); - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLES_SPACE_ELSEWHERE))); + final String sessionWorkspaceFilePathForSpace = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePathForSpace)); + final String sessionWorkspaceFilePathForSamplesSpaceElsewhere = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, SAMPLES_SPACE_ELSEWHERE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePathForSamplesSpaceElsewhere)); // WHEN - Sample sample = TestUtils.getSample(v3api, sessionToken, "VVV", "TEST_SPACE"); + Sample sample = TestUtils.getSample(v3api, sessionToken, "TEST_SPACE", "VVV"); // THEN assertNotNull(sample); } @@ -179,19 +188,28 @@ public class ImportSamplesTest extends AbstractImportTest String sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, - Paths.get(FilenameUtils.concat(FILES_DIR, SPACE)), - Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLES_SPACE_ELSEWHERE))); + final String sessionWorkspaceFilePathForSpace = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACE)); + final String sessionWorkspaceFilePathForSamplesSpaceElsewhere = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, SAMPLES_SPACE_ELSEWHERE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePathForSpace), + Paths.get(sessionWorkspaceFilePathForSamplesSpaceElsewhere)); // WHEN - Sample sample = TestUtils.getSample(v3api, sessionToken, "VVV", "TEST_SPACE"); + Sample sample = TestUtils.getSample(v3api, sessionToken, "TEST_SPACE", "VVV"); // THEN assertNotNull(sample); } - @Test(expectedExceptions = UserFailureException.class) + @Test(expectedExceptions = UserFailureException.class, + expectedExceptionsMessageRegExp = "(s?).*Entity \\[TEST_SPACE\\] could not be found. " + + "Either you forgot to register it or mistyped the identifier.*") public void shouldThrowExceptionIfSpaceDoesntExist() throws IOException { - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLES_SPACE_ELSEWHERE))); + // the Excel contains internally property types which can be only manipulated by the system user + sessionToken = v3api.loginAsSystem(); + + final String sessionWorkspaceFilePathForSamplesSpaceElsewhere = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, SAMPLES_SPACE_ELSEWHERE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePathForSamplesSpaceElsewhere)); } @Test @@ -202,10 +220,17 @@ public class ImportSamplesTest extends AbstractImportTest String sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, - Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARY_TYPE)), - Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPE_CYCLIC))); - List<IObjectId> ids = TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLES_SAMPLE_TYPE_ELSWHERE_CYCLIC))); + final String sessionWorkspaceFilePathForVocabularyType = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, VOCABULARY_TYPE)); + final String sessionWorkspaceFilePathForSampleType = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, SAMPLE_TYPE_CYCLIC)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePathForVocabularyType), + Paths.get(sessionWorkspaceFilePathForSampleType)); + + final String sessionWorkspaceFilePathForSampleTypeElsewhere = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, SAMPLES_SAMPLE_TYPE_ELSWHERE_CYCLIC)); + List<IObjectId> ids = TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, + Paths.get(sessionWorkspaceFilePathForSampleTypeElsewhere)); List<ISampleId> sampleIds = List.of((SampleIdentifier)ids.get(9), (SampleIdentifier)ids.get(10), (SampleIdentifier)ids.get(11)); // WHEN List<Sample> samples = (List<Sample>) TestUtils.getSamplesById(v3api, sessionToken, sampleIds); @@ -226,13 +251,22 @@ public class ImportSamplesTest extends AbstractImportTest String sessionToken = v3api.loginAsSystem(); // GIVEN + final String sessionWorkspaceFilePathForVocabularyType = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, VOCABULARY_TYPE)); + final String sessionWorkspaceFilePathForSampleType = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, SAMPLE_TYPE_CYCLIC_FIX_TYPE)); + TestUtils.createFrom(v3api, sessionToken, - Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARY_TYPE)), - Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPE_CYCLIC_FIX_TYPE))); - List<IObjectId> ids = TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLES_SAMPLE_TYPE_ELSWHERE_CYCLIC))); + Paths.get(sessionWorkspaceFilePathForVocabularyType), + Paths.get(sessionWorkspaceFilePathForSampleType)); + + final String sessionWorkspaceFilePathForSampleTypeElsewhere = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, SAMPLES_SAMPLE_TYPE_ELSWHERE_CYCLIC)); + List<IObjectId> ids = TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, + Paths.get(sessionWorkspaceFilePathForSampleTypeElsewhere)); List<ISampleId> sampleIds = List.of((SampleIdentifier)ids.get(9), (SampleIdentifier)ids.get(10), (SampleIdentifier)ids.get(11)); // WHEN - List<Sample> samples = (List<Sample>) TestUtils.getSamplesById(v3api, sessionToken, sampleIds); + List<Sample> samples = TestUtils.getSamplesById(v3api, sessionToken, sampleIds); Set<String> differentCyclicAssignments = new HashSet<>(); for (Sample sample:samples) { differentCyclicAssignments.add((String)sample.getProperty("CYCLIC_SAMPLE_PROPERTY")); @@ -242,7 +276,8 @@ public class ImportSamplesTest extends AbstractImportTest assertEquals(differentCyclicAssignments.size(), 2); } - @Test(expectedExceptions = UserFailureException.class) + @Test(expectedExceptions = UserFailureException.class, + expectedExceptionsMessageRegExp = "(?s).*Property CYCLIC_SAMPLE_PROPERTY is not a sample of type ANTIBODY but of type TEST_TYPE.*") @DirtiesContext public void testSamplesAreCreatedWhenSampleTypeCyclicOnServerFixTypeWrongType() throws IOException { @@ -250,10 +285,18 @@ public class ImportSamplesTest extends AbstractImportTest String sessionToken = v3api.loginAsSystem(); // GIVEN + final String sessionWorkspaceFilePathForVocabularyType = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, VOCABULARY_TYPE)); + final String sessionWorkspaceFilePathForSampleType = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, SAMPLE_TYPE_CYCLIC_FIX_TYPE)); + TestUtils.createFrom(v3api, sessionToken, - Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARY_TYPE)), - Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPE_CYCLIC_FIX_TYPE))); - List<IObjectId> ids = TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLES_SAMPLE_TYPE_ELSWHERE_CYCLIC_WRONG_TYPE))); + Paths.get(sessionWorkspaceFilePathForVocabularyType), + Paths.get(sessionWorkspaceFilePathForSampleType)); + + final String sessionWorkspaceFilePathForSampleTypeElsewhere = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, SAMPLES_SAMPLE_TYPE_ELSWHERE_CYCLIC_WRONG_TYPE)); + TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(sessionWorkspaceFilePathForSampleTypeElsewhere)); } @Test @@ -264,12 +307,19 @@ public class ImportSamplesTest extends AbstractImportTest String sessionToken = v3api.loginAsSystem(); // GIVEN + final String sessionWorkspaceFilePathForVocabularyType = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, VOCABULARY_TYPE)); + final String sessionWorkspaceFilePathForSampleType = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, SAMPLE_TYPE)); TestUtils.createFrom(v3api, sessionToken, - Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARY_TYPE)), - Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPE))); - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLES_SAMPLE_TYPE_ELSWHERE))); + Paths.get(sessionWorkspaceFilePathForVocabularyType), + Paths.get(sessionWorkspaceFilePathForSampleType)); + + final String sessionWorkspaceFilePathForSampleTypeElsewhere = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, SAMPLES_SAMPLE_TYPE_ELSWHERE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePathForSampleTypeElsewhere)); // WHEN - Sample sample = TestUtils.getSample(v3api, sessionToken, "VVV", "TEST_SPACE"); + Sample sample = TestUtils.getSample(v3api, sessionToken, "TEST_SPACE", "VVV"); // THEN assertNotNull(sample); } @@ -282,11 +332,14 @@ public class ImportSamplesTest extends AbstractImportTest sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, - Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPE)), - Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLES_SAMPLE_TYPE_ELSWHERE))); + final String sessionWorkspaceFilePathForSampleType = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, SAMPLE_TYPE)); + final String sessionWorkspaceFilePathForSampleTypeElsewhere = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, SAMPLES_SAMPLE_TYPE_ELSWHERE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePathForSampleType), + Paths.get(sessionWorkspaceFilePathForSampleTypeElsewhere)); // WHEN - Sample sample = TestUtils.getSample(v3api, sessionToken, "VVV", "TEST_SPACE"); + Sample sample = TestUtils.getSample(v3api, sessionToken, "TEST_SPACE", "VVV"); // THEN assertNotNull(sample); } @@ -299,10 +352,10 @@ public class ImportSamplesTest extends AbstractImportTest String sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, - Paths.get(FilenameUtils.concat(FILES_DIR, CHILD_AS_IDENTIFIER))); + final String sessionWorkspaceFile = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, CHILD_AS_IDENTIFIER)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFile)); // WHEN - Sample sample = TestUtils.getSample(v3api, sessionToken, "VVV", "TEST_SPACE"); + Sample sample = TestUtils.getSample(v3api, sessionToken, "TEST_SPACE", "VVV"); // THEN assertNotNull(sample); assertEquals(sample.getChildren().size(), 1); @@ -319,10 +372,10 @@ public class ImportSamplesTest extends AbstractImportTest String sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, - Paths.get(FilenameUtils.concat(FILES_DIR, PARENT_AS_IDENTIFIER))); + final String sessionWorkspaceFile = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PARENT_AS_IDENTIFIER)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFile)); // WHEN - Sample sample = TestUtils.getSample(v3api, sessionToken, "VVV", "TEST_SPACE"); + Sample sample = TestUtils.getSample(v3api, sessionToken, "TEST_SPACE", "VVV"); // THEN assertNotNull(sample); assertEquals(sample.getParents().size(), 1); @@ -339,10 +392,10 @@ public class ImportSamplesTest extends AbstractImportTest String sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, - Paths.get(FilenameUtils.concat(FILES_DIR, CHILD_AS_DOLLARTAG))); + final String sessionWorkspaceFile = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, CHILD_AS_DOLLARTAG)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFile)); // WHEN - Sample sample = TestUtils.getSample(v3api, sessionToken, "VVV", "TEST_SPACE"); + Sample sample = TestUtils.getSample(v3api, sessionToken, "TEST_SPACE", "VVV"); // THEN assertNotNull(sample); assertEquals(sample.getChildren().size(), 1); @@ -359,10 +412,10 @@ public class ImportSamplesTest extends AbstractImportTest String sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, - Paths.get(FilenameUtils.concat(FILES_DIR, PARENT_AS_DOLLARTAG))); + final String sessionWorkspaceFile = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PARENT_AS_DOLLARTAG)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFile)); // WHEN - Sample sample = TestUtils.getSample(v3api, sessionToken, "VVV", "TEST_SPACE"); + Sample sample = TestUtils.getSample(v3api, sessionToken, "TEST_SPACE", "VVV"); // THEN assertNotNull(sample); assertEquals(sample.getParents().size(), 1); @@ -379,10 +432,10 @@ public class ImportSamplesTest extends AbstractImportTest sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, - Paths.get(FilenameUtils.concat(FILES_DIR, NON_MANDATORY_FIELD_MISSING))); + final String sessionWorkspaceFile = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, NON_MANDATORY_FIELD_MISSING)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFile)); // WHEN - Sample sample = TestUtils.getSample(v3api, sessionToken, "AAA", "TEST_SPACE"); + Sample sample = TestUtils.getSample(v3api, sessionToken, "TEST_SPACE", "AAA"); // THEN assertNotNull(sample); assertEquals(sample.getProperties().get("FOR_WHAT"), null); @@ -396,9 +449,9 @@ public class ImportSamplesTest extends AbstractImportTest sessionToken = v3api.loginAsSystem(); // GIVEN - - List<IObjectId> result = TestUtils.createFrom(v3api, sessionToken, UpdateMode.IGNORE_EXISTING, - Paths.get(FilenameUtils.concat(FILES_DIR, AUTO_GENERATED_SAMPLE_LEVEL))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, AUTO_GENERATED_SAMPLE_LEVEL)); + List<IObjectId> result = TestUtils.createFrom(v3api, sessionToken, UpdateMode.IGNORE_EXISTING, Paths.get(sessionWorkspaceFilePath)); String permId = result.get(result.size() - 1).toString(); // WHEN @@ -416,8 +469,9 @@ public class ImportSamplesTest extends AbstractImportTest sessionToken = v3api.loginAsSystem(); // GIVEN - List<IObjectId> result = TestUtils.createFrom(v3api, sessionToken, UpdateMode.IGNORE_EXISTING, - Paths.get(FilenameUtils.concat(FILES_DIR, AUTO_GENERATED_SAMPLE_TYPE_LEVEL))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, AUTO_GENERATED_SAMPLE_TYPE_LEVEL)); + List<IObjectId> result = TestUtils.createFrom(v3api, sessionToken, UpdateMode.IGNORE_EXISTING, Paths.get(sessionWorkspaceFilePath)); String permId = result.get(result.size() - 1).toString(); // WHEN @@ -434,10 +488,11 @@ public class ImportSamplesTest extends AbstractImportTest // the Excel contains internally managed property types which can be only manipulated by the system user sessionToken = v3api.loginAsSystem(); - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, GENERAL_ELN_SETTINGS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, GENERAL_ELN_SETTINGS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); // test sample before update - Sample sample = TestUtils.getSample(v3api, sessionToken, "GENERAL_ELN_SETTINGS", "ELN_SETTINGS"); + Sample sample = TestUtils.getSample(v3api, sessionToken, "ELN_SETTINGS", "GENERAL_ELN_SETTINGS"); assertNotNull(sample); // properties are empty assertEquals(sample.getProperties().size(), 0); @@ -456,11 +511,12 @@ public class ImportSamplesTest extends AbstractImportTest assertEquals(experiment.getProperties().containsKey("$NAME"), true); assertEquals(experiment.getProperties().get("$NAME"), "Default Experiment"); - TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, - Paths.get(FilenameUtils.concat(FILES_DIR, GENERAL_ELN_SETTINGS_UPDATE))); + final String sessionWorkspaceFilePathForUpdate = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, GENERAL_ELN_SETTINGS_UPDATE)); + TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(sessionWorkspaceFilePathForUpdate)); // test sample after update - sample = TestUtils.getSample(v3api, sessionToken, "GENERAL_ELN_SETTINGS", "ELN_SETTINGS"); + sample = TestUtils.getSample(v3api, sessionToken, "ELN_SETTINGS", "GENERAL_ELN_SETTINGS"); assertNotNull(sample); // properties have been updated assertEquals(sample.getProperties().size(), 1); @@ -483,16 +539,28 @@ public class ImportSamplesTest extends AbstractImportTest assertEquals(experiment.getProperties().get("$NAME"), "Default Experiment Updated"); } - @Test(expectedExceptions = UserFailureException.class) + @Test(expectedExceptions = UserFailureException.class, + expectedExceptionsMessageRegExp = "(s?).*Entity \\[TEST_SPACE, /TEST_SPACE/TEST_PROJECT/TEST_EXPERIMENT\\] could not be found. " + + "Either you forgot to register it or mistyped the identifier.*") public void shouldThrowExceptionIfSamplesSpaceProjectDoesntExist() throws IOException { - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLES_SPACE_PROJECT_EXPERIMENT_ELSEWHERE))); + // the Excel contains internally property types which can be only manipulated by the system user + sessionToken = v3api.loginAsSystem(); + + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, SAMPLES_SPACE_PROJECT_EXPERIMENT_ELSEWHERE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); } - @Test(expectedExceptions = UserFailureException.class) + @Test(expectedExceptions = UserFailureException.class, + expectedExceptionsMessageRegExp = "(s?).*Header 'name' is neither an attribute, property code or property label.*") public void shouldThrowExceptionIfMandatoryPropertyIsMissing() throws IOException { - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, MANDATORY_FIELD_MISSING))); + // the Excel contains internally property types which can be only manipulated by the system user + sessionToken = v3api.loginAsSystem(); + + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, MANDATORY_FIELD_MISSING)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); } } diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportSpacesTest.java b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportSpacesTest.java index 75fb6f688e44cb5cfcae88979eae971ef0099761..8024fecf89ea4ea66f6fb3c4adb9f5d117c7f4c9 100644 --- a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportSpacesTest.java +++ b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportSpacesTest.java @@ -53,7 +53,7 @@ public class ImportSpacesTest extends AbstractImportTest public void setupClass() throws IOException { String f = ImportSpacesTest.class.getName().replace(".", "/"); - FILES_DIR = f.substring(0, f.length() - ImportSpacesTest.class.getSimpleName().length()) + "/test_files/"; + FILES_DIR = f.substring(0, f.length() - ImportSpacesTest.class.getSimpleName().length()) + "test_files/"; } @Test @@ -61,7 +61,8 @@ public class ImportSpacesTest extends AbstractImportTest public void testNormalSpacesAreCreated() throws IOException { // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACES_XLS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACES_XLS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); // WHEN Space rawData = TestUtils.getSpace(v3api, sessionToken, "TEST_SPACE"); // THEN @@ -74,7 +75,8 @@ public class ImportSpacesTest extends AbstractImportTest public void testNormalSpacesAreCreatedSecondSpace() throws IOException { // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACES_XLS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACES_XLS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); // WHEN Space space = TestUtils.getSpace(v3api, sessionToken, "TEST_SPACE2"); // THEN @@ -82,17 +84,19 @@ public class ImportSpacesTest extends AbstractImportTest assertEquals(space.getDescription(), "TEST desc"); } - @Test(expectedExceptions = UserFailureException.class) + @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "(?s).*Header 'Code' is missing.*") public void shouldThrowExceptionIfNoSpaceCode() throws IOException { - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACES_NO_CODE))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACES_NO_CODE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); } - @Test(expectedExceptions = UserFailureException.class) + @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "(?s).*Header 'Description' is missing.*") @DirtiesContext public void shouldCreateSpaceWhenNoDescription() throws IOException { - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACES_NO_DESCRIPTION))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACES_NO_DESCRIPTION)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); } } diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportVocabularyTypesTest.java b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportVocabularyTypesTest.java index 3b10cf00fe995b4615240409319fd99900a47dd2..707d1ab1ef31ef2f4108f5594760b5a00770df8d 100644 --- a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportVocabularyTypesTest.java +++ b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportVocabularyTypesTest.java @@ -40,7 +40,6 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyTerm import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.fetchoptions.VocabularyFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.VocabularyPermId; import ch.ethz.sis.openbis.generic.server.asapi.v3.IApplicationServerInternalApi; -import ch.systemsx.cisd.common.exceptions.UserFailureException; @ContextConfiguration(locations = "classpath:applicationContext.xml") @Transactional(transactionManager = "transaction-manager") @@ -75,7 +74,7 @@ public class ImportVocabularyTypesTest extends AbstractImportTest public void setupClass() throws IOException { String f = ImportVocabularyTypesTest.class.getName().replace(".", "/"); - FILES_DIR = f.substring(0, f.length() - ImportVocabularyTypesTest.class.getSimpleName().length()) + "/test_files/"; + FILES_DIR = f.substring(0, f.length() - ImportVocabularyTypesTest.class.getSimpleName().length()) + "test_files/"; } @Test @@ -86,7 +85,8 @@ public class ImportVocabularyTypesTest extends AbstractImportTest sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARIES_TYPES_XLS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, VOCABULARIES_TYPES_XLS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); // WHEN Vocabulary detection = TestUtils.getVocabulary(v3api, sessionToken, "DETECTION"); // THEN @@ -102,9 +102,12 @@ public class ImportVocabularyTypesTest extends AbstractImportTest sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARIES_TYPES_XLS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, VOCABULARIES_TYPES_XLS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN Vocabulary detection = TestUtils.getVocabulary(v3api, sessionToken, "DETECTION"); + // THEN VocabularyTerm term = detection.getTerms().get(0); assertEquals(term.getCode(), "HRP"); @@ -120,9 +123,12 @@ public class ImportVocabularyTypesTest extends AbstractImportTest sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARIES_TYPES_XLS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, VOCABULARIES_TYPES_XLS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN List<Vocabulary> vocabularies = TestUtils.getAllVocabularies(v3api, sessionToken); + // THEN assertEquals(vocabularies.size(), 3); // 2 created + 1 default } @@ -135,9 +141,12 @@ public class ImportVocabularyTypesTest extends AbstractImportTest sessionToken = v3api.loginAsSystem(); // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARIES_TYPES_XLS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, VOCABULARIES_TYPES_XLS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN Vocabulary detection = TestUtils.getVocabulary(v3api, sessionToken, "DETECTION"); + // THEN VocabularyTerm term = detection.getTerms().get(1); assertEquals(term.getCode(), "TEST_VOC"); @@ -150,24 +159,30 @@ public class ImportVocabularyTypesTest extends AbstractImportTest public void testVocabularyWithNoTermDescriptionShouldBeCreated() throws IOException { // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARIES_NO_TERM_DESCRIPTION))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, VOCABULARIES_NO_TERM_DESCRIPTION)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN Vocabulary detection = TestUtils.getVocabulary(v3api, sessionToken, "DETECTION"); + // THEN assertNotNull(detection); assertNull(detection.getTerms().get(0).getDescription()); } - @Test(expectedExceptions = RuntimeException.class) + @Test(expectedExceptions = RuntimeException.class, expectedExceptionsMessageRegExp = "(s?).*Mandatory field is missing or empty: Code.*") public void shouldThrowExceptionIfNoVocabularyCode() throws IOException { - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARIES_NO_CODE))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, VOCABULARIES_NO_CODE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); } - @Test(expectedExceptions = RuntimeException.class) + @Test(expectedExceptions = RuntimeException.class, expectedExceptionsMessageRegExp = "(s?).*Mandatory field is missing or empty: Code.*") public void shouldThrowExceptionIfNoTermCode() throws IOException { - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARIES_NO_TERM_CODE))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, VOCABULARIES_NO_TERM_CODE)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); } @Test @@ -175,9 +190,13 @@ public class ImportVocabularyTypesTest extends AbstractImportTest public void shouldNotThrowExceptionIfNoVocabularyDescription() throws IOException { // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARIES_NO_DESCRIPTION))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, + FilenameUtils.concat(FILES_DIR, VOCABULARIES_NO_DESCRIPTION)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN Vocabulary detection = TestUtils.getVocabulary(v3api, sessionToken, "DETECTION"); + // THEN assertNotNull(detection); assertNull(detection.getDescription()); @@ -188,9 +207,12 @@ public class ImportVocabularyTypesTest extends AbstractImportTest public void shouldNotThrowExceptionIfNoTermLabel() throws IOException { // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARIES_NO_TERM_LABEL))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, VOCABULARIES_NO_TERM_LABEL)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN Vocabulary detection = TestUtils.getVocabulary(v3api, sessionToken, "DETECTION"); + // THEN assertNotNull(detection); assertNull(detection.getTerms().get(0).getLabel()); @@ -201,9 +223,12 @@ public class ImportVocabularyTypesTest extends AbstractImportTest public void shouldNotThrowExceptionIfNoTerms() throws IOException { // GIVEN - TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARIES_NO_TERMS))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, VOCABULARIES_NO_TERMS)); + TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath)); + // WHEN Vocabulary detection = TestUtils.getVocabulary(v3api, sessionToken, "DETECTION"); + // THEN assertNotNull(detection); } @@ -214,7 +239,8 @@ public class ImportVocabularyTypesTest extends AbstractImportTest { TestUtils.createVocabulary(v3api, sessionToken, "TEST_VOCABULARY_TYPE", "Test desc"); // there should be no exceptions - TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(FilenameUtils.concat(FILES_DIR, EXIST_VOCABULARIES))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, EXIST_VOCABULARIES)); + TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(sessionWorkspaceFilePath)); Vocabulary test = TestUtils.getVocabulary(v3api, sessionToken, "TEST_VOCABULARY_TYPE"); assertNotNull(test); } @@ -250,8 +276,9 @@ public class ImportVocabularyTypesTest extends AbstractImportTest assertEquals(beforeTerm.getDescription(), "Original Description"); assertEquals(beforeTerm.getRegistrator().getUserId(), TEST_USER); - TestUtils.createFrom(v3api, systemSessionToken, UpdateMode.UPDATE_IF_EXISTS, - Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARY_WITH_TERM_TO_TAKE_OVER))); + final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(systemSessionToken, + FilenameUtils.concat(FILES_DIR, VOCABULARY_WITH_TERM_TO_TAKE_OVER)); + TestUtils.createFrom(v3api, systemSessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(sessionWorkspaceFilePath)); Vocabulary afterVocabulary = v3api.getVocabularies(instanceAdminSessionToken, Arrays.asList(vocabularyId), fetchOptions).get(vocabularyId); VocabularyTerm afterTerm = afterVocabulary.getTerms().get(0); diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/TestUtils.java b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/TestUtils.java index adbb3a91ba45a39e82ce887e9c3e615352a65525..8681e8e9cb335b9352f26fb00f78c25d6066e5f6 100644 --- a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/TestUtils.java +++ b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/TestUtils.java @@ -15,23 +15,15 @@ */ package ch.ethz.sis.openbis.systemtest.plugin.excelimport; -import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.InputStream; import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.id.IObjectId; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyCreation; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.StringUtils; - import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IEntityType; import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.SearchResult; import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSetType; @@ -44,6 +36,11 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.fetchoptions.Experime import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id.ExperimentIdentifier; import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id.IExperimentId; import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.search.ExperimentTypeSearchCriteria; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportResult; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportData; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportFormat; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportMode; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.Project; import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.fetchoptions.ProjectFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.search.ProjectSearchCriteria; @@ -60,12 +57,11 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.ISampleId; import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.SampleIdentifier; import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.SamplePermId; import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.search.SampleTypeSearchCriteria; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.CustomASServiceExecutionOptions; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.id.CustomASServiceCode; import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.Space; import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.fetchoptions.SpaceFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.search.SpaceSearchCriteria; import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.Vocabulary; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyCreation; import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.fetchoptions.VocabularyFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.VocabularyPermId; import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.search.VocabularySearchCriteria; @@ -73,19 +69,6 @@ import ch.ethz.sis.openbis.generic.server.asapi.v3.IApplicationServerInternalApi public class TestUtils { - private static final String TEST_XLS = "TEST-XLS"; - - private static final String XLS_NAME = "xls_name"; - - private static final String UPDATE_MODE = "update_mode"; - - private static final String XLS_PARAM = "xls"; - - public static final String CSV_PARAM = "csv"; - - private static final String SCRIPTS_PARAM = "scripts"; - - private static final String XLS_IMPORT_API = "xls-import-api"; static Vocabulary getVocabulary(IApplicationServerInternalApi v3api, String sessionToken, String code) { @@ -276,7 +259,7 @@ public class TestUtils } } - static Sample getSample(IApplicationServerInternalApi v3api, String sessionToken, String sampleCode, String spaceCode) + static Sample getSample(IApplicationServerInternalApi v3api, String sessionToken, String spaceCode, String sampleCode) { List<ISampleId> ids = new ArrayList<>(); ids.add(new SampleIdentifier(spaceCode, null, null, sampleCode)); @@ -351,83 +334,11 @@ public class TestUtils static List<IObjectId> createFrom(IApplicationServerInternalApi v3api, String sessionToken, UpdateMode updateMode, Path... xls_paths) throws IOException { - List<byte[]> excels = new ArrayList<>(); - for (Path xls_path : xls_paths) - { - byte[] xls = readData(xls_path); - excels.add(xls); - } - CustomASServiceExecutionOptions options = new CustomASServiceExecutionOptions(); - options.withParameter(XLS_PARAM, excels); - options.withParameter(UPDATE_MODE, updateMode.name()); - options.withParameter(XLS_NAME, TEST_XLS); - return (List<IObjectId>) v3api.executeCustomASService(sessionToken, new CustomASServiceCode(XLS_IMPORT_API), options); - } - - static String createFromCsv(IApplicationServerInternalApi v3api, String sessionToken, Path... csv_paths) throws IOException - { - List<byte[]> csvs = new ArrayList<>(); - for (Path csv_path : csv_paths) - { - byte[] csv = readData(csv_path); - csvs.add(csv); - } - CustomASServiceExecutionOptions options = new CustomASServiceExecutionOptions(); - options.withParameter(CSV_PARAM, csvs); - options.withParameter(UPDATE_MODE, UpdateMode.IGNORE_EXISTING.name()); - options.withParameter(XLS_NAME, TEST_XLS); - return v3api.executeCustomASService(sessionToken, new CustomASServiceCode(XLS_IMPORT_API), options).toString(); - } - - static String createFrom(IApplicationServerInternalApi v3api, String sessionToken, Map<String, String> scripts, Path... xls_paths) - throws IOException - { - return TestUtils.createFrom(v3api, sessionToken, scripts, UpdateMode.IGNORE_EXISTING, xls_paths); - } - - static String createFrom(IApplicationServerInternalApi v3api, String sessionToken, Map<String, String> scripts, UpdateMode updateMode, - Path... xls_paths) throws IOException - { - List<byte[]> excels = new ArrayList<>(); - for (Path xls_path : xls_paths) - { - byte[] xls = readData(xls_path); - excels.add(xls); - } - CustomASServiceExecutionOptions options = new CustomASServiceExecutionOptions(); - options.withParameter(XLS_PARAM, excels); - options.withParameter(SCRIPTS_PARAM, scripts); - options.withParameter(UPDATE_MODE, updateMode.name()); - options.withParameter(XLS_NAME, TEST_XLS); - return v3api.executeCustomASService(sessionToken, new CustomASServiceCode(XLS_IMPORT_API), options).toString(); - } - - static String getValidationScript() - { - return "def validate(entity, isNew):\n if isNew:\n return"; - } + final String[] sessionWorkspaceFiles = Arrays.stream(xls_paths).map(Path::toString).toArray(String[]::new); + final ImportResult importResult = v3api.executeImport(sessionToken, new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles), + new ImportOptions(ImportMode.valueOf(updateMode.name()))); - static String getDynamicScript() - { - return "def calculate():\n return 1"; - } - - static Map<String, String> getValidationPluginMap() - { - String dynamicScriptString = getValidationScript(); - Map<String, String> scriptsMap = new HashMap<>(); - scriptsMap.put("valid.py", dynamicScriptString); - - return scriptsMap; - } - - static Map<String, String> getDynamicPluginMap() - { - String dynamicScriptString = getDynamicScript(); - Map<String, String> scriptsMap = new HashMap<>(); - scriptsMap.put("dynamic/dynamic.py", dynamicScriptString); - - return scriptsMap; + return importResult.getObjectIds(); } static VocabularyPermId createVocabulary(IApplicationServerInternalApi v3api, String sessionToken, String code, String description) @@ -447,17 +358,6 @@ public class TestUtils } } - static String extractSamplePermIdFromResults(String result) - { - // Note this will work only if we created single sample!! - int indexOfSamples = result.indexOf("CreateSamplesOperationResult"); - int permIdStart = indexOfSamples + "CreateSamplesOperationResult".length(); - int permIdEnd = result.indexOf("]", indexOfSamples); - String permId = result.substring(permIdStart, permIdEnd); - permId = StringUtils.strip(permId, "[]"); - return permId; - } - static List<PropertyAssignment> extractAndSortPropertyAssignmentsPerGivenPropertyName(IEntityType rawData, List<String> propertyNames) throws Exception { @@ -477,15 +377,4 @@ public class TestUtils return sortedPropertyAssignments; } - private static byte[] readData(Path xls_path) throws IOException - { - String path = xls_path.toString(); - try (InputStream resourceAsStream = TestUtils.class.getClassLoader().getResourceAsStream(path)) - { - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - IOUtils.copy(resourceAsStream, byteArrayOutputStream); - return byteArrayOutputStream.toByteArray(); - } - } - } diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/experiments/update.xls b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/experiments/update.xls index 60bfe80c3e8fea6978f0145f164c9cb71130df34..ab24558768f2a6600fff42053a2ea52a5125cbe4 100644 Binary files a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/experiments/update.xls and b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/experiments/update.xls differ diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/property_types/normal_property_type.xls b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/property_types/normal_property_type.xls index 633a047ccafd7d2b61987293ac60eaa7c4699d17..21a24d210d4513255e21f55db657a2fcd929d162 100644 Binary files a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/property_types/normal_property_type.xls and b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/property_types/normal_property_type.xls differ diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/sample_types/with_dynamic_script.xls b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/sample_types/with_dynamic_script.xls index 1f4512890f85a50466176aa79763c5cb03309cb4..59ad19a0a9394856024903b37ec0b635d4f5ff77 100644 Binary files a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/sample_types/with_dynamic_script.xls and b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/sample_types/with_dynamic_script.xls differ diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/samples/space_project_experiment_elsewhere.xls b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/samples/space_project_experiment_elsewhere.xls index 2ba767a0c663d8d29d81131d1507ace8ec071198..40d3452f0b4f42da9c6cec7ebb25a5f8c673a41c 100644 Binary files a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/samples/space_project_experiment_elsewhere.xls and b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/samples/space_project_experiment_elsewhere.xls differ diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApi.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApi.java index df54c5679c00ae347859bbca0e5318e136d8713e..1d4263cd87b16fbe2ed4e4d27b644f02266d05f7 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApi.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApi.java @@ -173,7 +173,9 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.search.GlobalSearchCriter import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.search.SearchGloballyOperation; import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.search.SearchGloballyOperationResult; import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportOperation; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.IImportData; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportOperationResult; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportResult; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportData; import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.Material; import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.MaterialType; @@ -1818,9 +1820,10 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi> } @Override - public void executeImport(final String sessionToken, final IImportData importData, final ImportOptions importOptions) + public ImportResult executeImport(final String sessionToken, final ImportData importData, final ImportOptions importOptions) { - executeOperation(sessionToken, new ImportOperation(importData, importOptions)); + final ImportOperationResult operationResult = executeOperation(sessionToken, new ImportOperation(importData, importOptions)); + return operationResult.getImportResult(); } @Override diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiLogger.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiLogger.java index b730776794ffb04fb7ffb8c6d4456c2e4bd97bc8..fbf88fbd32aaaf79c93a576e1366553af53b76e5 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiLogger.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiLogger.java @@ -18,7 +18,6 @@ package ch.ethz.sis.openbis.generic.server.asapi.v3; import java.util.List; import java.util.Map; -import ch.ethz.sis.openbis.generic.asapi.v3.IApplicationServerApi; import ch.ethz.sis.openbis.generic.asapi.v3.dto.authorizationgroup.AuthorizationGroup; import ch.ethz.sis.openbis.generic.asapi.v3.dto.authorizationgroup.create.AuthorizationGroupCreation; import ch.ethz.sis.openbis.generic.asapi.v3.dto.authorizationgroup.delete.AuthorizationGroupDeletionOptions; @@ -90,7 +89,8 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.externaldms.update.ExternalDmsUp import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.GlobalSearchObject; import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.fetchoptions.GlobalSearchObjectFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.search.GlobalSearchCriteria; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.IImportData; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportResult; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportData; import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.Material; import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.MaterialType; @@ -1374,9 +1374,10 @@ public class ApplicationServerApiLogger extends AbstractServerLogger implements } @Override - public void executeImport(final String sessionToken, final IImportData importData, final ImportOptions importOptions) + public ImportResult executeImport(final String sessionToken, final ImportData importData, final ImportOptions importOptions) { - logAccess(sessionToken, "execute-import", "IImportData(%s) ImportOptions(%s)", importData, importOptions); + logAccess(sessionToken, "execute-import", "ImportData(%s) ImportOptions(%s)", importData, importOptions); + return null; } @Override diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiPersonalAccessTokenInvocationHandler.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiPersonalAccessTokenInvocationHandler.java index 1eba23cd4650c3f3bbda3dff28015498fc1281e3..fbce5f0a9ac2f6b51fddd924f836207fea1e942c 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiPersonalAccessTokenInvocationHandler.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiPersonalAccessTokenInvocationHandler.java @@ -91,7 +91,8 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.externaldms.update.ExternalDmsUp import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.GlobalSearchObject; import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.fetchoptions.GlobalSearchObjectFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.search.GlobalSearchCriteria; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.IImportData; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportResult; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportData; import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.Material; import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.MaterialType; @@ -1258,9 +1259,9 @@ public class ApplicationServerApiPersonalAccessTokenInvocationHandler implements } @Override - public void executeImport(final String sessionToken, final IImportData importData, final ImportOptions importOptions) + public ImportResult executeImport(final String sessionToken, final ImportData importData, final ImportOptions importOptions) { - invocation.proceedWithNewFirstArgument(converter.convert(sessionToken)); + return invocation.proceedWithNewFirstArgument(converter.convert(sessionToken)); } @Override diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/importer/IImportExecutor.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/importer/IImportExecutor.java index ae242abdc90c11999c57c0353907d98078b7b674..e90d0fca54cf7ecc12189af5f33befd28f67ab98 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/importer/IImportExecutor.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/importer/IImportExecutor.java @@ -18,11 +18,12 @@ package ch.ethz.sis.openbis.generic.server.asapi.v3.executor.importer; import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportOperation; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportResult; import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext; public interface IImportExecutor { - void doImport(final IOperationContext context, final ImportOperation operation); + ImportResult doImport(final IOperationContext context, final ImportOperation operation); } diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/importer/ImportExecutor.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/importer/ImportExecutor.java index 51363987d1fd87e1efc9ee8d1b47da8bbeacfee3..2957d712024196b15cd1166a85a797230332fe2b 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/importer/ImportExecutor.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/importer/ImportExecutor.java @@ -17,23 +17,13 @@ package ch.ethz.sis.openbis.generic.server.asapi.v3.executor.importer; -import java.io.ByteArrayInputStream; import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.stream.Collectors; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; -import ch.ethz.sis.openbis.generic.server.xls.importer.utils.FileServerUtils; import org.springframework.stereotype.Component; import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportOperation; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.IImportData; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportScript; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportValue; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.UncompressedImportData; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ZipImportData; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportResult; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportData; import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportOptions; import ch.ethz.sis.openbis.generic.server.asapi.v3.IApplicationServerInternalApi; import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext; @@ -46,110 +36,11 @@ import ch.systemsx.cisd.openbis.generic.server.CommonServiceProvider; public class ImportExecutor implements IImportExecutor { - private static final String ZIP_PATH_SEPARATOR = "/"; - - private static final String SCRIPTS_FOLDER_NAME = "scripts" + ZIP_PATH_SEPARATOR; - - private static final String DATA_FOLDER_NAME = "data" + ZIP_PATH_SEPARATOR; - - private static final String MISCELLANEOUS_FOLDER_NAME = "miscellaneous" + ZIP_PATH_SEPARATOR; - - private static final String FILE_SERVICES_FOLDER_NAME = MISCELLANEOUS_FOLDER_NAME + "file-service" + ZIP_PATH_SEPARATOR; - - private static final String XLS_EXTENSION = "." + "xls"; - - private static final String XLSX_EXTENSION = "." + "xlsx"; - @Override - public void doImport(final IOperationContext context, final ImportOperation operation) + public ImportResult doImport(final IOperationContext context, final ImportOperation operation) { - final IImportData importData = operation.getImportData(); - - try - { - if (importData instanceof UncompressedImportData) - { - // XLS file - - final UncompressedImportData uncompressedImportData = (UncompressedImportData) importData; - - final Map<String, String> scripts = uncompressedImportData.getScripts() != null - ? uncompressedImportData.getScripts().stream().collect(Collectors.toMap(ImportScript::getName, ImportScript::getSource)) - : null; - final Map<String, String> importValues = uncompressedImportData.getImportValues() != null - ? uncompressedImportData.getImportValues().stream().collect(Collectors.toMap(ImportValue::getName, ImportValue::getValue)) - : null; - importXls(context, operation, scripts, importValues, uncompressedImportData.getFile(), null); - } else if (importData instanceof ZipImportData) - { - // ZIP file - final Map<String, String> scripts = new HashMap<>(); - final Map<String, String> importValues = new HashMap<>(); - byte[] xlsFileContent = null; + final ImportData importData = operation.getImportData(); - final ZipImportData zipImportData = (ZipImportData) importData; - try (final ZipInputStream zip = new ZipInputStream(new ByteArrayInputStream(zipImportData.getFile()))) - { - ZipEntry entry; - while ((entry = zip.getNextEntry()) != null) - { - final String entryName = entry.getName(); - if (entry.isDirectory()) - { - if (!SCRIPTS_FOLDER_NAME.equals(entryName) && !DATA_FOLDER_NAME.equals(entryName) && !MISCELLANEOUS_FOLDER_NAME.equals(entryName)) - { - throw UserFailureException.fromTemplate("Illegal directory '%s' is found inside the imported file.", entryName); - } - } else - { - if (!entryName.contains(ZIP_PATH_SEPARATOR) && (entryName.endsWith(XLS_EXTENSION) || entryName.endsWith(XLSX_EXTENSION))) - { - if (xlsFileContent == null) - { - xlsFileContent = zip.readAllBytes(); - } else - { - throw UserFailureException.fromTemplate("More than one XLS file found in the root of the imported ZIP file."); - } - } else if (entryName.startsWith(SCRIPTS_FOLDER_NAME)) - { - scripts.put(entryName.substring(SCRIPTS_FOLDER_NAME.length()), new String(zip.readAllBytes())); - } else if (entryName.startsWith(DATA_FOLDER_NAME)) - { - importValues.put(entryName.substring(DATA_FOLDER_NAME.length()), new String(zip.readAllBytes())); - } else - { - throw UserFailureException.fromTemplate( - "Entry '%s' is not allowed. Only one root XLS file is allowed and files inside the '%s' or '%s' folder", - entryName, SCRIPTS_FOLDER_NAME, DATA_FOLDER_NAME); - } - } - } - } - - if (xlsFileContent != null) - { - importXls(context, operation, scripts, importValues, xlsFileContent, zipImportData.getFile()); - } else - { - throw UserFailureException.fromTemplate("XLS file not found in the root of the imported ZIP file."); - } - - } else - { - throw UserFailureException.fromTemplate("Unknown instance of import data '%s'.", - importData != null ? importData.getClass().getName() : null); - } - } catch (final IOException e) - { - throw UserFailureException.fromTemplate(e, "IO exception importing."); - } - } - - private static void importXls(final IOperationContext context, final ImportOperation operation, final Map<String, String> scripts, - final Map<String, String> importValues, final byte[] xlsContent, byte[] zipImportDataOrNull) - throws IOException - { final IApplicationServerInternalApi applicationServerApi = CommonServiceProvider.getApplicationServerApi(); final ImportOptions importOptions = operation.getImportOptions(); @@ -160,31 +51,18 @@ public class ImportExecutor implements IImportExecutor .get("project-samples-enabled")); importerImportOptions.setAllowProjectSamples(projectSamplesEnabled); - final XLSImport xlsImport = new XLSImport(context.getSession().getSessionToken(), applicationServerApi, scripts, - importValues, ImportModes.valueOf(importOptions.getMode().name()), importerImportOptions, "DEFAULT"); - - xlsImport.importXLS(xlsContent); - if (zipImportDataOrNull != null) + try { - importZipData(zipImportDataOrNull); - } - } - - public static void importZipData(byte[] zipImportDataOrNull) throws IOException - { - try (final ZipInputStream zip = new ZipInputStream(new ByteArrayInputStream(zipImportDataOrNull))) + final XLSImport xlsImport = new XLSImport(context.getSession().getSessionToken(), applicationServerApi, + ImportModes.valueOf(importOptions.getMode().name()), importerImportOptions, importData.getSessionWorkspaceFiles(), false); + return new ImportResult(xlsImport.start()); + } catch (final IOException e) { - ZipEntry entry; - while ((entry = zip.getNextEntry()) != null) - { - final String filePath = entry.getName(); - if (!entry.isDirectory() && filePath.startsWith(FILE_SERVICES_FOLDER_NAME)) - { - String fileServicePath = ZIP_PATH_SEPARATOR + filePath.substring(FILE_SERVICES_FOLDER_NAME.length()); - byte[] fileBytes = zip.readAllBytes(); - FileServerUtils.write(fileServicePath, fileBytes); - } - } + throw UserFailureException.fromTemplate(e, "IO exception importing."); + } catch (final Exception e) + { + throw UserFailureException.fromTemplate(e,"Exception importing data: %s", e.getMessage()); } } + } diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/importer/ImportOperationExecutor.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/importer/ImportOperationExecutor.java index ef4032eeaa8069acad357189f88a7ad6bd389419..7702c16e50ea06f63a6466f3b7b2d19a972f337b 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/importer/ImportOperationExecutor.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/importer/ImportOperationExecutor.java @@ -22,6 +22,7 @@ import org.springframework.stereotype.Component; import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportOperation; import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportOperationResult; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportResult; import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext; import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.common.OperationExecutor; @@ -41,8 +42,8 @@ public class ImportOperationExecutor extends OperationExecutor<ImportOperation, @Override protected ImportOperationResult doExecute(final IOperationContext context, final ImportOperation operation) { - executor.doImport(context, operation); - return new ImportOperationResult(); + final ImportResult importResult = executor.doImport(context, operation); + return new ImportOperationResult(importResult); } } diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/export/helper/AbstractXLSExportHelper.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/export/helper/AbstractXLSExportHelper.java index 2e15b9a1a959b074293d744d8ba23030bf31ad4b..5d7c32c7277e67b10cbe7976b0c13c07e907f6ec 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/export/helper/AbstractXLSExportHelper.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/export/helper/AbstractXLSExportHelper.java @@ -220,8 +220,7 @@ public abstract class AbstractXLSExportHelper<ENTITY_TYPE extends IEntityType> i final String filePath = matcher.group(3); try { - final byte[] fileContent = FileServerUtils.read(filePath); - imageFiles.put(filePath, fileContent); + imageFiles.put(filePath, FileServerUtils.readAllBytes(filePath)); } catch (final IOException e) { warnings.add(String.format("Could not read the file at path '%s'.", filePath)); diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/MainImportXlsTest.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/MainImportXlsTest.java deleted file mode 100644 index 715cfae1dd0bdae8ff65e74cfb2d6ff7ced32c3b..0000000000000000000000000000000000000000 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/MainImportXlsTest.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright ETH 2022 - 2023 Zürich, Scientific IT Services - * - * 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.ethz.sis.openbis.generic.server.xls.importer; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Map; - -import org.apache.log4j.Logger; - -import ch.ethz.sis.openbis.generic.asapi.v3.IApplicationServerApi; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.id.IObjectId; -import ch.ethz.sis.openbis.generic.server.xls.importer.enums.ImportModes; -import ch.systemsx.cisd.common.filesystem.FileUtilities; -import ch.systemsx.cisd.common.logging.LogCategory; -import ch.systemsx.cisd.common.logging.LogFactory; -import ch.systemsx.cisd.common.spring.HttpInvokerUtils; -import ch.systemsx.cisd.openbis.generic.server.jython.api.v1.impl.MasterDataRegistrationHelper; - -public class MainImportXlsTest -{ - private static final Logger operationLog = - LogFactory.getLogger(LogCategory.OPERATION, MainImportXlsTest.class); - - private static final int TIMEOUT = 10000; - - private static final String URL = - "http://localhost:8888/openbis/openbis" + IApplicationServerApi.SERVICE_URL; - - private static final File ELN_MASTER_DATA_PATH = - new File("../core-plugin-openbis/dist/core-plugins/eln-lims/1/as"); - - private static final File LIFE_SCIENCES_MASTER_DATA_PATH = - new File("../core-plugin-openbis/dist/core-plugins/eln-lims-life-sciences/1/as"); - - // used only for development! - public static void main(String[] args) - { - IApplicationServerApi v3 = - HttpInvokerUtils.createServiceStub(IApplicationServerApi.class, URL, TIMEOUT); - String sessionToken = v3.login("system", "a"); - - Map<String, String> scripts = getListScripts(ELN_MASTER_DATA_PATH.getPath()); - ImportOptions options = new ImportOptions(); - - XLSImport importXls = - new XLSImport(sessionToken, v3, scripts, Map.of(), ImportModes.UPDATE_IF_EXISTS, options, - "ELN-LIMS"); - Collection<IObjectId> importedIds = new ArrayList<>(); - - File commonDataModel = new File(ELN_MASTER_DATA_PATH, "/master-data/common-data-model.xls"); - importedIds.addAll(importXls.importXLS(FileUtilities.loadToByteArray(commonDataModel))); - File singleGroupDataModel = - new File(ELN_MASTER_DATA_PATH, "/master-data/single-group-data-model.xls"); - importedIds.addAll( - importXls.importXLS(FileUtilities.loadToByteArray(singleGroupDataModel))); - - Map<String, String> lifeSciencesImporterScripts = - getListScripts(LIFE_SCIENCES_MASTER_DATA_PATH.getPath()); - XLSImport lifeSciencesImporter = - new XLSImport(sessionToken, v3, lifeSciencesImporterScripts, - Map.of(), ImportModes.UPDATE_IF_EXISTS, options, "ELN-LIMS-LIFE-SCIENCES"); - File lifeSciencesDataModel = - new File(LIFE_SCIENCES_MASTER_DATA_PATH, "/master-data/data-model.xls"); - importedIds.addAll(lifeSciencesImporter.importXLS( - FileUtilities.loadToByteArray(lifeSciencesDataModel))); - } - - private static Map<String, String> getListScripts(String path) - { - MasterDataRegistrationHelper helper = new MasterDataRegistrationHelper(Arrays.asList(path)); - return helper.getAllScripts(); - } -} diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/XLSImport.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/XLSImport.java index 6340b3a5b13bee7351dd9fec47c67bc94a6589a9..64c3dc87bf60033ec122f3ba47d0377c80c09fae 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/XLSImport.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/XLSImport.java @@ -15,12 +15,29 @@ */ package ch.ethz.sis.openbis.generic.server.xls.importer; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import org.apache.log4j.Logger; + import ch.ethz.sis.openbis.generic.asapi.v3.IApplicationServerApi; import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.id.IObjectId; import ch.ethz.sis.openbis.generic.server.xls.importer.delay.DelayedExecutionDecorator; import ch.ethz.sis.openbis.generic.server.xls.importer.enums.ImportModes; import ch.ethz.sis.openbis.generic.server.xls.importer.enums.ImportTypes; import ch.ethz.sis.openbis.generic.server.xls.importer.enums.ScriptTypes; +import ch.ethz.sis.openbis.generic.server.xls.importer.handler.ExcelParser; import ch.ethz.sis.openbis.generic.server.xls.importer.handler.VersionInfoHandler; import ch.ethz.sis.openbis.generic.server.xls.importer.helper.DatasetTypeImportHelper; import ch.ethz.sis.openbis.generic.server.xls.importer.helper.ExperimentImportHelper; @@ -35,20 +52,34 @@ import ch.ethz.sis.openbis.generic.server.xls.importer.helper.SemanticAnnotation import ch.ethz.sis.openbis.generic.server.xls.importer.helper.SpaceImportHelper; import ch.ethz.sis.openbis.generic.server.xls.importer.helper.VocabularyImportHelper; import ch.ethz.sis.openbis.generic.server.xls.importer.helper.VocabularyTermImportHelper; -import ch.ethz.sis.openbis.generic.server.xls.importer.handler.ExcelParser; import ch.ethz.sis.openbis.generic.server.xls.importer.utils.DatabaseConsistencyChecker; +import ch.ethz.sis.openbis.generic.server.xls.importer.utils.FileServerUtils; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.common.logging.LogCategory; import ch.systemsx.cisd.common.logging.LogFactory; -import org.apache.log4j.Logger; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; +import ch.systemsx.cisd.openbis.generic.server.CommonServiceProvider; +import ch.systemsx.cisd.openbis.generic.shared.ISessionWorkspaceProvider; public class XLSImport { + private static final String PATH_SEPARATOR = "/"; + + private static final String SCRIPTS_FOLDER_NAME = "scripts" + PATH_SEPARATOR; + + private static final String DATA_FOLDER_NAME = "data" + PATH_SEPARATOR; + + private static final String MISCELLANEOUS_FOLDER_NAME = "miscellaneous" + PATH_SEPARATOR; + + private static final String FILE_SERVICES_FOLDER_NAME = MISCELLANEOUS_FOLDER_NAME + "file-service" + PATH_SEPARATOR; + + private static final String XLS_EXTENSION = "." + "xls"; + + private static final String XLSX_EXTENSION = "." + "xlsx"; + + private static final int XLSX_DOCUMENT_LIMIT = 536870912; // 512 MB + + private static final int EMBEDDED_DOCUMENT_LIMIT = 16777216; // 16 MB + private static final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION, XLSImport.class); private final String sessionToken; @@ -85,8 +116,6 @@ public class XLSImport private final PropertyAssignmentImportHelper propertyAssignmentHelper; - private final ScriptImportHelper scriptHelper; - private final SemanticAnnotationImportHelper semanticAnnotationImportHelper; private final DatabaseConsistencyChecker dbChecker; @@ -95,8 +124,20 @@ public class XLSImport private final Map<String, String> importValues; - public XLSImport(String sessionToken, IApplicationServerApi api, Map<String, String> scripts, Map<String, String> importValues, - ImportModes mode, ImportOptions options, String xlsName) + private final ScriptImportHelper scriptHelper; + + private final String[] sessionWorkspaceFiles; + + private final byte[][] xls; + + private static final String ZIP_EXTENSION = "." + "zip"; + + public XLSImport(String sessionToken, + IApplicationServerApi api, + ImportModes mode, + ImportOptions options, + String[] sessionWorkspaceFiles, + boolean shouldCheckVersionsOnDatabase) throws IOException { this.sessionToken = sessionToken; this.api = api; @@ -105,8 +146,6 @@ public class XLSImport this.afterVersions = VersionInfoHandler.loadAllVersions(options); this.dbChecker = new DatabaseConsistencyChecker(this.sessionToken, this.api, this.afterVersions); this.delayedExecutor = new DelayedExecutionDecorator(this.sessionToken, this.api); - this.importValues = importValues; - this.vocabularyHelper = new VocabularyImportHelper(this.delayedExecutor, mode, options, afterVersions); this.vocabularyTermHelper = new VocabularyTermImportHelper(this.delayedExecutor, mode, options, afterVersions); this.sampleTypeHelper = new SampleTypeImportHelper(this.delayedExecutor, mode, options, afterVersions); @@ -118,122 +157,238 @@ public class XLSImport this.sampleHelper = new SampleImportHelper(this.delayedExecutor, mode, options); this.propertyHelper = new PropertyTypeImportHelper(this.delayedExecutor, mode, options, afterVersions); this.propertyAssignmentHelper = new PropertyAssignmentImportHelper(this.delayedExecutor, mode, options, beforeVersions); - this.scriptHelper = new ScriptImportHelper(this.delayedExecutor, mode, options, scripts); this.semanticAnnotationImportHelper = new SemanticAnnotationImportHelper(this.delayedExecutor, mode, options); - this.shouldCheckVersionsOnDatabase = xlsName == null || xlsName.equals("DEFAULT") == false; - } + this.shouldCheckVersionsOnDatabase = shouldCheckVersionsOnDatabase; - public List<IObjectId> importXLS(byte xls[]) - { - if (shouldCheckVersionsOnDatabase) - { - this.dbChecker.checkVersionsOnDataBase(); - } + // File Parsing + this.sessionWorkspaceFiles = sessionWorkspaceFiles; + final ISessionWorkspaceProvider sessionWorkspaceProvider = CommonServiceProvider.getSessionWorkspaceProvider(); - List<List<List<String>>> lines = ExcelParser.parseExcel(xls, importValues); - int pageNumber = 0; - int lineNumber; + final Map<String, String> scripts = new HashMap<>(); + byte[][] xls = new byte[sessionWorkspaceFiles.length][]; + this.importValues = new HashMap<>(); - while (pageNumber < lines.size()) + for (int i = 0; i < sessionWorkspaceFiles.length; i++) { - lineNumber = 0; - List<List<String>> page = lines.get(pageNumber); - int pageEnd = getPageEnd(page); - while (lineNumber < pageEnd) + InputStream read = sessionWorkspaceProvider.read(sessionToken, sessionWorkspaceFiles[i]); + if (sessionWorkspaceFiles[i].toLowerCase().endsWith(ZIP_EXTENSION)) { - int blockEnd = getBlockEnd(page, lineNumber); - ImportTypes blockType; - try + try (final ZipInputStream zip = new ZipInputStream(read)) { - blockType = ImportTypes.valueOf(page.get(lineNumber).get(0)); - } catch (Exception e) - { - throw new UserFailureException( - "Exception at page " + (pageNumber + 1) + " and line " + (lineNumber + 1) + " with message: " + e.getMessage()); - } - lineNumber++; - - switch (blockType) - { - case VOCABULARY_TYPE: - vocabularyHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2); - if (lineNumber + 2 != blockEnd) + ZipEntry entry; + while ((entry = zip.getNextEntry()) != null) + { + final String entryName = entry.getName(); + if (entry.isDirectory()) { - vocabularyTermHelper.importBlock(page, pageNumber, lineNumber, blockEnd); - } - break; - case SAMPLE_TYPE: - // parse and create scripts - scriptHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2, ScriptTypes.VALIDATION_SCRIPT); - // parse and create sample type - sampleTypeHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2); - semanticAnnotationImportHelper.importBlockForEntityType(page, pageNumber, lineNumber, lineNumber + 2, ImportTypes.SAMPLE_TYPE); - // parse and assignment properties - if (lineNumber + 2 != blockEnd) + if (!SCRIPTS_FOLDER_NAME.equals(entryName) && !DATA_FOLDER_NAME.equals(entryName) && + !entryName.startsWith(MISCELLANEOUS_FOLDER_NAME)) + { + throw UserFailureException.fromTemplate("Illegal directory '%s' is found inside the imported file.", entryName); + } + } else { - scriptHelper.importBlock(page, pageNumber, lineNumber + 2, blockEnd, ScriptTypes.DYNAMIC_SCRIPT); - propertyHelper.importBlock(page, pageNumber, lineNumber + 2, blockEnd); - propertyAssignmentHelper.importBlock(page, pageNumber, lineNumber, blockEnd, ImportTypes.SAMPLE_TYPE); - semanticAnnotationImportHelper.importBlockForEntityTypeProperty(page, pageNumber, lineNumber, blockEnd, ImportTypes.SAMPLE_TYPE); + if (!entryName.contains(PATH_SEPARATOR) && (entryName.endsWith(XLS_EXTENSION) || entryName.endsWith(XLSX_EXTENSION))) + { + validateEntrySize(entry.getSize(), XLSX_DOCUMENT_LIMIT); + if (xls[i] == null) + { + xls[i] = zip.readAllBytes(); + } else + { + throw UserFailureException.fromTemplate("More than one XLS file found in the root of the imported ZIP file."); + } + } else if (entryName.startsWith(SCRIPTS_FOLDER_NAME)) + { + validateEntrySize(entry.getSize(), EMBEDDED_DOCUMENT_LIMIT); + scripts.put(entryName.substring(SCRIPTS_FOLDER_NAME.length()), new String(zip.readAllBytes())); + } else if (entryName.startsWith(DATA_FOLDER_NAME)) + { + validateEntrySize(entry.getSize(), EMBEDDED_DOCUMENT_LIMIT); + this.importValues.put(entryName.substring(DATA_FOLDER_NAME.length()), new String(zip.readAllBytes())); + } else if (!entryName.startsWith(MISCELLANEOUS_FOLDER_NAME)) + { + throw UserFailureException.fromTemplate( + "Entry '%s' is not allowed. Only one root XLS file is allowed and files inside the '%s' or '%s' folder", + entryName, SCRIPTS_FOLDER_NAME, DATA_FOLDER_NAME); + } } - break; - case EXPERIMENT_TYPE: - // parse and create scripts - scriptHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2, ScriptTypes.VALIDATION_SCRIPT); - // parse and create experiment type - experimentTypeHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2); - semanticAnnotationImportHelper.importBlockForEntityType(page, pageNumber, lineNumber, lineNumber + 2, ImportTypes.EXPERIMENT_TYPE); - // parse and assignment properties - if (lineNumber + 2 != blockEnd) + } + } + } else + { + final File canonicalFile = sessionWorkspaceProvider.getCanonicalFile(sessionToken, sessionWorkspaceFiles[i]); + validateEntrySize(canonicalFile.length(), XLSX_DOCUMENT_LIMIT); + xls[i] = sessionWorkspaceProvider.readAllBytes(sessionToken, sessionWorkspaceFiles[i]); + + // Script folder support + final String scriptsFolderName = canonicalFile.getParent() + + PATH_SEPARATOR + SCRIPTS_FOLDER_NAME; + + final File scriptsFolder = new File(scriptsFolderName); + if (scriptsFolder.exists() && scriptsFolder.isDirectory()) + { + final File[] files = scriptsFolder.listFiles(); + if (files != null) + { + for (final File file : files) { - scriptHelper.importBlock(page, pageNumber, lineNumber + 2, blockEnd, ScriptTypes.DYNAMIC_SCRIPT); - propertyHelper.importBlock(page, pageNumber, lineNumber + 2, blockEnd); - propertyAssignmentHelper.importBlock(page, pageNumber, lineNumber, blockEnd, ImportTypes.EXPERIMENT_TYPE); - semanticAnnotationImportHelper.importBlockForEntityTypeProperty(page, pageNumber, lineNumber, blockEnd, ImportTypes.EXPERIMENT_TYPE); + scripts.put(file.getName(), Files.readString(file.toPath(), StandardCharsets.UTF_8)); } - break; - case DATASET_TYPE: - // parse and create scripts - scriptHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2, ScriptTypes.VALIDATION_SCRIPT); - // parse and create dataset type - datasetTypeHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2); - semanticAnnotationImportHelper.importBlockForEntityType(page, pageNumber, lineNumber, lineNumber + 2, ImportTypes.DATASET_TYPE); - // parse and assignment properties - if (lineNumber + 2 != blockEnd) + } + } + + // Data folder support + final String dataFolderName = canonicalFile.getParent() + + PATH_SEPARATOR + DATA_FOLDER_NAME; + + final File dataFolder = new File(dataFolderName); + if (dataFolder.exists() && dataFolder.isDirectory()) + { + final File[] files = dataFolder.listFiles(); + if (files != null) + { + for (final File file : files) { - scriptHelper.importBlock(page, pageNumber, lineNumber + 2, blockEnd, ScriptTypes.DYNAMIC_SCRIPT); - propertyHelper.importBlock(page, pageNumber, lineNumber + 2, blockEnd); - propertyAssignmentHelper.importBlock(page, pageNumber, lineNumber, blockEnd, ImportTypes.DATASET_TYPE); - semanticAnnotationImportHelper.importBlockForEntityTypeProperty(page, pageNumber, lineNumber, blockEnd, ImportTypes.DATASET_TYPE); + this.importValues.put(file.getName(), Files.readString(file.toPath(), StandardCharsets.UTF_8)); } - break; - case SPACE: - spaceHelper.importBlock(page, pageNumber, lineNumber, blockEnd); - break; - case PROJECT: - projectHelper.importBlock(page, pageNumber, lineNumber, blockEnd); - break; - case EXPERIMENT: - experimentHelper.importBlock(page, pageNumber, lineNumber, blockEnd); - break; - case SAMPLE: - sampleHelper.importBlock(page, pageNumber, lineNumber, blockEnd); - break; - case PROPERTY_TYPE: - propertyHelper.importBlock(page, pageNumber, lineNumber, blockEnd); - semanticAnnotationImportHelper.importBlockForPropertyType(page, pageNumber, lineNumber, blockEnd); - break; - default: - throw new UserFailureException("Unknown type: " + blockType); + } } - lineNumber = blockEnd + 1; } - pageNumber++; } - this.delayedExecutor.hasFinished(); + this.xls = xls; + this.scriptHelper = new ScriptImportHelper(this.delayedExecutor, mode, options, scripts); + } + + private static void validateEntrySize(final long size, final int limit) + { + if (size > limit) + { + throw UserFailureException.fromTemplate("Document limit exceeded: %d.", size); + } + } + public List<IObjectId> start() throws IOException + { + if (shouldCheckVersionsOnDatabase) + { + this.dbChecker.checkVersionsOnDataBase(); + } + + for (int i = 0; i < this.xls.length; i++) + { + List<List<List<String>>> lines = ExcelParser.parseExcel(this.xls[i], importValues); + int pageNumber = 0; + int lineNumber; + + while (pageNumber < lines.size()) + { + lineNumber = 0; + List<List<String>> page = lines.get(pageNumber); + int pageEnd = getPageEnd(page); + while (lineNumber < pageEnd) + { + int blockEnd = getBlockEnd(page, lineNumber); + ImportTypes blockType; + try + { + blockType = ImportTypes.valueOf(page.get(lineNumber).get(0)); + } catch (Exception e) + { + throw new UserFailureException( + "Exception at page " + (pageNumber + 1) + " and line " + (lineNumber + 1) + " with message: " + e.getMessage()); + } + lineNumber++; + + switch (blockType) + { + case VOCABULARY_TYPE: + vocabularyHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2); + if (lineNumber + 2 != blockEnd) + { + vocabularyTermHelper.importBlock(page, pageNumber, lineNumber, blockEnd); + } + break; + case SAMPLE_TYPE: + // parse and create scripts + scriptHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2, ScriptTypes.VALIDATION_SCRIPT); + // parse and create sample type + sampleTypeHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2); + semanticAnnotationImportHelper.importBlockForEntityType(page, pageNumber, lineNumber, lineNumber + 2, + ImportTypes.SAMPLE_TYPE); + // parse and assignment properties + if (lineNumber + 2 != blockEnd) + { + scriptHelper.importBlock(page, pageNumber, lineNumber + 2, blockEnd, ScriptTypes.DYNAMIC_SCRIPT); + propertyHelper.importBlock(page, pageNumber, lineNumber + 2, blockEnd); + propertyAssignmentHelper.importBlock(page, pageNumber, lineNumber, blockEnd, ImportTypes.SAMPLE_TYPE); + semanticAnnotationImportHelper.importBlockForEntityTypeProperty(page, pageNumber, lineNumber, blockEnd, + ImportTypes.SAMPLE_TYPE); + } + break; + case EXPERIMENT_TYPE: + // parse and create scripts + scriptHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2, ScriptTypes.VALIDATION_SCRIPT); + // parse and create experiment type + experimentTypeHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2); + semanticAnnotationImportHelper.importBlockForEntityType(page, pageNumber, lineNumber, lineNumber + 2, + ImportTypes.EXPERIMENT_TYPE); + // parse and assignment properties + if (lineNumber + 2 != blockEnd) + { + scriptHelper.importBlock(page, pageNumber, lineNumber + 2, blockEnd, ScriptTypes.DYNAMIC_SCRIPT); + propertyHelper.importBlock(page, pageNumber, lineNumber + 2, blockEnd); + propertyAssignmentHelper.importBlock(page, pageNumber, lineNumber, blockEnd, ImportTypes.EXPERIMENT_TYPE); + semanticAnnotationImportHelper.importBlockForEntityTypeProperty(page, pageNumber, lineNumber, blockEnd, + ImportTypes.EXPERIMENT_TYPE); + } + break; + case DATASET_TYPE: + // parse and create scripts + scriptHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2, ScriptTypes.VALIDATION_SCRIPT); + // parse and create dataset type + datasetTypeHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2); + semanticAnnotationImportHelper.importBlockForEntityType(page, pageNumber, lineNumber, lineNumber + 2, + ImportTypes.DATASET_TYPE); + // parse and assignment properties + if (lineNumber + 2 != blockEnd) + { + scriptHelper.importBlock(page, pageNumber, lineNumber + 2, blockEnd, ScriptTypes.DYNAMIC_SCRIPT); + propertyHelper.importBlock(page, pageNumber, lineNumber + 2, blockEnd); + propertyAssignmentHelper.importBlock(page, pageNumber, lineNumber, blockEnd, ImportTypes.DATASET_TYPE); + semanticAnnotationImportHelper.importBlockForEntityTypeProperty(page, pageNumber, lineNumber, blockEnd, + ImportTypes.DATASET_TYPE); + } + break; + case SPACE: + spaceHelper.importBlock(page, pageNumber, lineNumber, blockEnd); + break; + case PROJECT: + projectHelper.importBlock(page, pageNumber, lineNumber, blockEnd); + break; + case EXPERIMENT: + experimentHelper.importBlock(page, pageNumber, lineNumber, blockEnd); + break; + case SAMPLE: + sampleHelper.importBlock(page, pageNumber, lineNumber, blockEnd); + break; + case PROPERTY_TYPE: + propertyHelper.importBlock(page, pageNumber, lineNumber, blockEnd); + semanticAnnotationImportHelper.importBlockForPropertyType(page, pageNumber, lineNumber, blockEnd); + break; + default: + throw new UserFailureException("Unknown type: " + blockType); + } + lineNumber = blockEnd + 1; + } + pageNumber++; + } + } + + this.delayedExecutor.hasFinished(); VersionInfoHandler.writeAllVersions(options, afterVersions); + importZipData(); return new ArrayList<>(this.delayedExecutor.getIds()); } @@ -290,4 +445,34 @@ public class XLSImport } return true; } + + + private void importZipData() throws IOException + { + for (int i = 0; i < this.sessionWorkspaceFiles.length; i++) + { + if (this.sessionWorkspaceFiles[i].toLowerCase().endsWith(ZIP_EXTENSION)) + { + final ISessionWorkspaceProvider sessionWorkspaceProvider = CommonServiceProvider.getSessionWorkspaceProvider(); + InputStream read = sessionWorkspaceProvider.read(this.sessionToken, this.sessionWorkspaceFiles[i]); + + try (final ZipInputStream zip = new ZipInputStream(read)) + { + ZipEntry entry; + while ((entry = zip.getNextEntry()) != null) + { + final String filePath = entry.getName(); + if (!entry.isDirectory() && filePath.startsWith(FILE_SERVICES_FOLDER_NAME)) + { + String fileServicePath = PATH_SEPARATOR + filePath.substring(FILE_SERVICES_FOLDER_NAME.length()); + try (final OutputStream outputStream = FileServerUtils.newOutputStream(fileServicePath)) + { + zip.transferTo(outputStream); + } + } + } + } + } + } + } } \ No newline at end of file diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/delay/DelayedExecutionDecorator.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/delay/DelayedExecutionDecorator.java index b67fb2fb56570b5e595f56bebbf0c27ba54f85b4..6d596c17d8086f3a5e93c18681a0110ebfd4f4c6 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/delay/DelayedExecutionDecorator.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/delay/DelayedExecutionDecorator.java @@ -15,6 +15,18 @@ */ package ch.ethz.sis.openbis.generic.server.xls.importer.delay; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Stream; + import ch.ethz.sis.openbis.generic.asapi.v3.IApplicationServerApi; import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.id.IObjectId; import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IEntityType; @@ -26,7 +38,6 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSetType; import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.create.DataSetTypeCreation; import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.fetchoptions.DataSetTypeFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.update.DataSetTypeUpdate; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.EntityKind; import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.id.EntityTypePermId; import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.id.IEntityTypeId; import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.Experiment; @@ -94,10 +105,6 @@ import ch.ethz.sis.openbis.generic.server.xls.importer.enums.ImportTypes; import ch.ethz.sis.openbis.generic.server.xls.importer.utils.ImportUtils; import ch.systemsx.cisd.common.exceptions.UserFailureException; -import java.io.Serializable; -import java.util.*; -import java.util.stream.Stream; - public class DelayedExecutionDecorator { private String sessionToken; @@ -123,7 +130,7 @@ public class DelayedExecutionDecorator this.v3 = v3; this.ids = new LinkedHashSet<>(); this.resolvedVariables = new HashMap<>(); - this.delayedExecutions = new HashMap<>(); + this.delayedExecutions = new LinkedHashMap<>(); // The only reason this is a linked Hash Map is so the list of error messages is on the same order as the delayed executions are added. this.propertyTypeCache = new HashMap<>(); } @@ -173,7 +180,7 @@ public class DelayedExecutionDecorator if (!delayedExecutions.isEmpty()) { List<String> errors = new ArrayList<>(); - Set<DelayedExecution> delayedExecutionsAsList = new HashSet<>(); + Set<DelayedExecution> delayedExecutionsAsList = new LinkedHashSet<>(); // The only reason this is a linked Hash Set is so the list of error messages is on the same order as the delayed executions are added. for (List<DelayedExecution> valueList : delayedExecutions.values()) { delayedExecutionsAsList.addAll(valueList); diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/BasicImportHelper.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/BasicImportHelper.java index 68e38eb2b438447d8c8fbdcb979911340a8a8b24..27692bc4fdd2e32d2b98ae7b9ea071b1178774eb 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/BasicImportHelper.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/BasicImportHelper.java @@ -87,7 +87,10 @@ public abstract class BasicImportHelper extends AbstractImportHelper switch (mode) { case FAIL_IF_EXISTS: - throw new UserFailureException("Mode FAIL_IF_EXISTS - Found existing " + getTypeName()); + if (!(this instanceof SemanticAnnotationImportHelper)) + { + throw new UserFailureException("Mode FAIL_IF_EXISTS - Found existing " + getTypeName()); + } case UPDATE_IF_EXISTS: updateObject(header, page.get(lineIndex), pageIndex, lineIndex); updateVersion(header, page.get(lineIndex)); diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/DatasetTypeImportHelper.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/DatasetTypeImportHelper.java index 1b0e34aba048eee4b08115d57e8631bab3c87f30..e7087238d59e7aaddfd685449c6345b28cdda3c1 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/DatasetTypeImportHelper.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/DatasetTypeImportHelper.java @@ -15,6 +15,9 @@ */ package ch.ethz.sis.openbis.generic.server.xls.importer.helper; +import java.util.List; +import java.util.Map; + import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.create.DataSetTypeCreation; import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.fetchoptions.DataSetTypeFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.update.DataSetTypeUpdate; @@ -28,9 +31,7 @@ import ch.ethz.sis.openbis.generic.server.xls.importer.utils.AttributeValidator; import ch.ethz.sis.openbis.generic.server.xls.importer.utils.IAttribute; import ch.ethz.sis.openbis.generic.server.xls.importer.utils.ImportUtils; import ch.ethz.sis.openbis.generic.server.xls.importer.utils.VersionUtils; - -import java.util.List; -import java.util.Map; +import ch.systemsx.cisd.common.exceptions.UserFailureException; public class DatasetTypeImportHelper extends BasicImportHelper { @@ -81,9 +82,15 @@ public class DatasetTypeImportHelper extends BasicImportHelper @Override protected boolean isNewVersion(Map<String, Integer> header, List<String> values) { - String version = getValueByColumnName(header, values, Attribute.Version); String code = getValueByColumnName(header, values, Attribute.Code); + if (code == null) + { + throw new UserFailureException("Mandatory field is missing or empty: " + Attribute.Code); + } + + String version = getValueByColumnName(header, values, Attribute.Version); + if (version == null || version.isEmpty()) { return true; } else { diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/ExperimentImportHelper.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/ExperimentImportHelper.java index 1c90876232a28322f5bed4f01a1c225a1e75b8cb..fea3039b97e4375afb28885fc5092ef7c40e81aa 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/ExperimentImportHelper.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/ExperimentImportHelper.java @@ -92,7 +92,7 @@ public class ExperimentImportHelper extends BasicImportHelper experimentType = new EntityTypePermId(getValueByColumnName(header, page.get(lineIndex), EXPERIMENT_TYPE_FIELD)); if(experimentType.getPermId() == null || experimentType.getPermId().isEmpty()) { - throw new UserFailureException("Mandatory field missing or empty: " + EXPERIMENT_TYPE_FIELD); + throw new UserFailureException("Mandatory field is missing or empty: " + EXPERIMENT_TYPE_FIELD); } // first check that experiment type exist. @@ -171,7 +171,6 @@ public class ExperimentImportHelper extends BasicImportHelper @Override protected void updateObject(Map<String, Integer> header, List<String> values, int page, int line) { String identifier = getValueByColumnName(header, values, Attribute.Identifier); - String project = getValueByColumnName(header, values, Attribute.Project); if (identifier == null || identifier.isEmpty()) { @@ -182,6 +181,8 @@ public class ExperimentImportHelper extends BasicImportHelper IExperimentId experimentId = new ExperimentIdentifier(identifier); update.setExperimentId(experimentId); + String project = getValueByColumnName(header, values, Attribute.Project); + // Project is used to "MOVE", only set if present since can't be null if (project != null && !project.isEmpty()) { diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/ExperimentTypeImportHelper.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/ExperimentTypeImportHelper.java index 274c1a36a4b2970e52e859b3228533b195bb5e07..7b816377c5b8d3c8bd41202afeb49d9dce30a11c 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/ExperimentTypeImportHelper.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/ExperimentTypeImportHelper.java @@ -15,6 +15,9 @@ */ package ch.ethz.sis.openbis.generic.server.xls.importer.helper; +import java.util.List; +import java.util.Map; + import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.id.EntityTypePermId; import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.create.ExperimentTypeCreation; import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.fetchoptions.ExperimentTypeFetchOptions; @@ -28,9 +31,7 @@ import ch.ethz.sis.openbis.generic.server.xls.importer.utils.AttributeValidator; import ch.ethz.sis.openbis.generic.server.xls.importer.utils.IAttribute; import ch.ethz.sis.openbis.generic.server.xls.importer.utils.ImportUtils; import ch.ethz.sis.openbis.generic.server.xls.importer.utils.VersionUtils; - -import java.util.List; -import java.util.Map; +import ch.systemsx.cisd.common.exceptions.UserFailureException; public class ExperimentTypeImportHelper extends BasicImportHelper { @@ -81,9 +82,15 @@ public class ExperimentTypeImportHelper extends BasicImportHelper @Override protected boolean isNewVersion(Map<String, Integer> header, List<String> values) { - String version = getValueByColumnName(header, values, Attribute.Version); String code = getValueByColumnName(header, values, Attribute.Code); + if (code == null) + { + throw new UserFailureException("Mandatory field is missing or empty: " + Attribute.Code); + } + + String version = getValueByColumnName(header, values, Attribute.Version); + if (version == null || version.isEmpty()) { return true; } else { diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/PropertyAssignmentImportHelper.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/PropertyAssignmentImportHelper.java index a8b9c170e663cb8e19b9128746cccc5d28c7ee47..5eba0433083b649799dd2da7a50820d3d121c5f6 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/PropertyAssignmentImportHelper.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/PropertyAssignmentImportHelper.java @@ -15,6 +15,13 @@ */ package ch.ethz.sis.openbis.generic.server.xls.importer.helper; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IEntityType; import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.update.ListUpdateValue; import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSetType; @@ -43,13 +50,7 @@ import ch.ethz.sis.openbis.generic.server.xls.importer.utils.AttributeValidator; import ch.ethz.sis.openbis.generic.server.xls.importer.utils.IAttribute; import ch.ethz.sis.openbis.generic.server.xls.importer.utils.ImportUtils; import ch.ethz.sis.openbis.generic.server.xls.importer.utils.VersionUtils; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; +import ch.systemsx.cisd.common.exceptions.UserFailureException; public class PropertyAssignmentImportHelper extends BasicImportHelper { @@ -123,9 +124,15 @@ public class PropertyAssignmentImportHelper extends BasicImportHelper @Override protected boolean isNewVersion(Map<String, Integer> header, List<String> values) { - String version = getValueByColumnName(header, values, PropertyAssignmentImportHelper.Attribute.Version); String code = getValueByColumnName(header, values, PropertyAssignmentImportHelper.Attribute.Code); + if (code == null) + { + throw new UserFailureException("Mandatory field is missing or empty: " + Attribute.Code); + } + + String version = getValueByColumnName(header, values, PropertyAssignmentImportHelper.Attribute.Version); + if (version == null || version.isEmpty()) { return true; } else { diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/PropertyTypeImportHelper.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/PropertyTypeImportHelper.java index 74b87f10c9abcc7a1a671f81dd722cd020fdce1f..7f7ebd0b6d554061fd49b0eef1eba56a2bc544f7 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/PropertyTypeImportHelper.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/PropertyTypeImportHelper.java @@ -15,6 +15,15 @@ */ package ch.ethz.sis.openbis.generic.server.xls.importer.helper; +import static ch.ethz.sis.openbis.generic.server.xls.importer.utils.PropertyTypeSearcher.SAMPLE_DATA_TYPE_MANDATORY_TYPE; +import static ch.ethz.sis.openbis.generic.server.xls.importer.utils.PropertyTypeSearcher.SAMPLE_DATA_TYPE_PREFIX; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; + import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.EntityKind; import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.id.EntityTypePermId; import ch.ethz.sis.openbis.generic.asapi.v3.dto.property.DataType; @@ -29,21 +38,13 @@ import ch.ethz.sis.openbis.generic.server.xls.importer.delay.DelayedExecutionDec import ch.ethz.sis.openbis.generic.server.xls.importer.enums.ImportModes; import ch.ethz.sis.openbis.generic.server.xls.importer.enums.ImportTypes; import ch.ethz.sis.openbis.generic.server.xls.importer.handler.JSONHandler; -import ch.ethz.sis.openbis.generic.server.xls.importer.utils.IAttribute; import ch.ethz.sis.openbis.generic.server.xls.importer.utils.AttributeValidator; +import ch.ethz.sis.openbis.generic.server.xls.importer.utils.IAttribute; import ch.ethz.sis.openbis.generic.server.xls.importer.utils.ImportUtils; import ch.ethz.sis.openbis.generic.server.xls.importer.utils.VersionUtils; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.common.logging.LogCategory; import ch.systemsx.cisd.common.logging.LogFactory; -import org.apache.log4j.Logger; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static ch.ethz.sis.openbis.generic.server.xls.importer.utils.PropertyTypeSearcher.SAMPLE_DATA_TYPE_MANDATORY_TYPE; -import static ch.ethz.sis.openbis.generic.server.xls.importer.utils.PropertyTypeSearcher.SAMPLE_DATA_TYPE_PREFIX; public class PropertyTypeImportHelper extends BasicImportHelper { @@ -132,8 +133,7 @@ public class PropertyTypeImportHelper extends BasicImportHelper } if (!propertyData.equals(this.propertyCache.get(code))) { - throw new UserFailureException( - "Unambiguous property " + code + " found, has been declared before with different attributes."); + throw new UserFailureException("Ambiguous property " + code + " found, it has been declared before with different attributes."); } } @@ -149,6 +149,11 @@ public class PropertyTypeImportHelper extends BasicImportHelper String version = getValueByColumnName(header, values, Attribute.Version); String code = getValueByColumnName(header, values, Attribute.Code); + if (code == null) + { + throw new UserFailureException("Mandatory field is missing or empty: " + Attribute.Code); + } + boolean isInternalNamespace = ImportUtils.isInternalNamespace(code); boolean isSystem = delayedExecutor.isSystem(); boolean canUpdate = (isInternalNamespace == false) || isSystem; diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/SampleImportHelper.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/SampleImportHelper.java index 0847c18c62584723972d69a6d5b7c13c3a61cd46..1d59d9745cb3a94c2c83d5b5b7c347fb032a44bd 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/SampleImportHelper.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/SampleImportHelper.java @@ -107,7 +107,7 @@ public class SampleImportHelper extends BasicImportHelper sampleType = new EntityTypePermId(getValueByColumnName(header, page.get(lineIndex), SAMPLE_TYPE_FIELD)); if(sampleType.getPermId() == null || sampleType.getPermId().isEmpty()) { - throw new UserFailureException("Mandatory field missing or empty: " + SAMPLE_TYPE_FIELD); + throw new UserFailureException("Mandatory field is missing or empty: " + SAMPLE_TYPE_FIELD); } // first check that sample type exist. @@ -268,7 +268,7 @@ public class SampleImportHelper extends BasicImportHelper } if (identifier == null || identifier.isEmpty()) { - throw new UserFailureException("'Identifier' is missing, is mandatory since is needed to select a sample to update."); + throw new UserFailureException("'Identifier' is missing, it is mandatory since it is needed to select a sample to update."); } ISampleId sampleId = ImportUtils.buildSampleIdentifier(identifier); diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/SampleTypeImportHelper.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/SampleTypeImportHelper.java index 7597d8ba6a2ddc6ccab2c244356a44d3b3d602e6..91f624ebce1a80442b2343af412a7d43128ed96f 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/SampleTypeImportHelper.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/SampleTypeImportHelper.java @@ -15,6 +15,9 @@ */ package ch.ethz.sis.openbis.generic.server.xls.importer.helper; +import java.util.List; +import java.util.Map; + import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.id.EntityTypePermId; import ch.ethz.sis.openbis.generic.asapi.v3.dto.plugin.id.PluginPermId; import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.create.SampleTypeCreation; @@ -28,9 +31,7 @@ import ch.ethz.sis.openbis.generic.server.xls.importer.utils.AttributeValidator; import ch.ethz.sis.openbis.generic.server.xls.importer.utils.IAttribute; import ch.ethz.sis.openbis.generic.server.xls.importer.utils.ImportUtils; import ch.ethz.sis.openbis.generic.server.xls.importer.utils.VersionUtils; - -import java.util.List; -import java.util.Map; +import ch.systemsx.cisd.common.exceptions.UserFailureException; public class SampleTypeImportHelper extends BasicImportHelper { @@ -83,9 +84,15 @@ public class SampleTypeImportHelper extends BasicImportHelper @Override protected boolean isNewVersion(Map<String, Integer> header, List<String> values) { - String version = getValueByColumnName(header, values, Attribute.Version); String code = getValueByColumnName(header, values, Attribute.Code); + if (code == null) + { + throw new UserFailureException("Mandatory field is missing or empty: " + Attribute.Code); + } + + String version = getValueByColumnName(header, values, Attribute.Version); + if (version == null || version.isEmpty()) { return true; } else { @@ -110,6 +117,12 @@ public class SampleTypeImportHelper extends BasicImportHelper @Override protected boolean isObjectExist(Map<String, Integer> header, List<String> values) { String code = getValueByColumnName(header, values, Attribute.Code); + + if (code == null) + { + throw new UserFailureException("Mandatory field is missing or empty: " + Attribute.Code); + } + EntityTypePermId id = new EntityTypePermId(code); return delayedExecutor.getSampleType(id, new SampleTypeFetchOptions()) != null; diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/ScriptImportHelper.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/ScriptImportHelper.java index 1c116252adf7e16587d9af314271bed5b19684a1..bec20f48cd5d0425d7f225554bc4695264c5d477 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/ScriptImportHelper.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/ScriptImportHelper.java @@ -15,6 +15,10 @@ */ package ch.ethz.sis.openbis.generic.server.xls.importer.helper; +import java.io.File; +import java.util.List; +import java.util.Map; + import ch.ethz.sis.openbis.generic.asapi.v3.dto.plugin.PluginType; import ch.ethz.sis.openbis.generic.asapi.v3.dto.plugin.create.PluginCreation; import ch.ethz.sis.openbis.generic.asapi.v3.dto.plugin.fetchoptions.PluginFetchOptions; @@ -27,9 +31,6 @@ import ch.ethz.sis.openbis.generic.server.xls.importer.enums.ImportTypes; import ch.ethz.sis.openbis.generic.server.xls.importer.enums.ScriptTypes; import ch.ethz.sis.openbis.generic.server.xls.importer.utils.ImportUtils; -import java.util.List; -import java.util.Map; - public class ScriptImportHelper extends BasicImportHelper { private static final String OWNER_CODE = "Code"; @@ -80,36 +81,42 @@ public class ScriptImportHelper extends BasicImportHelper { String scriptPath = getValueByColumnName(header, values, scriptType.getColumnName()); - if (scriptPath == null || scriptPath.isEmpty()) + if (scriptPath != null && !scriptPath.isEmpty()) { - return; - } - - PluginCreation creation = new PluginCreation(); - creation.setName(getScriptName(header, values)); - creation.setScript(this.scripts.get(scriptPath)); - switch (scriptType) { - case VALIDATION_SCRIPT: - creation.setPluginType(PluginType.ENTITY_VALIDATION); - break; - case DYNAMIC_SCRIPT: - creation.setPluginType(PluginType.DYNAMIC_PROPERTY); - break; + String script = this.scripts.get(new File(scriptPath).getName()); + if (script != null) + { + PluginCreation creation = new PluginCreation(); + creation.setName(getScriptName(header, values)); + creation.setScript(script); + switch (scriptType) + { + case VALIDATION_SCRIPT: + creation.setPluginType(PluginType.ENTITY_VALIDATION); + break; + case DYNAMIC_SCRIPT: + creation.setPluginType(PluginType.DYNAMIC_PROPERTY); + break; + } + delayedExecutor.createPlugin(creation); + } } - delayedExecutor.createPlugin(creation); } @Override protected void updateObject(Map<String, Integer> header, List<String> values, int page, int line) { String scriptPath = getValueByColumnName(header, values, scriptType.getColumnName()); - String script = this.scripts.get(scriptPath); - if (script != null) + if (scriptPath != null && !scriptPath.isEmpty()) { - PluginUpdate update = new PluginUpdate(); - PluginPermId permId = new PluginPermId(getScriptName(header, values)); - update.setPluginId(permId); - update.setScript(this.scripts.get(scriptPath)); - delayedExecutor.updatePlugin(update); + String script = this.scripts.get(new File(scriptPath).getName()); + if (script != null) + { + PluginUpdate update = new PluginUpdate(); + PluginPermId permId = new PluginPermId(getScriptName(header, values)); + update.setPluginId(permId); + update.setScript(script); + delayedExecutor.updatePlugin(update); + } } } diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/VocabularyImportHelper.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/VocabularyImportHelper.java index 7554dec7cac9ae9c2da369664f75921719682e81..758795589b87f09ac32e7403a9c48903db57414e 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/VocabularyImportHelper.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/VocabularyImportHelper.java @@ -15,6 +15,9 @@ */ package ch.ethz.sis.openbis.generic.server.xls.importer.helper; +import java.util.List; +import java.util.Map; + import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyCreation; import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.fetchoptions.VocabularyFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.VocabularyPermId; @@ -27,9 +30,7 @@ import ch.ethz.sis.openbis.generic.server.xls.importer.utils.AttributeValidator; import ch.ethz.sis.openbis.generic.server.xls.importer.utils.IAttribute; import ch.ethz.sis.openbis.generic.server.xls.importer.utils.ImportUtils; import ch.ethz.sis.openbis.generic.server.xls.importer.utils.VersionUtils; - -import java.util.List; -import java.util.Map; +import ch.systemsx.cisd.common.exceptions.UserFailureException; public class VocabularyImportHelper extends BasicImportHelper { @@ -79,6 +80,11 @@ public class VocabularyImportHelper extends BasicImportHelper String version = getValueByColumnName(header, values, Attribute.Version); String code = getValueByColumnName(header, values, Attribute.Code); + if (code == null) + { + throw new UserFailureException("Mandatory field is missing or empty: " + Attribute.Code); + } + boolean isInternalNamespace = ImportUtils.isInternalNamespace(code); boolean isSystem = delayedExecutor.isSystem(); boolean canUpdate = (isInternalNamespace == false) || isSystem; diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/VocabularyTermImportHelper.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/VocabularyTermImportHelper.java index cb22b739a744704837de575ce31805d1fd00e251..32d35170e47e690fea96d69042827a7a4428178e 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/VocabularyTermImportHelper.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/VocabularyTermImportHelper.java @@ -15,6 +15,9 @@ */ package ch.ethz.sis.openbis.generic.server.xls.importer.helper; +import java.util.List; +import java.util.Map; + import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyTermCreation; import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.fetchoptions.VocabularyTermFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.VocabularyPermId; @@ -28,9 +31,7 @@ import ch.ethz.sis.openbis.generic.server.xls.importer.utils.AttributeValidator; import ch.ethz.sis.openbis.generic.server.xls.importer.utils.IAttribute; import ch.ethz.sis.openbis.generic.server.xls.importer.utils.ImportUtils; import ch.ethz.sis.openbis.generic.server.xls.importer.utils.VersionUtils; - -import java.util.List; -import java.util.Map; +import ch.systemsx.cisd.common.exceptions.UserFailureException; public class VocabularyTermImportHelper extends BasicImportHelper { @@ -92,6 +93,11 @@ public class VocabularyTermImportHelper extends BasicImportHelper String version = getValueByColumnName(header, values, Attribute.Version); String code = getValueByColumnName(header, values, Attribute.Code); + if (code == null) + { + throw new UserFailureException("Mandatory field is missing or empty: " + Attribute.Code); + } + boolean isInternalNamespace = ImportUtils.isInternalNamespace(code) || ImportUtils.isInternalNamespace(vocabularyCode); boolean isSystem = delayedExecutor.isSystem(); boolean canUpdate = (isInternalNamespace == false) || isSystem; diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/utils/FileServerUtils.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/utils/FileServerUtils.java index e8f8b280404a50993ba94c981ba9ad3ea380e1df..7f461860a818bb2b42b3c7db6aeba328a9762448 100644 --- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/utils/FileServerUtils.java +++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/utils/FileServerUtils.java @@ -5,6 +5,8 @@ import ch.systemsx.cisd.openbis.generic.server.CommonServiceProvider; import java.io.File; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.util.Set; @@ -47,15 +49,27 @@ public class FileServerUtils } } - public static byte[] read(String filePath) throws IOException + public static InputStream read(String src) throws IOException { - return Files.readAllBytes(getFilePath(filePath)); + return Files.newInputStream(getFilePath(src)); } - public static Path write(String filePath, byte[] bytes) throws IOException + public static byte[] readAllBytes(final String src) throws IOException { - Path filePathAsPath = getFilePath(filePath); - Files.createDirectories(filePathAsPath); - return Files.write(filePathAsPath, bytes); + final Path filePathAsPath = getFilePath(src); + return Files.readAllBytes(filePathAsPath); } + + public static long write(final InputStream src, final String dst) throws IOException + { + final Path filePathAsPath = getFilePath(dst); + return Files.copy(src, filePathAsPath); + } + + public static OutputStream newOutputStream(String dst) throws IOException + { + final Path filePathAsPath = getFilePath(dst); + return Files.newOutputStream(filePathAsPath); + } + } diff --git a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadServiceServlet.java b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadServiceServlet.java index d845b16a11d2e9c72ebb8136315c929faf376277..2c1a170dd54b4da4937ac96064247449a1782568 100644 --- a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadServiceServlet.java +++ b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadServiceServlet.java @@ -127,7 +127,7 @@ public final class UploadServiceServlet extends AbstractController // @Override - @RequestMapping({ "/upload", "/openbis/upload" }) + @RequestMapping({ "/upload", "/openbis/upload", "/openbis/openbis/upload" }) protected ModelAndView handleRequestInternal(final HttpServletRequest request, final HttpServletResponse response) throws Exception { diff --git a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/shared/ISessionWorkspaceProvider.java b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/shared/ISessionWorkspaceProvider.java index 7ed1f3ff06893945900508ebd6ec81b50b0a753b..736746dde6b61b3183915f8dff25738e605de97c 100644 --- a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/shared/ISessionWorkspaceProvider.java +++ b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/shared/ISessionWorkspaceProvider.java @@ -31,6 +31,8 @@ public interface ISessionWorkspaceProvider File getSessionWorkspace(String sessionToken); + File getCanonicalFile(String sessionToken, String relativePathToFile) throws IOException; + void deleteSessionWorkspace(String sessionToken); void write(String sessionToken, String relativePathToFile, InputStream inputStream) throws IOException; @@ -39,6 +41,8 @@ public interface ISessionWorkspaceProvider InputStream read(String sessionToken, String relativePathToFile) throws IOException; + byte[] readAllBytes(String sessionToken, String relativePathToFile) throws IOException; + void delete(String sessionToken, String relativePathToFile) throws IOException; } diff --git a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/shared/SessionWorkspaceProvider.java b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/shared/SessionWorkspaceProvider.java index b33d92b9ccf2879974d2b713edab98b214854d7c..a66afc20af4fd2faa89a7943f10caaf19f6ae188 100644 --- a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/shared/SessionWorkspaceProvider.java +++ b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/shared/SessionWorkspaceProvider.java @@ -133,6 +133,14 @@ public class SessionWorkspaceProvider implements ISessionWorkspaceProvider return sessionWorkspace; } + @Override + public File getCanonicalFile(String sessionToken, String relativePathToFile) throws IOException + { + File sessionWorkspace = getSessionWorkspace(sessionToken); + File targetFile = new File(sessionWorkspace, relativePathToFile); + return targetFile.getCanonicalFile(); + } + @Override public void deleteSessionWorkspace(String sessionTokenOrPAT) { @@ -156,6 +164,7 @@ public class SessionWorkspaceProvider implements ISessionWorkspaceProvider public void write(String sessionToken, String relativePathToFile, InputStream inputStream) throws IOException { File sessionWorkspace = getSessionWorkspace(sessionToken); File targetFile = new File(sessionWorkspace, relativePathToFile); + targetFile.getParentFile().mkdirs(); Files.copy(inputStream, targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING); } @@ -172,6 +181,13 @@ public class SessionWorkspaceProvider implements ISessionWorkspaceProvider return Files.newInputStream(targetFile.toPath()); } + @Override + public byte[] readAllBytes(String sessionToken, String relativePathToFile) throws IOException { + File sessionWorkspace = getSessionWorkspace(sessionToken); + File targetFile = new File(sessionWorkspace, relativePathToFile); + return Files.readAllBytes(targetFile.toPath()); + } + @Override public void delete(String sessionToken, String relativePathToFile) throws IOException { File sessionWorkspace = getSessionWorkspace(sessionToken); diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractImportTest.java b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractImportTest.java index f67f997478f3a2de43f15ce8f0dec63faafb78c1..21abc7ef30e554fe6530a67bae9ae1f999f89a51 100644 --- a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractImportTest.java +++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractImportTest.java @@ -18,13 +18,18 @@ package ch.ethz.sis.openbis.systemtest.asapi.v3; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; -import java.io.InputStream; +import java.util.Arrays; +import java.util.UUID; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.BeforeSuite; +import ch.systemsx.cisd.openbis.generic.server.CommonServiceProvider; +import ch.systemsx.cisd.openbis.generic.shared.ISessionWorkspaceProvider; + public class AbstractImportTest extends AbstractTest { @@ -59,20 +64,26 @@ public class AbstractImportTest extends AbstractTest v3api.logout(sessionToken); } - protected static byte[] getFileContent(final String fileName) + protected static String[] uploadToAsSessionWorkspace(final String sessionToken, final String... relativeFilePaths) throws IOException { - try (final InputStream is = AbstractImportTest.class.getResourceAsStream("test_files/import/" + fileName)) - { - if (is == null) - { - throw new RuntimeException(); - } + final String[] canonicalFilePaths = getFilePaths(relativeFilePaths); + final ISessionWorkspaceProvider sessionWorkspaceProvider = CommonServiceProvider.getSessionWorkspaceProvider(); + final String uploadId = UUID.randomUUID().toString(); + final String[] destinations = new String[canonicalFilePaths.length]; - return is.readAllBytes(); - } catch (final IOException e) + for (int i = 0; i < canonicalFilePaths.length; i++) { - throw new RuntimeException(e); + destinations[i] = uploadId + "/" + relativeFilePaths[i]; + sessionWorkspaceProvider.write(sessionToken, destinations[i], new FileInputStream(canonicalFilePaths[i])); } + + return destinations; + } + + private static String[] getFilePaths(final String... fileNames) + { + return Arrays.stream(fileNames).map(fileName -> AbstractImportTest.class.getResource("test_files/import/" + fileName).getPath()) + .toArray(String[]::new); } } diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTest.java b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTest.java index 972d9eced25f0e2c51965d2301e8ff0eb246e290..b229afb708d0239dbe127639d95dfaf0dd7b3116 100644 --- a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTest.java +++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTest.java @@ -20,6 +20,9 @@ import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.fail; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; import java.lang.reflect.Method; import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -161,6 +164,8 @@ import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.common.logging.BufferedAppender; import ch.systemsx.cisd.common.test.AssertionUtil; +import ch.systemsx.cisd.openbis.generic.server.CommonServiceProvider; +import ch.systemsx.cisd.openbis.generic.shared.ISessionWorkspaceProvider; import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationService; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialIdentifier; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy; diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/UncompressedImportTest.java b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/UncompressedImportTest.java index 534803e5b09b244a585a1db87c59fdd44f4bcbbf..94ebd7a52ee8d6d6973dd45965229a55d0dad5ff 100644 --- a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/UncompressedImportTest.java +++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/UncompressedImportTest.java @@ -16,8 +16,8 @@ package ch.ethz.sis.openbis.systemtest.asapi.v3; +import static org.junit.Assert.assertNotNull; import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; import java.util.Arrays; @@ -25,21 +25,17 @@ import java.util.List; import java.util.Set; import java.util.stream.Collectors; +import org.testng.annotations.Test; + +import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.SearchResult; import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSetType; import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.fetchoptions.DataSetTypeFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.search.DataSetTypeSearchCriteria; import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.ExperimentType; import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.fetchoptions.ExperimentTypeFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.search.ExperimentTypeSearchCriteria; -import ch.systemsx.cisd.common.action.IDelegatedAction; -import org.testng.annotations.Test; - -import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.SearchResult; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.IImportData; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportData; import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportFormat; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportScript; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportValue; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.UncompressedImportData; import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportMode; import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.plugin.Plugin; @@ -55,15 +51,18 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.Vocabulary; import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.VocabularyTerm; import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.fetchoptions.VocabularyFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.search.VocabularySearchCriteria; +import ch.systemsx.cisd.common.action.IDelegatedAction; import ch.systemsx.cisd.common.exceptions.UserFailureException; public class UncompressedImportTest extends AbstractImportTest { @Test - public void testDataImport() + public void testDataImport() throws Exception { - final IImportData importData = new UncompressedImportData(ImportFormat.XLS, getFileContent("import.xlsx"), null, null); + final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "import.xlsx"); + + final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles); final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS); v3api.executeImport(sessionToken, importData, importOptions); @@ -85,10 +84,11 @@ public class UncompressedImportTest extends AbstractImportTest } @Test - public void testLargeDataImport() + public void testLargeDataImport() throws Exception { - final UncompressedImportData importData = new UncompressedImportData(ImportFormat.XLS, getFileContent("import_large_cell.xlsx"), null, - List.of(new ImportValue("value-M20.txt", new String(getFileContent("data/value-M20.txt"))))); + final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "import_large_cell.xlsx", "data/value-M20.txt"); + + final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles[0]); final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS); v3api.executeImport(sessionToken, importData, importOptions); @@ -110,9 +110,11 @@ public class UncompressedImportTest extends AbstractImportTest } @Test - public void testImportOptionsUpdateIfExists() + public void testImportOptionsUpdateIfExists() throws Exception { - final IImportData importData = new UncompressedImportData(ImportFormat.XLS, getFileContent("existing_vocabulary.xlsx"), null, null); + final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "existing_vocabulary.xlsx"); + + final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles); final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS); v3api.executeImport(sessionToken, importData, importOptions); @@ -137,9 +139,11 @@ public class UncompressedImportTest extends AbstractImportTest } @Test - public void testImportOptionsIgnoreExisting() + public void testImportOptionsIgnoreExisting() throws Exception { - final IImportData importData = new UncompressedImportData(ImportFormat.XLS, getFileContent("existing_vocabulary.xlsx"), null, null); + final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "existing_vocabulary.xlsx"); + + final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles); final ImportOptions importOptions = new ImportOptions(ImportMode.IGNORE_EXISTING); v3api.executeImport(sessionToken, importData, importOptions); @@ -164,21 +168,23 @@ public class UncompressedImportTest extends AbstractImportTest } @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = ".*FAIL_IF_EXISTS.*") - public void testImportOptionsFailIfExists() + public void testImportOptionsFailIfExists() throws Exception { - final IImportData importData = new UncompressedImportData(ImportFormat.XLS, getFileContent("existing_vocabulary.xlsx"), null, null); + final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "existing_vocabulary.xlsx"); + + final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles); final ImportOptions importOptions = new ImportOptions(ImportMode.FAIL_IF_EXISTS); v3api.executeImport(sessionToken, importData, importOptions); } @Test - public void testWithValidationScript() + public void testWithValidationScript() throws Exception { final String name = "valid.py"; final String source = "print 'Test validation script'"; - final IImportData importData = new UncompressedImportData(ImportFormat.XLS, getFileContent("validation_script.xls"), - List.of(new ImportScript(name, source)), null); + final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "validation_script.xls", "scripts/" + name); + final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles[0]); final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS); v3api.executeImport(sessionToken, importData, importOptions); @@ -203,12 +209,12 @@ public class UncompressedImportTest extends AbstractImportTest } @Test - public void testWithDynamicScript() + public void testWithDynamicScript() throws Exception { final String name = "dynamic.py"; final String source = "1+1"; - final IImportData importData = new UncompressedImportData(ImportFormat.XLS, getFileContent("dynamic_script.xls"), - List.of(new ImportScript(name, source)), null); + final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "dynamic_script.xls", "scripts/" + name); + final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles[0]); final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS); v3api.executeImport(sessionToken, importData, importOptions); @@ -238,9 +244,11 @@ public class UncompressedImportTest extends AbstractImportTest } @Test - public void testInternalTypes_failForNormalUser() + public void testInternalTypes_failForNormalUser() throws Exception { - final IImportData importData = new UncompressedImportData(ImportFormat.XLS, getFileContent("import_internal_type.xlsx"), null, null); + final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "import_internal_type.xlsx"); + + final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles); final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS); assertUserFailureException(new IDelegatedAction() @@ -255,13 +263,15 @@ public class UncompressedImportTest extends AbstractImportTest } @Test - public void testInternalTypes() + public void testInternalTypes() throws Exception { - final IImportData importData = new UncompressedImportData(ImportFormat.XLS, getFileContent("import_internal_type.xlsx"), null, null); - final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS); - final String systemSessionToken = v3api.loginAsSystem(); + final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(systemSessionToken, "import_internal_type.xlsx"); + + final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles); + final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS); + v3api.executeImport(systemSessionToken, importData, importOptions); final DataSetTypeSearchCriteria dataSetTypeSearchCriteria = new DataSetTypeSearchCriteria(); diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/ZipImportTest.java b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/ZipImportTest.java index 43807a6b2b4e0fa69d8351ec9e8cec314725eb12..d2196dd938d69289bccd70265a96d1c1248067a9 100644 --- a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/ZipImportTest.java +++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/ZipImportTest.java @@ -25,19 +25,17 @@ import java.util.List; import java.util.Set; import java.util.stream.Collectors; +import org.testng.annotations.Test; + +import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.SearchResult; import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSetType; import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.fetchoptions.DataSetTypeFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.search.DataSetTypeSearchCriteria; import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.ExperimentType; import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.fetchoptions.ExperimentTypeFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.search.ExperimentTypeSearchCriteria; -import ch.systemsx.cisd.common.action.IDelegatedAction; -import org.testng.annotations.Test; - -import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.SearchResult; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.IImportData; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportData; import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportFormat; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ZipImportData; import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportMode; import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.plugin.Plugin; @@ -53,15 +51,18 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.Vocabulary; import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.VocabularyTerm; import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.fetchoptions.VocabularyFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.search.VocabularySearchCriteria; +import ch.systemsx.cisd.common.action.IDelegatedAction; import ch.systemsx.cisd.common.exceptions.UserFailureException; public class ZipImportTest extends AbstractImportTest { @Test - public void testDataImport() + public void testDataImport() throws Exception { - final IImportData importData = new ZipImportData(ImportFormat.XLS, getFileContent("import.zip")); + final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "import.zip"); + + final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles); final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS); v3api.executeImport(sessionToken, importData, importOptions); @@ -82,9 +83,11 @@ public class ZipImportTest extends AbstractImportTest } @Test - public void testDataImportInternalTypes_failForNormalUser() + public void testDataImportInternalTypes_failForNormalUser() throws Exception { - final IImportData importData = new ZipImportData(ImportFormat.XLS, getFileContent("import_internal_type.zip")); + final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "import_internal_type.zip"); + + final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles); final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS); assertUserFailureException(new IDelegatedAction() @@ -99,13 +102,15 @@ public class ZipImportTest extends AbstractImportTest } @Test - public void testDataImportInternalTypes_systemUser() + public void testDataImportInternalTypes_systemUser() throws Exception { - final IImportData importData = new ZipImportData(ImportFormat.XLS, getFileContent("import_internal_type.zip")); - final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS); - final String systemSessionToken = v3api.loginAsSystem(); + final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(systemSessionToken, "import_internal_type.zip"); + + final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles); + final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS); + v3api.executeImport(systemSessionToken, importData, importOptions); final DataSetTypeSearchCriteria dataSetTypeSearchCriteria = new DataSetTypeSearchCriteria(); @@ -130,7 +135,6 @@ public class ZipImportTest extends AbstractImportTest assertEquals(sampleTypeSearchResult.getTotalCount(), 1); assertEquals(sampleTypeSearchResult.getObjects().get(0).getDescription(), "Internal Sample Type"); - final ExperimentTypeSearchCriteria experimentTypeSearchCriteria = new ExperimentTypeSearchCriteria(); experimentTypeSearchCriteria.withCode().thatEquals("$INTERNAL_EXPERIMENT_TYPE"); @@ -144,9 +148,11 @@ public class ZipImportTest extends AbstractImportTest } @Test - public void testLargeDataImport() + public void testLargeDataImport() throws Exception { - final IImportData importData = new ZipImportData(ImportFormat.XLS, getFileContent("import_large_cell.zip")); + final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "import_large_cell.zip"); + + final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles); final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS); v3api.executeImport(sessionToken, importData, importOptions); @@ -168,9 +174,11 @@ public class ZipImportTest extends AbstractImportTest } @Test - public void testImportOptionsUpdateIfExists() + public void testImportOptionsUpdateIfExists() throws Exception { - final IImportData importData = new ZipImportData(ImportFormat.XLS, getFileContent("existing_vocabulary.zip")); + final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "existing_vocabulary.zip"); + + final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles); final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS); v3api.executeImport(sessionToken, importData, importOptions); @@ -195,9 +203,11 @@ public class ZipImportTest extends AbstractImportTest } @Test - public void testImportOptionsIgnoreExisting() + public void testImportOptionsIgnoreExisting() throws Exception { - final IImportData importData = new ZipImportData(ImportFormat.XLS, getFileContent("existing_vocabulary.zip")); + final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "existing_vocabulary.zip"); + + final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles); final ImportOptions importOptions = new ImportOptions(ImportMode.IGNORE_EXISTING); v3api.executeImport(sessionToken, importData, importOptions); @@ -222,20 +232,24 @@ public class ZipImportTest extends AbstractImportTest } @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = ".*FAIL_IF_EXISTS.*") - public void testImportOptionsFailIfExists() + public void testImportOptionsFailIfExists() throws Exception { - final IImportData importData = new ZipImportData(ImportFormat.XLS, getFileContent("existing_vocabulary.zip")); + final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "existing_vocabulary.zip"); + + final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles); final ImportOptions importOptions = new ImportOptions(ImportMode.FAIL_IF_EXISTS); v3api.executeImport(sessionToken, importData, importOptions); } @Test - public void testWithValidationScript() + public void testWithValidationScript() throws Exception { + final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "validation_script.zip"); + final String name = "valid.py"; final String source = "print 'Test validation script'"; - final IImportData importData = new ZipImportData(ImportFormat.XLS, getFileContent("validation_script.zip")); + final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles); final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS); v3api.executeImport(sessionToken, importData, importOptions); @@ -260,11 +274,13 @@ public class ZipImportTest extends AbstractImportTest } @Test - public void testWithDynamicScript() + public void testWithDynamicScript() throws Exception { + final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "dynamic_script.zip"); + final String name = "dynamic.py"; final String source = "1+1"; - final IImportData importData = new ZipImportData(ImportFormat.XLS, getFileContent("dynamic_script.zip")); + final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles); final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS); v3api.executeImport(sessionToken, importData, importOptions); diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/test_files/import/scripts/dynamic.py b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/test_files/import/scripts/dynamic.py index c040fa67d3452162197945543e1ca9974e202924..07d91dc6abdd2cc89ac1acf5afcdb9bc93838ee9 100644 --- a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/test_files/import/scripts/dynamic.py +++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/test_files/import/scripts/dynamic.py @@ -1 +1 @@ -1+1 +1+1 \ No newline at end of file diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/test_files/import/scripts/valid.py b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/test_files/import/scripts/valid.py new file mode 100644 index 0000000000000000000000000000000000000000..d23f9285861417fe45f0016056e72c385dfc6843 --- /dev/null +++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/test_files/import/scripts/valid.py @@ -0,0 +1 @@ +print 'Test validation script' \ No newline at end of file diff --git a/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/common.js b/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/common.js index aa489331b1f5f1bd2ce33b7cab50f89efc4f1404..26d12018fc51c6536baa5e5f9cde3d2be6ee11de 100644 --- a/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/common.js +++ b/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/common.js @@ -1288,6 +1288,26 @@ define([ 'jquery', 'underscore'], function($, _) { this.assert.ok(false, msg); }; + this.base64ToBlob = (b64Data, contentType='', sliceSize=512) => { + var byteCharacters = atob(b64Data); + var byteArrays = []; + + for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) { + var slice = byteCharacters.slice(offset, offset + sliceSize); + + var byteNumbers = new Array(slice.length); + for (var i = 0; i < slice.length; i++) { + byteNumbers[i] = slice.charCodeAt(i); + } + + var byteArray = new Uint8Array(byteNumbers); + byteArrays.push(byteArray); + } + + var blob = new Blob(byteArrays, {type: contentType}); + return blob; + } + }; return Common; diff --git a/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/dtos.js b/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/dtos.js index 8d498fe2aedd1fa482ee3462643c8a582fe7676c..64d5520347628ad2e6d49483dd02170bfbf1c82c 100644 --- a/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/dtos.js +++ b/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/dtos.js @@ -58,12 +58,9 @@ var fullTypes = [ "as/dto/importer/options/ImportMode", "as/dto/importer/ImportOperation", "as/dto/importer/ImportOperationResult", +"as/dto/importer/ImportResult", +"as/dto/importer/data/ImportData", "as/dto/importer/data/ImportFormat", -"as/dto/importer/data/ZipImportData", -"as/dto/importer/data/UncompressedImportData", -"as/dto/importer/data/ImportValue", -"as/dto/importer/data/ImportScript", -"as/dto/importer/data/IImportData", "as/dto/entitytype/update/IEntityTypeUpdate", "as/dto/entitytype/update/PropertyAssignmentListUpdateValue", "as/dto/entitytype/EntityKind", diff --git a/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/openbis-execute-operations.js b/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/openbis-execute-operations.js index 8f57a107fb9f6b3bc58d7f136d2c10eecced9969..e17ce32cf2ad37119c20a223c966747f6e37dede 100644 --- a/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/openbis-execute-operations.js +++ b/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/openbis-execute-operations.js @@ -709,7 +709,7 @@ define([], function() { this.executeImport = function (importData, importOptions) { return this._executeOperation(new dtos.ImportOperation(importData, importOptions)).then(function (results) { - return results.getResults()[0] + return results.getResults()[0].getImportResult() }) } diff --git a/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/test-import-export.ts b/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/test-import-export.ts index df54153e4ff10d1bec2714c024ff8ce4f57f6598..b6b7f5065f7ef3050ee11cc02e1f7dac048247ee 100644 --- a/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/test-import-export.ts +++ b/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/test-import-export.ts @@ -15,10 +15,10 @@ * */ -import jquery from "./types/jquery" -import underscore from "./types/underscore" -import common from "./types/common" -import openbis from "./types/openbis.esm" +import jquery from './types/jquery' +import underscore from './types/underscore' +import common from './types/common' +import openbis from './types/openbis.esm' exports.default = new Promise((resolve) => { require(["jquery", "underscore", "openbis", "test/common", "test/openbis-execute-operations", "test/dtos"], function ( @@ -29,62 +29,7 @@ exports.default = new Promise((resolve) => { openbisExecuteOperations, dtos ) { - var fileContent = - "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" + var fileContent = "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" var executeModule = function (moduleName: string, facade: openbis.openbis, dtos: openbis.bundle) { QUnit.module(moduleName) @@ -117,14 +62,23 @@ exports.default = new Promise((resolve) => { var c = new common(assert, dtos) var fAction = function (facade: openbis.openbis) { - var importData = new dtos.UncompressedImportData() - importData.setFormat("XLS") - importData.setFile(fileContent) - - var importOptions = new dtos.ImportOptions() - importOptions.setMode("UPDATE_IF_EXISTS") - - return facade.executeImport(importData, importOptions) + var fileName = "model.xlsx" + var data = new window.File([c.base64ToBlob(fileContent)], fileName) + return facade.uploadToSessionWorkspace(data) + .then(function() { + c.ok("uploadToSessionWorkspace") + var importData = new dtos.ImportData() + importData.setFormat("EXCEL") + importData.setSessionWorkspaceFiles([fileName]) + + var importOptions = new dtos.ImportOptions() + importOptions.setMode("UPDATE_IF_EXISTS") + + return facade.executeImport(importData, importOptions) + .then(function() { + c.ok("executeImport") + }) + }) } var fCheck = function (facade: openbis.openbis) { diff --git a/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/types/common.d.ts b/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/types/common.d.ts index e05938aadc3c9957d0f211457fc50b2b54543e10..eea599e1d417a1a8d985ef56e9e33e6ef9b3da7d 100644 --- a/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/types/common.d.ts +++ b/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/types/common.d.ts @@ -152,5 +152,6 @@ export namespace common { ok(msg?): void section(msg): void fail(msg?): void + base64ToBlob(b64Data: string, contentType: string='', sliceSize: number=512): Blob } } diff --git a/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/types/openbis.esm.d.ts b/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/types/openbis.esm.d.ts index 6add41dd7ece762e7136c8d3a9ab1faf1be4a175..7f6dc21ff7eba597609748c9a4e96190f61edc3d 100644 --- a/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/types/openbis.esm.d.ts +++ b/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/types/openbis.esm.d.ts @@ -11139,9 +11139,6 @@ export namespace openbis { getIdentifier(): ObjectIdentifier; } - interface IImportData extends Serializable { - } - interface ILabelHolder { getLabel(): string; @@ -11619,12 +11616,32 @@ export namespace openbis { new <T extends IObjectId>(): IdsSearchCriteria<T>; } + interface ImportData extends Serializable { + + getFormat(): ImportFormat; + + getSessionWorkspaceFiles(): string[]; + + setFormat(arg0: ImportFormat): void; + + setSessionWorkspaceFiles(arg0: string[]): void; + } + + /** + */ + interface ImportDataConstructor { + + new (): ImportData; + + new (arg0: ImportFormat, arg1: string[]): ImportData; + } + /** */ interface ImportFormatObject { /** */ - XLS: ImportFormat<> = "XLS"; + EXCEL: ImportFormat<> = "EXCEL"; } /** @@ -11643,13 +11660,13 @@ export namespace openbis { interface ImportOperation extends Serializable, IOperation { - getImportData(): IImportData; + getImportData(): ImportData; getImportOptions(): ImportOptions; getMessage(): string; - setImportData(arg0: IImportData): void; + setImportData(arg0: ImportData): void; setImportOptions(arg0: ImportOptions): void; } @@ -11660,12 +11677,16 @@ export namespace openbis { new (): ImportOperation; - new (arg0: IImportData, arg1: ImportOptions): ImportOperation; + new (arg0: ImportData, arg1: ImportOptions): ImportOperation; } interface ImportOperationResult extends Serializable, as_dto_common_operation_IOperationResult { + getImportResult(): ImportResult; + getMessage(): string; + + setImportResult(arg0: ImportResult): void; } /** @@ -11673,6 +11694,8 @@ export namespace openbis { interface ImportOperationResultConstructor { new (): ImportOperationResult; + + new (arg0: ImportResult): ImportOperationResult; } interface ImportOptions extends Serializable { @@ -11691,44 +11714,20 @@ export namespace openbis { new (arg0: ImportMode): ImportOptions; } - interface ImportScript extends Serializable { - - getName(): string; - - getSource(): string; - - setName(arg0: string): void; - - setSource(arg0: string): void; - } - - /** - */ - interface ImportScriptConstructor { - - new (): ImportScript; - - new (arg0: string, arg1: string): ImportScript; - } + interface ImportResult extends Serializable { - interface ImportValue extends Serializable { - - getName(): string; - - getValue(): string; - - setName(arg0: string): void; + getObjectIds(): IObjectId[]; - setValue(arg0: string): void; + setObjectIds(arg0: IObjectId[]): void; } /** */ - interface ImportValueConstructor { + interface ImportResultConstructor { - new (): ImportValue; + new (): ImportResult; - new (arg0: string, arg1: string): ImportValue; + new (arg0: IObjectId[]): ImportResult; } interface LabelSearchCriteria extends StringFieldSearchCriteria { @@ -13851,7 +13850,7 @@ export namespace openbis { executeExport(arg1: ExportData, arg2: ExportOptions): Promise<ExportResult>; - executeImport(arg1: IImportData, arg2: ImportOptions): Promise<void>; + executeImport(arg1: ImportData, arg2: ImportOptions): Promise<ImportResult>; executeOperations(arg1: IOperation[], arg2: IOperationExecutionOptions): Promise<IOperationExecutionResults>; @@ -14068,6 +14067,8 @@ export namespace openbis { updateVocabularies(arg1: VocabularyUpdate[]): Promise<void>; updateVocabularyTerms(arg1: VocabularyTermUpdate[]): Promise<void>; + + uploadToSessionWorkspace(arg0: any): Promise<void>; } /** @@ -23027,34 +23028,6 @@ export namespace openbis { new (): UnarchiveDataSetsOperationResult; } - interface UncompressedImportData extends Serializable, IImportData { - - getFile(): string; - - getFormat(): ImportFormat; - - getImportValues(): ImportValue[]; - - getScripts(): ImportScript[]; - - setFile(arg0: string): void; - - setFormat(arg0: ImportFormat): void; - - setImportValues(arg0: ImportValue[]): void; - - setScripts(arg0: ImportScript[]): void; - } - - /** - */ - interface UncompressedImportDataConstructor { - - new (): UncompressedImportData; - - new (arg0: ImportFormat, arg1: string, arg2: ImportScript[], arg3: ImportValue[]): UncompressedImportData; - } - interface UnknownRelatedObjectId extends IObjectId { getRelatedObjectId(): string; @@ -24590,26 +24563,6 @@ export namespace openbis { RICH: XlsTextFormat<> = "RICH"; } - interface ZipImportData extends Serializable, IImportData { - - getFile(): string; - - getFormat(): ImportFormat; - - setFile(arg0: string): void; - - setFormat(arg0: ImportFormat): void; - } - - /** - */ - interface ZipImportDataConstructor { - - new (): ZipImportData; - - new (arg0: ImportFormat, arg1: string): ZipImportData; - } - interface as_dto_common_operation_IOperationResult extends Serializable { getMessage(): string; @@ -25182,13 +25135,13 @@ export namespace openbis { IdSearchCriteria: IdSearchCriteriaConstructor; IdentifierSearchCriteria: IdentifierSearchCriteriaConstructor; IdsSearchCriteria: IdsSearchCriteriaConstructor; + ImportData: ImportDataConstructor; ImportFormat: ImportFormatObject; ImportMode: ImportModeObject; ImportOperation: ImportOperationConstructor; ImportOperationResult: ImportOperationResultConstructor; ImportOptions: ImportOptionsConstructor; - ImportScript: ImportScriptConstructor; - ImportValue: ImportValueConstructor; + ImportResult: ImportResultConstructor; LabelSearchCriteria: LabelSearchCriteriaConstructor; LastNameSearchCriteria: LastNameSearchCriteriaConstructor; LinkedData: LinkedDataConstructor; @@ -25571,7 +25524,6 @@ export namespace openbis { TimeZone: TimeZoneConstructor; UnarchiveDataSetsOperation: UnarchiveDataSetsOperationConstructor; UnarchiveDataSetsOperationResult: UnarchiveDataSetsOperationResultConstructor; - UncompressedImportData: UncompressedImportDataConstructor; UnknownRelatedObjectId: UnknownRelatedObjectIdConstructor; UnlockDataSetsOperation: UnlockDataSetsOperationConstructor; UnlockDataSetsOperationResult: UnlockDataSetsOperationResultConstructor; @@ -25649,7 +25601,6 @@ export namespace openbis { WebAppSettingsSortOptions: WebAppSettingsSortOptionsConstructor; WebAppSettingsUpdateValue: WebAppSettingsUpdateValueConstructor; XlsTextFormat: XlsTextFormatObject; - ZipImportData: ZipImportDataConstructor; as_dto_attachment_Attachment: AttachmentConstructor; as_dto_attachment_create_AttachmentCreation: AttachmentCreationConstructor; as_dto_attachment_fetchoptions_AttachmentFetchOptions: AttachmentFetchOptionsConstructor; @@ -26024,11 +25975,9 @@ export namespace openbis { as_dto_history_id_UnknownRelatedObjectId: UnknownRelatedObjectIdConstructor; as_dto_importer_ImportOperation: ImportOperationConstructor; as_dto_importer_ImportOperationResult: ImportOperationResultConstructor; + as_dto_importer_ImportResult: ImportResultConstructor; + as_dto_importer_data_ImportData: ImportDataConstructor; as_dto_importer_data_ImportFormat: ImportFormatObject; - as_dto_importer_data_ImportScript: ImportScriptConstructor; - as_dto_importer_data_ImportValue: ImportValueConstructor; - as_dto_importer_data_UncompressedImportData: UncompressedImportDataConstructor; - as_dto_importer_data_ZipImportData: ZipImportDataConstructor; as_dto_importer_options_ImportMode: ImportModeObject; as_dto_importer_options_ImportOptions: ImportOptionsConstructor; as_dto_material_Material: MaterialConstructor; @@ -26695,7 +26644,7 @@ MATERIAL : "MATERIAL", SAMPLE : "SAMPLE"} as const const ImportFormat = { -XLS : "XLS"} as const +EXCEL : "EXCEL"} as const const ImportMode = { FAIL_IF_EXISTS : "FAIL_IF_EXISTS", @@ -26979,7 +26928,7 @@ MATERIAL : "MATERIAL", SAMPLE : "SAMPLE"} as const const as_dto_importer_data_ImportFormat = { -XLS : "XLS"} as const +EXCEL : "EXCEL"} as const const as_dto_importer_options_ImportMode = { FAIL_IF_EXISTS : "FAIL_IF_EXISTS", @@ -27882,15 +27831,15 @@ SAMPLE : "SAMPLE"} as const export const IdsSearchCriteria:IdsSearchCriteriaConstructor + export const ImportData:ImportDataConstructor + export const ImportOperation:ImportOperationConstructor export const ImportOperationResult:ImportOperationResultConstructor export const ImportOptions:ImportOptionsConstructor - export const ImportScript:ImportScriptConstructor - - export const ImportValue:ImportValueConstructor + export const ImportResult:ImportResultConstructor export const LabelSearchCriteria:LabelSearchCriteriaConstructor @@ -28624,8 +28573,6 @@ SAMPLE : "SAMPLE"} as const export const UnarchiveDataSetsOperationResult:UnarchiveDataSetsOperationResultConstructor - export const UncompressedImportData:UncompressedImportDataConstructor - export const UnknownRelatedObjectId:UnknownRelatedObjectIdConstructor export const UnlockDataSetsOperation:UnlockDataSetsOperationConstructor @@ -28778,8 +28725,6 @@ SAMPLE : "SAMPLE"} as const export const WebAppSettingsUpdateValue:WebAppSettingsUpdateValueConstructor - export const ZipImportData:ZipImportDataConstructor - export const as_dto_attachment_Attachment:AttachmentConstructor export const as_dto_attachment_create_AttachmentCreation:AttachmentCreationConstructor @@ -29490,13 +29435,9 @@ SAMPLE : "SAMPLE"} as const export const as_dto_importer_ImportOperationResult:ImportOperationResultConstructor - export const as_dto_importer_data_ImportScript:ImportScriptConstructor - - export const as_dto_importer_data_ImportValue:ImportValueConstructor - - export const as_dto_importer_data_UncompressedImportData:UncompressedImportDataConstructor + export const as_dto_importer_ImportResult:ImportResultConstructor - export const as_dto_importer_data_ZipImportData:ZipImportDataConstructor + export const as_dto_importer_data_ImportData:ImportDataConstructor export const as_dto_importer_options_ImportOptions:ImportOptionsConstructor @@ -31466,17 +31407,11 @@ SAMPLE : "SAMPLE"} as const type as_dto_importer_ImportOperationResult = ImportOperationResult - type as_dto_importer_data_IImportData = IImportData + type as_dto_importer_ImportResult = ImportResult - type as_dto_importer_data_ImportFormat = typeof as_dto_importer_data_ImportFormat[keyof typeof as_dto_importer_data_ImportFormat] - - type as_dto_importer_data_ImportScript = ImportScript - - type as_dto_importer_data_ImportValue = ImportValue + type as_dto_importer_data_ImportData = ImportData - type as_dto_importer_data_UncompressedImportData = UncompressedImportData - - type as_dto_importer_data_ZipImportData = ZipImportData + type as_dto_importer_data_ImportFormat = typeof as_dto_importer_data_ImportFormat[keyof typeof as_dto_importer_data_ImportFormat] type as_dto_importer_options_ImportMode = typeof as_dto_importer_options_ImportMode[keyof typeof as_dto_importer_options_ImportMode] diff --git a/test-integration/sourceTest/java/ch/ethz/sis/openbis/systemtests/IntegrationSessionWorkspaceTest.java b/test-integration/sourceTest/java/ch/ethz/sis/openbis/systemtests/IntegrationSessionWorkspaceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..49768482efe4933db4c61dd9f2eaab44133a7552 --- /dev/null +++ b/test-integration/sourceTest/java/ch/ethz/sis/openbis/systemtests/IntegrationSessionWorkspaceTest.java @@ -0,0 +1,90 @@ +package ch.ethz.sis.openbis.systemtests; + +import static ch.ethz.sis.transaction.TransactionTestUtil.TestTransaction; +import static ch.ethz.sis.transaction.TransactionTestUtil.assertTransactions; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; + +import java.io.File; +import java.lang.reflect.Method; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +import javax.sql.DataSource; + +import org.testng.annotations.AfterMethod; +import org.testng.annotations.Test; + +import ch.ethz.sis.openbis.generic.OpenBIS; +import ch.ethz.sis.openbis.generic.asapi.v3.ITransactionCoordinatorApi; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.id.EntityTypePermId; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.Experiment; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.create.ExperimentCreation; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.fetchoptions.ExperimentFetchOptions; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id.ExperimentPermId; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.Project; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.create.ProjectCreation; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.fetchoptions.ProjectFetchOptions; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.id.ProjectIdentifier; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.id.ProjectPermId; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.Space; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.create.SpaceCreation; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.fetchoptions.SpaceFetchOptions; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.id.SpacePermId; +import ch.ethz.sis.openbis.generic.dssapi.v3.dto.datasetfile.fetchoptions.DataSetFileFetchOptions; +import ch.ethz.sis.openbis.generic.dssapi.v3.dto.datasetfile.search.DataSetFileSearchCriteria; +import ch.ethz.sis.openbis.generic.server.asapi.v3.TransactionConfiguration; +import ch.ethz.sis.openbis.generic.server.asapi.v3.TransactionCoordinatorApi; +import ch.ethz.sis.openbis.systemtests.common.AbstractIntegrationTest; +import ch.ethz.sis.transaction.TransactionStatus; + +public class IntegrationSessionWorkspaceTest extends AbstractIntegrationTest +{ + + @Test + public void testUploadToSessionWorkspace() throws Exception + { + final OpenBIS openBIS = createOpenBIS(); + final String sessionToken = openBIS.login(USER, PASSWORD); + + final Path originalFilePath = Path.of("sourceTest/java/tests.xml"); + + // Testing upload + + final String uploadId = openBIS.uploadToSessionWorkspace(originalFilePath); + + // Verifying upload ID + + assertTrue(uploadId.endsWith("tests.xml")); + + // Verifying file info + + final Path uploadedFilePath = Path.of(String.format("targets/sessionWorkspace/%s/tests.xml", sessionToken)); + final File originalFile = originalFilePath.toFile(); + final File uploadedFile = uploadedFilePath.toFile(); + + assertTrue(uploadedFile.exists()); + assertEquals(uploadedFile.length(), originalFile.length()); + + // Verifying file content + + final byte[] originalFileContent = Files.readAllBytes(originalFilePath); + final byte[] uploadedFileContent = Files.readAllBytes(uploadedFilePath); + + assertEquals(uploadedFileContent, originalFileContent); + + openBIS.logout(); + } + +} diff --git a/ui-admin/src/core-plugins/admin/1/as/services/xls-import/xls-import.py b/ui-admin/src/core-plugins/admin/1/as/services/xls-import/xls-import.py index dce1366af7d630109fcc750585e6ee770fa84411..441ff4576e099e134ff8ce110b401fec7368bbbb 100644 --- a/ui-admin/src/core-plugins/admin/1/as/services/xls-import/xls-import.py +++ b/ui-admin/src/core-plugins/admin/1/as/services/xls-import/xls-import.py @@ -1,19 +1,11 @@ -import base64 -from ch.systemsx.cisd.openbis.generic.server.jython.api.v1.impl import MasterDataRegistrationHelper from ch.ethz.sis.openbis.generic.server.xls.importer import ImportOptions from ch.ethz.sis.openbis.generic.server.xls.importer import XLSImport from ch.ethz.sis.openbis.generic.server.xls.importer.enums import ImportModes from ch.systemsx.cisd.common.exceptions import UserFailureException from java.util import ArrayList -from org.apache.commons.io import FileUtils -from java.io import File -from java.lang import Long -from java.lang import System -from java.nio.file import Path -from ch.ethz.sis.openbis.generic.server.asapi.v3.executor.importer import ImportExecutor -def get_update_mode(parameters): - update_mode = parameters.get('update_mode', 'FAIL_IF_EXISTS') +def getMode(parameters): + update_mode = parameters.get('mode', 'FAIL_IF_EXISTS') if update_mode == "IGNORE_EXISTING": return ImportModes.IGNORE_EXISTING elif update_mode == "FAIL_IF_EXISTS": @@ -25,20 +17,16 @@ def get_update_mode(parameters): str(update_mode) if update_mode else 'None')) -def get_import_options(parameters): +def getImportOptions(parameters): options = ImportOptions() - experiments_by_type = parameters.get('experiments_by_type', None) - options.setExperimentsByType(experiments_by_type) - spaces_by_type = parameters.get('spaces_by_type', None) - options.setSpacesByType(spaces_by_type) - definitions_only = parameters.get('definitions_only', False) - options.setDefinitionsOnly(definitions_only) - disallow_creations = parameters.get("disallow_creations", False) - options.setDisallowEntityCreations(disallow_creations) - ignore_versioning = parameters.get('ignore_versioning', False) - options.setIgnoreVersioning(ignore_versioning) - render_result = parameters.get('render_result', True) - options.setRenderResult(render_result) + allowedSampleTypes = parameters.get("allowedSampleTypes") + + options.setExperimentsByType(parameters.get('experimentsByType', None)) + options.setSpacesByType(parameters.get('spacesByType', None)) + options.setDefinitionsOnly(False) + options.setDisallowEntityCreations(False) + options.setIgnoreVersioning(False) + options.setRenderResult(True) return options @@ -47,82 +35,20 @@ def process(context, parameters): result = None if method == "import": - zip = parameters.get('zip', False) - temp = None - zip_bytes = None - if zip: # Zip mode uses xls_base64 for all multiple XLS + script files - zip_bytes = base64.b64decode(parameters.get('xls_base64')) - temp = File.createTempFile("temp", Long.toString(System.nanoTime())) - temp.delete() - temp.mkdir() - tempPath = temp.getAbsolutePath() - MasterDataRegistrationHelper.extractToDestination(zip_bytes, tempPath) - if (len(temp.listFiles()) == 1): - singleFile = temp.listFiles()[0] - if (singleFile.isDirectory()): - temp = singleFile - tempPath = singleFile.getAbsolutePath() - byteArrays = MasterDataRegistrationHelper.getByteArrays(Path.of(tempPath), ".xls") - if len(byteArrays) == 0: - raise UserFailureException('No .xls or .xlsx files found on the root folder of the zip file. This error could be caused by the way the zip file was generated.') - parameters.put('xls', byteArrays) - allScripts = MasterDataRegistrationHelper.getAllScripts(Path.of(tempPath)) - parameters.put('scripts', allScripts) - largeValues = MasterDataRegistrationHelper.getAllLargeValues(Path.of(tempPath)) - parameters.put('values', largeValues) - else: - # Check if xls_base64 is used for a single XLS - xls_base64_string = parameters.get('xls_base64', None) - if xls_base64_string is not None: - parameters.put('xls', [ base64.b64decode(xls_base64_string) ]) - result = _import(context, parameters, zip_bytes) - if temp is not None: - FileUtils.deleteDirectory(temp) + result = _import(context, parameters) return result -def _import(context, parameters, zip_bytes): - """ - Excel import AS service. - For extensive documentation of usage and Excel layout, - please visit https://wiki-bsse.ethz.ch/display/openBISDoc/Excel+import+service +def _import(context, parameters): + fileName = parameters.get("fileName") - :param context: Standard Openbis AS Service context object - :param parameters: Contains two elements - { - 'xls' : excel byte blob, - optional - 'xls_base64' : base64-encoded excel byte blob - optional - 'xls_name': identifier of excel file - mandatory - 'zip' : True / False - optional (default: False) - 'scripts': { - optional - file path: loaded file - }, - 'experiments_by_type', - optional - 'spaces_by_type', - optional - 'definitions_only', - optional (default: False) - 'disallow_creations', - optional (default: False) - 'ignore_versioning', - optional (default: False) - 'render_result', - optional (default: True) - 'update_mode': [IGNORE_EXISTING|FAIL_IF_EXISTS|UPDATE_IF_EXISTS] - optional, default FAIL_IF_EXISTS - This only takes duplicates that are ON THE SERVER - } - :return: Openbis's execute operations result string. It should contain report on what was created. - """ session_token = context.sessionToken api = context.applicationService - scripts = parameters.get('scripts', {}) - values = parameters.get('values', {}) - mode = get_update_mode(parameters) - options = get_import_options(parameters) - xls_name = parameters.get('xls_name', None) + mode = getMode(parameters) + options = getImportOptions(parameters) - importXls = XLSImport(session_token, api, scripts, values, mode, options, xls_name) + importXLS = XLSImport(session_token, api, mode, options, [fileName], False) ids = ArrayList() - xls_byte_arrays = parameters.get('xls', None) - for xls_byte_array in xls_byte_arrays: - ids.addAll(importXls.importXLS(xls_byte_array)) - if zip_bytes is not None: - ImportExecutor.importZipData(zip_bytes) - + ids.addAll(importXLS.start()) return ids diff --git a/ui-admin/src/js/components/tools/form/import/all/ImportAllFormFacade.js b/ui-admin/src/js/components/tools/form/import/all/ImportAllFormFacade.js index c1bf057f5f3d30ef74756bb93a93b0321d6cecb0..5bf59d1a984274045fe2dc47828aecd0c0891717 100644 --- a/ui-admin/src/js/components/tools/form/import/all/ImportAllFormFacade.js +++ b/ui-admin/src/js/components/tools/form/import/all/ImportAllFormFacade.js @@ -3,25 +3,19 @@ import openbis from '@src/js/services/openbis.js' export default class ImportAllFormFacade { async import(file, updateMode) { return new Promise((resolve, reject) => { - const reader = new FileReader() - reader.onload = () => { - const resultBase64 = reader.result.split(',')[1] - const serviceId = new openbis.CustomASServiceCode('xls-import') - const serviceOptions = new openbis.CustomASServiceExecutionOptions() - serviceOptions.withParameter('method', 'import') - serviceOptions.withParameter( - 'zip', - file.name.toLowerCase().endsWith('.zip') - ) - serviceOptions.withParameter('xls_name', 'DEFAULT') - serviceOptions.withParameter('xls_base64', resultBase64) - serviceOptions.withParameter('update_mode', updateMode) - openbis.executeService(serviceId, serviceOptions).then(result => { - resolve(result) - }, reject) - } - reader.onerror = reject - reader.readAsDataURL(file) - }) + openbis.uploadToSessionWorkspace(file) + .then(() => { + const serviceId = new openbis.CustomASServiceCode('xls-import') + const serviceOptions = new openbis.CustomASServiceExecutionOptions() + + serviceOptions.withParameter('method', 'import') + serviceOptions.withParameter('mode', updateMode) + serviceOptions.withParameter('fileName', file.name) + + return openbis.executeService(serviceId, serviceOptions) + .then(result => resolve(result)) + .catch(error => reject(error)) + }, (error) => reject(error)); + }); } } diff --git a/ui-admin/src/js/services/openbis/api.js b/ui-admin/src/js/services/openbis/api.js index d79fc89e1d378fb298b26038aee61949f4ffe308..40bd2e7e6ccd4ead4ec0b886a1a6115020c8105a 100644 --- a/ui-admin/src/js/services/openbis/api.js +++ b/ui-admin/src/js/services/openbis/api.js @@ -252,6 +252,10 @@ class Facade { return this.promise(this.v3.evaluatePlugin(options)) } + uploadToSessionWorkspace(file) { + return this.promise(this.v3.uploadToSessionWorkspace(file)) + } + executeCustomDSSService(serviceId, options) { return this.promise(this.v3.getDataStoreFacade().executeCustomDSSService(serviceId, options)); } diff --git a/ui-eln-lims/src/core-plugins/eln-lims/1/as/services/as-eln-lims-api/script.py b/ui-eln-lims/src/core-plugins/eln-lims/1/as/services/as-eln-lims-api/script.py index 2ab162548baabc0e8cdc6ee51eff4f92fc208e7e..60ea54881c25a362a82f678bf342aef2ec9942ad 100644 --- a/ui-eln-lims/src/core-plugins/eln-lims/1/as/services/as-eln-lims-api/script.py +++ b/ui-eln-lims/src/core-plugins/eln-lims/1/as/services/as-eln-lims-api/script.py @@ -2,15 +2,12 @@ import ch.systemsx.cisd.openbis.generic.server.ComponentNames as ComponentNames import ch.systemsx.cisd.openbis.generic.server.CommonServiceProvider as CommonServiceProvider import ch.ethz.sis.openbis.generic.server.xls.export.XLSExportExtendedService as XLSExportExtendedService import ch.systemsx.cisd.common.exceptions.UserFailureException as UserFailureException -import base64 import json import re import ch.ethz.sis.openbis.generic.server.xls.importer.utils.AttributeValidator as AttributeValidator import ch.ethz.sis.openbis.generic.server.xls.importer.helper.SampleImportHelper as SampleImportHelper import ch.systemsx.cisd.common.logging.LogCategory as LogCategory; import ch.systemsx.cisd.common.logging.LogFactory as LogFactory; -from java.nio.file import Files -from java.io import File isOpenBIS2020 = True; enableNewSearchEngine = isOpenBIS2020; @@ -79,8 +76,6 @@ def process(context, parameters): result = getUserManagementMaintenanceTaskReport(context, parameters) elif method == "removeUserManagementMaintenanceTaskReport": result = removeUserManagementMaintenanceTaskReport(context, parameters) - elif method == "importSamples": - result = importSamples(context, parameters) elif method == "getSamplesImportTemplate": result = getSamplesImportTemplate(context, parameters) elif method == "createSpace": @@ -343,21 +338,6 @@ def _create_cell(row, cell_index, style, value): cell.setCellValue(value) return cell_index + 1 -def importSamples(context, parameters): - sessionKey = parameters.get("sessionKey") - allowedSampleTypes = parameters.get("allowedSampleTypes") - experimentsByType = parameters.get("experimentsByType", {}) - spacesByType = parameters.get("spacesByType", {}) - mode = parameters.get("mode") - barcodeValidationInfo = json.loads(parameters.get("barcodeValidationInfo")) - sessionManager = CommonServiceProvider.getApplicationContext().getBean("session-manager") - sessionWorkspaceProvider = CommonServiceProvider.getApplicationContext().getBean("session-workspace-provider") - workspaceFolder = sessionWorkspaceProvider.getSessionWorkspace(context.getSessionToken()) - uploadedFile = File(workspaceFolder, sessionKey) - bytes = Files.readAllBytes(uploadedFile.toPath()) - results = importData(context, bytes, sessionKey, experimentsByType, spacesByType, mode, False) - return results - def validateExperimentOrSpaceDefined(row_number, properties, mode, experiment, space): if experiment is None and space is None and not mode.startswith("UPDATE"): exp = properties.get("experiment") @@ -380,29 +360,6 @@ def validateBarcode(row_number, properties, barcodeValidationInfo): raise UserFailureException("Error in row %s: custom barcode %s does not match " "the regular expression '%s'." % (row_number, barcode, pattern.pattern)) -def importData(context, bytes, file_name, experimentsByType, spacesByType, mode, definitionsOnly): - from ch.ethz.sis.openbis.generic.asapi.v3.dto.service.id import CustomASServiceCode - from ch.ethz.sis.openbis.generic.asapi.v3.dto.service import CustomASServiceExecutionOptions - from ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id import ExperimentIdentifier - - sessionToken = context.getSessionToken() - api = context.getApplicationService() - props = CustomASServiceExecutionOptions().withParameter('xls', [bytes]) - props.withParameter('method', 'import') - props.withParameter('zip', False) - props.withParameter('xls_name', 'DEFAULT') - props.withParameter('update_mode', mode) - props.withParameter('disallow_creations', mode == 'UPDATE_IF_EXISTS') - props.withParameter('render_result', False) - props.withParameter('ignore_versioning', True) - if definitionsOnly: - props.withParameter('definitions_only', True) - if experimentsByType is not None: - props.withParameter('experiments_by_type', experimentsByType) - if spacesByType is not None: - props.withParameter('spaces_by_type', spacesByType) - return api.executeCustomASService(sessionToken, CustomASServiceCode("xls-import"), props) - def getUserManagementMaintenanceTaskConfig(context, parameters): from ch.systemsx.cisd.common.filesystem import FileUtilities diff --git a/ui-eln-lims/src/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/server/ServerFacade.js b/ui-eln-lims/src/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/server/ServerFacade.js index 026ab63b8ea644509f599c92da9ff30fcaa5c585..188deda519f031916000c14027c4a62693ab329c 100644 --- a/ui-eln-lims/src/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/server/ServerFacade.js +++ b/ui-eln-lims/src/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/server/ServerFacade.js @@ -120,19 +120,16 @@ function ServerFacade(openbisServer) { }); } - this.registerSamples = function(allowedSampleTypes, experimentsByType, spacesByType, barcodeValidationInfo, sessionKey, callback) { - this.customELNASAPI({ - "method" : "importSamples", - "allowedSampleTypes" : allowedSampleTypes, - "experimentsByType" : experimentsByType, - "spacesByType" : spacesByType, - "barcodeValidationInfo" : barcodeValidationInfo, - "mode" : "FAIL_IF_EXISTS", - "sessionKey" : sessionKey - }, function(result) { - callback(result) - }, true); - } + this.importSamples = function(mode, sessionKey, allowedSampleTypes, experimentsByType, spacesByType, callback) { + this.customASService({ + "method" : "import", + "mode" : mode, + "fileName" : sessionKey, + "allowedSampleTypes" : allowedSampleTypes, + "experimentsByType" : experimentsByType, + "spacesByType" : spacesByType, + }, callback, "xls-import", null, true); + } this.deleteSpace = function(code, reason, callback) { this.customELNASAPI({ @@ -144,18 +141,6 @@ function ServerFacade(openbisServer) { }); } - this.updateSamples = function(allowedSampleTypes, barcodeValidationInfo, sessionKey, callback) { - this.customELNASAPI({ - "method" : "importSamples", - "allowedSampleTypes" : allowedSampleTypes, - "barcodeValidationInfo" : barcodeValidationInfo, - "mode" : "UPDATE_IF_EXISTS", - "sessionKey" : sessionKey - }, function(result) { - callback(result) - }, true); - } - this.getSamplesImportTemplate = function(allowedSampleTypes, templateType, importMode, callback) { this.customELNASAPI({ "method" : "getSamplesImportTemplate", diff --git a/ui-eln-lims/src/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SampleTable/SampleTableController.js b/ui-eln-lims/src/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SampleTable/SampleTableController.js index baed546316871ea84500080ab4d3ba51291db8e8..c9cc4f1e290e5b9e1f08cc2634018cdcdc75259d 100644 --- a/ui-eln-lims/src/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SampleTable/SampleTableController.js +++ b/ui-eln-lims/src/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SampleTable/SampleTableController.js @@ -173,13 +173,13 @@ function SampleTableController(parentController, title, experimentIdentifier, pr var allowSampleTypeSelection = experimentIdentifier == null; var batchController = new BatchController(title, "REGISTRATION", allowedSampleTypes, allowSampleTypeSelection, function(file, selectedSampleTypes) { Util.blockUI(); - mainController.serverFacade.fileUpload(file, function() { - mainController.serverFacade.registerSamples(selectedSampleTypes, experimentsByType, spacesByType, - _this.getBarcodeValidationInfo(), file.name, - function(result) { + mainController.openbisV3.uploadToSessionWorkspace(file) + .done(function() { + mainController.serverFacade.importSamples("FAIL_IF_EXISTS", file.name, selectedSampleTypes, experimentsByType, spacesByType, + function(result) { _this._handleResult(result, "created", experimentIdentifier); - }); - }); + }); + }); }); batchController.init(); } @@ -196,11 +196,11 @@ function SampleTableController(parentController, title, experimentIdentifier, pr var allowSampleTypeSelection = experimentIdentifier == null; var batchController = new BatchController(title, "UPDATE", allowedSampleTypes, allowSampleTypeSelection, function(file, selectedSampleTypes) { Util.blockUI(); - mainController.serverFacade.fileUpload(file, function() { - mainController.serverFacade.updateSamples(selectedSampleTypes, - _this.getBarcodeValidationInfo(), file.name, - function(result) { - _this._handleResult(result, "updated", experimentIdentifier); + mainController.openbisV3.uploadToSessionWorkspace(file) + .done(function() { + mainController.serverFacade.importSamples("UPDATE_IF_EXISTS", file.name, selectedSampleTypes, experimentsByType, spacesByType, + function(result) { + _this._handleResult(result, "updated", experimentIdentifier); }); }); });