From ed3a13109499a6b9aa4de3dd313f5f096e1a09b7 Mon Sep 17 00:00:00 2001 From: juanf <juanf@ethz.ch> Date: Mon, 27 Nov 2023 16:15:18 +0100 Subject: [PATCH] SSDM-14137: make storage positions be inside a collection --- .../generic/server/hotfix/ELNFixes.java | 140 ++++++++++++++++++ .../1/as/master-data/common-data-model.xls | Bin 75776 -> 75776 bytes .../SampleForm/widgets/StorageListView.js | 6 + 3 files changed, 146 insertions(+) diff --git a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/hotfix/ELNFixes.java b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/hotfix/ELNFixes.java index 72a91ed2c67..b9ba0f449a6 100644 --- a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/hotfix/ELNFixes.java +++ b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/hotfix/ELNFixes.java @@ -18,8 +18,25 @@ package ch.systemsx.cisd.openbis.generic.server.hotfix; import static ch.systemsx.cisd.common.spring.ExposablePropertyPlaceholderConfigurer.PROPERTY_CONFIGURER_BEAN_NAME; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Set; +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.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.ExperimentIdentifier; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id.IExperimentId; +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.IProjectId; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.id.ProjectIdentifier; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.Space; import org.apache.log4j.Logger; import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.SearchResult; @@ -43,6 +60,7 @@ public class ELNFixes { public static void beforeUpgrade(String sessionToken) throws Exception { operationLog.info("ELNFixes beforeUpgrade START"); IApplicationServerInternalApi api = CommonServiceProvider.getApplicationServerApi(); + storageCollectionIntroduction(sessionToken, api); storageValidationLevelFix(sessionToken, api); nameNoRTFFix(sessionToken, api); // TODO(alaskowski): SSDM-13831: Do migration here!!! @@ -155,4 +173,126 @@ public class ELNFixes { operationLog.info(String.format("ELNFixes fixProperties for propertiesTable %s", propertiesTable)); } + private static void storageCollectionIntroduction(String sessionToken, + IApplicationServerInternalApi api) + { + SampleSearchCriteria criteria = new SampleSearchCriteria(); + criteria.withType().withCode().thatEquals("STORAGE_POSITION"); + + SampleFetchOptions options = new SampleFetchOptions(); + options.withSpace(); + options.withExperiment(); + options.withProject(); + + SearchResult<Sample> storagePositionResults = api.searchSamples(sessionToken, criteria, options); + + Set<ProjectIdentifier> createdProjects = new HashSet<>(); + Set<ExperimentIdentifier> createdExperiments = new HashSet<>(); + + List<SampleUpdate> storagePositionUpdates = new ArrayList<>(); + + for (Sample storagePosition:storagePositionResults.getObjects()) { + Space space = storagePosition.getSpace(); + String spaceCode = space.getCode(); + String postFix = ""; + + if (spaceCode.startsWith("STORAGE") && spaceCode.length() > "STORAGE".length()) + { + int start = spaceCode.indexOf("_"); + postFix = spaceCode.substring(start + 1); + } + + ProjectIdentifier projectIdentifier = null; + + if (storagePosition.getProject() == null) + { + String projectCode = "STORAGE_POSITIONS"; + if (!postFix.isBlank()) { + projectCode += "_" + postFix; + } + projectIdentifier = new ProjectIdentifier(spaceCode, projectCode); + + if (createdProjects.contains(projectIdentifier) == false) + { + Map<IProjectId, Project> projects = + api.getProjects(sessionToken, Arrays.asList(projectIdentifier), + new ProjectFetchOptions()); + + System.out.println("PROJECT [FETCH]: " + projectIdentifier + " " + projects.size() + " " + Thread.currentThread().getName()); + + if (projects.size() == 1) { + createdProjects.add(projectIdentifier); + } + } + + if (createdProjects.contains(projectIdentifier) == false) + { + ProjectCreation creation = new ProjectCreation(); + creation.setSpaceId(space.getPermId()); + creation.setCode(projectCode); + System.out.println("PROJECT [CREATION]: " + creation.getSpaceId() + " " + projectCode + " " + Thread.currentThread().getName()); + api.createProjects(sessionToken, Arrays.asList(creation)); + createdProjects.add(projectIdentifier); + } + } else { + projectIdentifier = storagePosition.getProject().getIdentifier(); + } + + ExperimentIdentifier experimentIdentifier; + + if (storagePosition.getExperiment() == null) + { + String experimentCode = "STORAGE_POSITIONS_COLLECTION"; + if (!postFix.isBlank()) { + experimentCode += "_" + postFix; + } + String experimentType = "COLLECTION"; + + experimentIdentifier = new ExperimentIdentifier(spaceCode, projectIdentifier.getIdentifier().substring(projectIdentifier.getIdentifier().lastIndexOf('/') + 1), experimentCode); + + if (createdExperiments.contains(experimentIdentifier) == false) + { + Map<IExperimentId, Experiment> experiments = + api.getExperiments(sessionToken, Arrays.asList(experimentIdentifier), + new ExperimentFetchOptions()); + + System.out.println("EXPERIMENT [FETCH]: " + experimentIdentifier + " " + experiments.size() + " " + Thread.currentThread().getName()); + + if (experiments.size() == 1) { + createdExperiments.add(experimentIdentifier); + } + } + + if (createdExperiments.contains(experimentIdentifier) == false) + { + ExperimentCreation creation = new ExperimentCreation(); + creation.setProjectId(projectIdentifier); + creation.setCode(experimentCode); + creation.setTypeId(new EntityTypePermId(experimentType, EntityKind.EXPERIMENT)); + System.out.println("EXPERIMENT [CREATION]: " + creation.getProjectId() + " " + experimentCode + " " + Thread.currentThread().getName()); + api.createExperiments(sessionToken, Arrays.asList(creation)); + createdExperiments.add(experimentIdentifier); + } + } else { + experimentIdentifier = storagePosition.getExperiment().getIdentifier(); + } + + SampleUpdate sampleUpdate = new SampleUpdate(); + sampleUpdate.setSampleId(storagePosition.getPermId()); + sampleUpdate.setExperimentId(experimentIdentifier); + + storagePositionUpdates.add(sampleUpdate); + + if (storagePositionUpdates.size() > 1000) { + api.updateSamples(sessionToken, storagePositionUpdates); + storagePositionUpdates.clear(); + } + } + + if (storagePositionUpdates.isEmpty() == false) { + api.updateSamples(sessionToken, storagePositionUpdates); + storagePositionUpdates.clear(); + } + } + } diff --git a/ui-eln-lims/src/core-plugins/eln-lims/1/as/master-data/common-data-model.xls b/ui-eln-lims/src/core-plugins/eln-lims/1/as/master-data/common-data-model.xls index 86a4612971080b10dfbf33ebaa8b30de2430e281..d00993ab3e5d6e2edf97a7eb5d7f79cab09d8828 100644 GIT binary patch delta 2132 zcmaJ@U1%It6#nk)>`!8vNg{>P#F`Y_TCiBPKT&JVZnn{A%%)9jlD2kdNOm`Ag28Mb zDhQK4=!+u4h~SIhgAWP?$zlYHdGe{E^u-2(iXc7|>kn*$B8q<J&g@J#S=@oU`<-*{ zIp6)xxsxniH<zxPAJ3b~rNYXa>7I43Y`$s?{^I>*&b1!cQ&``%u9oh;U%tI^d~uVh zQjIUF&9-uKtF4;)QKkNMZ!27C8LWKYTs&-Sx4nVB+2p&Om*aq4S?Rm6)7=R?I69U) zm450(?K?k`8yy@Q%ngsW1A#BHb<lQkVbLiS%H1Oi<=Km~3on+B{$G}@dGr0bp`jD~ ztnuV<SA!anU%UNsQMK;=h57lylvJ*~arWnJM`jf8vIG1y3;gjCu>Ue};4R?8_ka(s z0Pa;Fc@6mL8=(3FaP=mzcB^t__8w&(vXJn;zR(%}sLO)k{d(a`HB<R)?mO3Q!voCA zkFt<5+HjI+v+Yy^+nBb=8tr|)f$emIz2i}w8y22u5IEVucBX;tT$C`(_ky;)!Zjjz ze#_pbHst-l%JQxEW9~m_h8)*|)bWubIvXN`Nb32%7&4e*0YM^07HO`^NDwLd#4fUA zk>R?kkwT7-p?xBc1(O-XciPpPGJ#Wc%A%92q#390X>1RQjVpsbJ47-1IPgKFi4hzR zkO-T>;ULR|uFxMMgT5mna${tZ4WUWr-XM+i!XgR3#3a*L5cWcCl4LA>P9I4YQA3dE zXhFK+BiSc?@R97RDSbx8TtexGI7Q?v9^oo-p3}VjU#UP?Nt(sOTvyS`627oG3{z0a zAZ0Aw9@%$ZnRrgyr9u`Dah0e%_tjK(1sZqAoL4bA4~C&8ksT<KS8<{zLSF*?I2NKL z(c>XX5j_^7CJcqm%ByCgf}eAU<?kXah9z2vW<s=$h}S>h-AXhUB8zCAXbs2kS_<g$ z{;u{6_F@OR_zdvr<+B^zw8%}jNvA`%iJOAk?`T{78)3?i^JZ@EbL%}t?Ww<FrA=8y zVO#fZm>wU=%sm<+xk65G3Y$HO=Fz6W{^Z7u6tg7u68bmAR!OAsEK)(rCN{d4DL==3 zu)ST?eXh+TSvVQSx8WH+?K<AkgmM7|M^Eq35Zy`0sUzgn5pq;Q^N~Y2N*Ejp7&xlg z`=YwXbwUmjBSJ<4J*7FwU{0ypKu_z4+CWb;Lf#b7Ko{t@@QL(``wHPeOCzFzE^?n9 z=-v9T#kzqmh6BCIsVI5}H|}*yn#u^12+b1XGrEY6YI4XOD``10TKc3WQR2L&dH-7I zv$Vt_@){@WTLZX+WxNy2+yssr9au>WuudP3ARqqi#p~X+jUBD>65z4;GLT>1?;AIk V|Gc?Bk$-!d{~~<)TaRi_{0E`wW5xgg delta 1825 zcmZuyTWAzl82--e?CxYWnIvsRyr72G8zS}+HL;brE~1Gw>m??{>`r2Km)Z?@dx;=S zUixIAg?TR2cOS%U6%+%44~ihZR4JuJ5NtyfDXA9((eFPqd$t>Q4tv<|zn$;DoSCV6 z_S8N5;)I?2aoJ4w%)h?}r|s`7_et>DF1NUkMWRmJ{U_AKPt6lm=HjQ+eA(&b`?5Lb zk#Z)ttZaVe|1wbdD^=>W2EAZc&#~kmOU}fB;mYNn`%5alBeTt$OA5F)3amK>be#ms zQ^4^bfZ3mbzb^nct^#{*1MY7?=R;s_1~@-kDSx|M*=t=`!T05*aV&C?2riWGs8VHe z;!odi#|Fmbqg*&vEA|u3mmO#zJE&!c>U;&Yqh2=9!1r*?&Nl}SHZUA&ARDeZ8{Z>Z zc9wfBk&y<zx%cdrw<52F^{l<nxia$fe9Tu?0tZwKX}m!Sl6VF?xQqOtQjuH&WRT`Q zO{+tc_j6g=M~dLWCOOd!XrFYXlVW7Bl)FSfOx<pLM9UCa$oLpFFh(WEB2wDOVta(7 zd}(w>VFvXPI}Ng^+iXybWHJWX)UA%9NWoo5EIEFNQC#@KFoYJN<PstYBUuZQu4M2z zcd5#-K0f^CMD>v#W$+pIX|&)7Eu=pE*vGm^1nHNHaS{=~5oP0REzkMd@l)<%mZM{> zTsdX^uUt7cDT7VM(k2>>GRvtr(N{*7z)pN=P?BhyK@L&3L4FhVnxf}ail}IUE+8ry zw2<f<gPMtWS0majL}i0qqKOFQb+z_I2j-bl8eIm(vV>#CRJv8|WS%*NJ&#)s=Qu$W zj#yqLu>*Z@^x=8c#L{kM$m{qR`QY_`Yy3R#yNmtCz7@S(ZQ9<`g!&^29tpYFVvt;f zDj$z+s`2sa_;?W?>6)h*d=WA5R4VxS`6nNEhQkBS@!2L|Q*d)`RbL8=v5adM*H(03 zCGkUC((k7+#+d((IjUv#*MD5gHUt})Ywd0e7l}|C)iIr`jNF*2j;h3~jp|Wa)Q_sf zcJV7~Cw}8*R14a#I;jQv=}GO-MJ?2gYQc=^G!rcZr57vwqNb8%5TRMrb0CL=s9JWp zJw;viv~F=ylPIbMMAKMEovT|Z&3r)H3C7DtMI6F*s~wjUGU`2yEKeJM=bToY3!Il9 nw#eyB3t7bv!P{W{%llVOtXAFX(yN(u3EYzJ-IZsnR9oU5BR42m diff --git a/ui-eln-lims/src/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SampleForm/widgets/StorageListView.js b/ui-eln-lims/src/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SampleForm/widgets/StorageListView.js index d1100528832..820132f2e90 100644 --- a/ui-eln-lims/src/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SampleForm/widgets/StorageListView.js +++ b/ui-eln-lims/src/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SampleForm/widgets/StorageListView.js @@ -166,6 +166,7 @@ function StorageListView(storageListController, storageListModel) { code : uuid, identifier : null, sampleTypeCode : "STORAGE_POSITION", + experimentIdentifier: null, properties : {} }; _this._storageListModel.sample.children.push(newChildSample); @@ -244,6 +245,11 @@ function StorageListView(storageListController, storageListModel) { if(sampleChild.newSampleJustCreated) { sampleChild.identifier = IdentifierUtil.getSampleIdentifier(storageSpaceCode, null, sampleChild.code); delete sampleChild.newSampleJustCreated; + var postFix = ""; + if(storageSpaceCode.length > "STORAGE".length) { + postFix = storageSpaceCode.substring("STORAGE".length + 1); + } + sampleChild.experimentIdentifier = "/" + storageSpaceCode + "/STORAGE_POSITIONS" + postFix + "/STORAGE_POSITIONS_COLLECTION" + postFix; } else { // On update the identifier should be set, fail if not } -- GitLab