6178 |
23 Mar 21 |
nicklas |
1 |
package net.sf.basedb.reggie.servlet; |
6178 |
23 Mar 21 |
nicklas |
2 |
|
6965 |
10 Jan 23 |
nicklas |
3 |
import java.io.ByteArrayInputStream; |
6998 |
20 Jan 23 |
nicklas |
4 |
import java.io.ByteArrayOutputStream; |
6178 |
23 Mar 21 |
nicklas |
5 |
import java.io.IOException; |
6199 |
08 Apr 21 |
nicklas |
6 |
import java.util.ArrayList; |
6896 |
28 Nov 22 |
nicklas |
7 |
import java.util.Arrays; |
6199 |
08 Apr 21 |
nicklas |
8 |
import java.util.Collections; |
6929 |
02 Dec 22 |
nicklas |
9 |
import java.util.Date; |
6582 |
11 Feb 22 |
nicklas |
10 |
import java.util.HashSet; |
6965 |
10 Jan 23 |
nicklas |
11 |
import java.util.LinkedHashMap; |
7173 |
17 May 23 |
nicklas |
12 |
import java.util.LinkedHashSet; |
6178 |
23 Mar 21 |
nicklas |
13 |
import java.util.List; |
6965 |
10 Jan 23 |
nicklas |
14 |
import java.util.Map; |
6582 |
11 Feb 22 |
nicklas |
15 |
import java.util.Set; |
6965 |
10 Jan 23 |
nicklas |
16 |
import java.util.TreeMap; |
7184 |
22 May 23 |
nicklas |
17 |
import java.util.regex.Matcher; |
7184 |
22 May 23 |
nicklas |
18 |
import java.util.regex.Pattern; |
6178 |
23 Mar 21 |
nicklas |
19 |
|
6178 |
23 Mar 21 |
nicklas |
20 |
import javax.servlet.ServletException; |
6178 |
23 Mar 21 |
nicklas |
21 |
import javax.servlet.http.HttpServlet; |
6178 |
23 Mar 21 |
nicklas |
22 |
import javax.servlet.http.HttpServletRequest; |
6178 |
23 Mar 21 |
nicklas |
23 |
import javax.servlet.http.HttpServletResponse; |
6178 |
23 Mar 21 |
nicklas |
24 |
|
7025 |
08 Feb 23 |
nicklas |
25 |
import org.apache.commons.lang3.time.FastDateFormat; |
6178 |
23 Mar 21 |
nicklas |
26 |
import org.json.simple.JSONArray; |
6178 |
23 Mar 21 |
nicklas |
27 |
import org.json.simple.JSONObject; |
6965 |
10 Jan 23 |
nicklas |
28 |
import org.json.simple.parser.JSONParser; |
6178 |
23 Mar 21 |
nicklas |
29 |
|
6734 |
09 May 22 |
nicklas |
30 |
import net.sf.basedb.clients.web.util.HTML; |
7173 |
17 May 23 |
nicklas |
31 |
import net.sf.basedb.core.BioPlate; |
7173 |
17 May 23 |
nicklas |
32 |
import net.sf.basedb.core.BioWell; |
6178 |
23 Mar 21 |
nicklas |
33 |
import net.sf.basedb.core.DbControl; |
6960 |
13 Dec 22 |
nicklas |
34 |
import net.sf.basedb.core.File; |
6178 |
23 Mar 21 |
nicklas |
35 |
import net.sf.basedb.core.FileServer; |
7189 |
22 May 23 |
nicklas |
36 |
import net.sf.basedb.core.Hardware; |
6736 |
10 May 22 |
nicklas |
37 |
import net.sf.basedb.core.ItemList; |
6178 |
23 Mar 21 |
nicklas |
38 |
import net.sf.basedb.core.ItemNotFoundException; |
6582 |
11 Feb 22 |
nicklas |
39 |
import net.sf.basedb.core.ItemQuery; |
6583 |
11 Feb 22 |
nicklas |
40 |
import net.sf.basedb.core.ItemSubtype; |
6211 |
14 Apr 21 |
nicklas |
41 |
import net.sf.basedb.core.Job; |
7173 |
17 May 23 |
nicklas |
42 |
import net.sf.basedb.core.MeasuredBioMaterial; |
6960 |
13 Dec 22 |
nicklas |
43 |
import net.sf.basedb.core.Path; |
6211 |
14 Apr 21 |
nicklas |
44 |
import net.sf.basedb.core.Protocol; |
6582 |
11 Feb 22 |
nicklas |
45 |
import net.sf.basedb.core.Sample; |
6178 |
23 Mar 21 |
nicklas |
46 |
import net.sf.basedb.core.SessionControl; |
6898 |
29 Nov 22 |
nicklas |
47 |
import net.sf.basedb.core.SimpleProgressReporter; |
6211 |
14 Apr 21 |
nicklas |
48 |
import net.sf.basedb.core.Software; |
6734 |
09 May 22 |
nicklas |
49 |
import net.sf.basedb.core.Subtypable; |
6582 |
11 Feb 22 |
nicklas |
50 |
import net.sf.basedb.core.Type; |
6582 |
11 Feb 22 |
nicklas |
51 |
import net.sf.basedb.core.query.Annotations; |
6582 |
11 Feb 22 |
nicklas |
52 |
import net.sf.basedb.core.query.Expressions; |
6582 |
11 Feb 22 |
nicklas |
53 |
import net.sf.basedb.core.query.Hql; |
7173 |
17 May 23 |
nicklas |
54 |
import net.sf.basedb.core.query.Orders; |
6582 |
11 Feb 22 |
nicklas |
55 |
import net.sf.basedb.core.query.Restrictions; |
6211 |
14 Apr 21 |
nicklas |
56 |
import net.sf.basedb.opengrid.JobDefinition; |
6178 |
23 Mar 21 |
nicklas |
57 |
import net.sf.basedb.opengrid.OpenGrid; |
6178 |
23 Mar 21 |
nicklas |
58 |
import net.sf.basedb.opengrid.OpenGridCluster; |
6178 |
23 Mar 21 |
nicklas |
59 |
import net.sf.basedb.opengrid.RemoteHost; |
6178 |
23 Mar 21 |
nicklas |
60 |
import net.sf.basedb.opengrid.RemoteSession; |
6178 |
23 Mar 21 |
nicklas |
61 |
import net.sf.basedb.opengrid.config.ConnectionInfo; |
6929 |
02 Dec 22 |
nicklas |
62 |
import net.sf.basedb.opengrid.filetransfer.FileMetaData; |
6178 |
23 Mar 21 |
nicklas |
63 |
import net.sf.basedb.opengrid.service.OpenGridService; |
6178 |
23 Mar 21 |
nicklas |
64 |
import net.sf.basedb.reggie.JsonUtil; |
6178 |
23 Mar 21 |
nicklas |
65 |
import net.sf.basedb.reggie.Reggie; |
7032 |
10 Feb 23 |
nicklas |
66 |
import net.sf.basedb.reggie.activity.ActivityDef; |
6178 |
23 Mar 21 |
nicklas |
67 |
import net.sf.basedb.reggie.counter.CounterService; |
6210 |
14 Apr 21 |
nicklas |
68 |
import net.sf.basedb.reggie.dao.Annotationtype; |
6210 |
14 Apr 21 |
nicklas |
69 |
import net.sf.basedb.reggie.dao.BiomaterialList; |
6582 |
11 Feb 22 |
nicklas |
70 |
import net.sf.basedb.reggie.dao.Case; |
6215 |
16 Apr 21 |
nicklas |
71 |
import net.sf.basedb.reggie.dao.DemuxedSequences; |
6178 |
23 Mar 21 |
nicklas |
72 |
import net.sf.basedb.reggie.dao.Fileserver; |
6582 |
11 Feb 22 |
nicklas |
73 |
import net.sf.basedb.reggie.dao.NoSpecimen; |
6178 |
23 Mar 21 |
nicklas |
74 |
import net.sf.basedb.reggie.dao.ReggieRole; |
6736 |
10 May 22 |
nicklas |
75 |
import net.sf.basedb.reggie.dao.Rna; |
6495 |
01 Dec 21 |
nicklas |
76 |
import net.sf.basedb.reggie.dao.SpecimenTube; |
6582 |
11 Feb 22 |
nicklas |
77 |
import net.sf.basedb.reggie.dao.Subtype; |
6211 |
14 Apr 21 |
nicklas |
78 |
import net.sf.basedb.reggie.grid.ImportFastqJobCreator; |
6178 |
23 Mar 21 |
nicklas |
79 |
import net.sf.basedb.reggie.grid.ScriptUtil; |
6498 |
01 Dec 21 |
nicklas |
80 |
import net.sf.basedb.reggie.plugins.ExternalSpecimenImporter; |
7139 |
27 Apr 23 |
nicklas |
81 |
import net.sf.basedb.reggie.plugins.TransportBoxImporter; |
6498 |
01 Dec 21 |
nicklas |
82 |
import net.sf.basedb.reggie.plugins.ExternalSpecimenImporter.ImportedItems; |
7191 |
23 May 23 |
nicklas |
83 |
import net.sf.basedb.reggie.plugins.TransportBoxImporter.Box; |
7139 |
27 Apr 23 |
nicklas |
84 |
import net.sf.basedb.reggie.plugins.TransportBoxImporter.SampleEntry; |
6734 |
09 May 22 |
nicklas |
85 |
import net.sf.basedb.reggie.plugins.cmd.EndPoint; |
6929 |
02 Dec 22 |
nicklas |
86 |
import net.sf.basedb.reggie.plugins.cmd.ImportContext; |
6199 |
08 Apr 21 |
nicklas |
87 |
import net.sf.basedb.reggie.plugins.cmd.JsonFile; |
6341 |
29 Jun 21 |
nicklas |
88 |
import net.sf.basedb.reggie.plugins.cmd.MainInfo; |
6341 |
29 Jun 21 |
nicklas |
89 |
import net.sf.basedb.reggie.plugins.cmd.ScanBIdRef; |
6341 |
29 Jun 21 |
nicklas |
90 |
import net.sf.basedb.reggie.plugins.cmd.ScanBIdRef.SampleIdType; |
6965 |
10 Jan 23 |
nicklas |
91 |
import net.sf.basedb.util.FileUtil; |
6212 |
14 Apr 21 |
nicklas |
92 |
import net.sf.basedb.util.Values; |
6178 |
23 Mar 21 |
nicklas |
93 |
import net.sf.basedb.util.error.ThrowableUtil; |
6178 |
23 Mar 21 |
nicklas |
94 |
|
6178 |
23 Mar 21 |
nicklas |
95 |
|
6498 |
01 Dec 21 |
nicklas |
96 |
public class ExternalSpecimenServlet |
6178 |
23 Mar 21 |
nicklas |
97 |
extends HttpServlet |
6178 |
23 Mar 21 |
nicklas |
98 |
{ |
6178 |
23 Mar 21 |
nicklas |
99 |
|
6178 |
23 Mar 21 |
nicklas |
100 |
private static final long serialVersionUID = 2213869286902406649L; |
6178 |
23 Mar 21 |
nicklas |
101 |
|
6498 |
01 Dec 21 |
nicklas |
102 |
public ExternalSpecimenServlet() |
6178 |
23 Mar 21 |
nicklas |
103 |
{} |
6178 |
23 Mar 21 |
nicklas |
104 |
|
7184 |
22 May 23 |
nicklas |
105 |
@SuppressWarnings("unchecked") |
6178 |
23 Mar 21 |
nicklas |
106 |
@Override |
6178 |
23 Mar 21 |
nicklas |
107 |
protected void doGet(HttpServletRequest req, HttpServletResponse resp) |
6178 |
23 Mar 21 |
nicklas |
108 |
throws ServletException, IOException |
6178 |
23 Mar 21 |
nicklas |
109 |
{ |
6178 |
23 Mar 21 |
nicklas |
110 |
String cmd = req.getParameter("cmd"); |
6178 |
23 Mar 21 |
nicklas |
111 |
JsonUtil.setJsonResponseHeaders(resp); |
6178 |
23 Mar 21 |
nicklas |
112 |
|
6178 |
23 Mar 21 |
nicklas |
113 |
JSONObject json = new JSONObject(); |
6178 |
23 Mar 21 |
nicklas |
114 |
json.put("status", "ok"); |
6178 |
23 Mar 21 |
nicklas |
115 |
|
6178 |
23 Mar 21 |
nicklas |
116 |
final SessionControl sc = Reggie.getSessionControl(req); |
6178 |
23 Mar 21 |
nicklas |
117 |
DbControl dc = null; |
6178 |
23 Mar 21 |
nicklas |
118 |
try |
6178 |
23 Mar 21 |
nicklas |
119 |
{ |
6178 |
23 Mar 21 |
nicklas |
120 |
|
6178 |
23 Mar 21 |
nicklas |
121 |
if ("GetImportInformation".equals(cmd)) |
6178 |
23 Mar 21 |
nicklas |
122 |
{ |
6178 |
23 Mar 21 |
nicklas |
123 |
JSONArray jsonImportItems = new JSONArray(); |
6337 |
16 Jun 21 |
nicklas |
124 |
dc = sc.newDbControl(":Import externally processed samples"); |
6896 |
28 Nov 22 |
nicklas |
125 |
|
6896 |
28 Nov 22 |
nicklas |
// A single file may be requested |
6896 |
28 Nov 22 |
nicklas |
127 |
String file = Values.getStringOrNull(req.getParameter("file")); |
6896 |
28 Nov 22 |
nicklas |
128 |
int itemNo = Values.getInt(req.getParameter("itemNo")); |
6899 |
29 Nov 22 |
nicklas |
129 |
boolean validateAll = Values.getBoolean(req.getParameter("validateAll")); |
6178 |
23 Mar 21 |
nicklas |
130 |
|
6582 |
11 Feb 22 |
nicklas |
// Keep track of NoSpecimen items that have been pre-registered with ExternalSpecimenExists=Yes |
6582 |
11 Feb 22 |
nicklas |
132 |
Set<Integer> matchedNoSpecimen = new HashSet<>(); |
6896 |
28 Nov 22 |
nicklas |
133 |
List<JsonFile> files = null; |
6929 |
02 Dec 22 |
nicklas |
134 |
ImportContext ctx = new ImportContext(); |
6896 |
28 Nov 22 |
nicklas |
135 |
FileServer gateway = Fileserver.IMPORT_GATEWAY.load(dc); |
6896 |
28 Nov 22 |
nicklas |
136 |
if (file == null) |
6896 |
28 Nov 22 |
nicklas |
137 |
{ |
6898 |
29 Nov 22 |
nicklas |
138 |
SimpleProgressReporter progress = new SimpleProgressReporter(null); |
6898 |
29 Nov 22 |
nicklas |
139 |
sc.setSessionSetting("scan-json-progress", progress); |
6898 |
29 Nov 22 |
nicklas |
140 |
progress.display(1, "Scanning for JSON files on "+gateway.getName()+":"+gateway.getRootPath()+"..."); |
6929 |
02 Dec 22 |
nicklas |
141 |
files = JsonFile.findJsonFiles(dc, gateway, ctx, true, validateAll ? -1 : 30, progress); |
6904 |
29 Nov 22 |
nicklas |
142 |
progress.display(99, "Scan complete! Found " + files.size() + " JSON files on "+gateway.getName()+":"+gateway.getRootPath()); |
6898 |
29 Nov 22 |
nicklas |
143 |
Thread.sleep(2000); |
6896 |
28 Nov 22 |
nicklas |
144 |
} |
6896 |
28 Nov 22 |
nicklas |
145 |
else |
6896 |
28 Nov 22 |
nicklas |
146 |
{ |
6896 |
28 Nov 22 |
nicklas |
147 |
ScriptUtil.checkValidFilename(req.getParameter("file")); |
6896 |
28 Nov 22 |
nicklas |
148 |
files = Arrays.asList(JsonFile.getJsonFile(dc, gateway, file, true)); |
6896 |
28 Nov 22 |
nicklas |
149 |
} |
6198 |
07 Apr 21 |
nicklas |
150 |
for (JsonFile importFile : files) |
6178 |
23 Mar 21 |
nicklas |
151 |
{ |
6178 |
23 Mar 21 |
nicklas |
152 |
JSONObject jsonFile = new JSONObject(); |
6896 |
28 Nov 22 |
nicklas |
153 |
if (file != null) jsonFile.put("itemNo", itemNo); |
6734 |
09 May 22 |
nicklas |
154 |
MainInfo mainInfo = importFile.getMain(); |
6178 |
23 Mar 21 |
nicklas |
155 |
|
6734 |
09 May 22 |
nicklas |
156 |
if (mainInfo != null) |
6178 |
23 Mar 21 |
nicklas |
157 |
{ |
6734 |
09 May 22 |
nicklas |
158 |
ScanBIdRef idRef = mainInfo.idRef; |
6734 |
09 May 22 |
nicklas |
159 |
EndPoint endPoint = mainInfo.endPoint; |
6734 |
09 May 22 |
nicklas |
160 |
if (endPoint != null) |
6734 |
09 May 22 |
nicklas |
161 |
{ |
6736 |
10 May 22 |
nicklas |
162 |
jsonFile.put("endPoint", endPoint.asJSONObject()); |
6736 |
10 May 22 |
nicklas |
163 |
jsonFile.put("endPointRNA", EndPoint.RNA.asJSONObject()); |
6734 |
09 May 22 |
nicklas |
164 |
if (endPoint != EndPoint.DEMUX) |
6734 |
09 May 22 |
nicklas |
165 |
{ |
6734 |
09 May 22 |
nicklas |
166 |
importFile.addWarningMessage(0, "[HTML]<b>No FASTQ files exists</b>"); |
6734 |
09 May 22 |
nicklas |
167 |
} |
6734 |
09 May 22 |
nicklas |
168 |
} |
6341 |
29 Jun 21 |
nicklas |
169 |
if (idRef != null) |
6495 |
01 Dec 21 |
nicklas |
170 |
{ |
6505 |
02 Dec 21 |
nicklas |
171 |
if (idRef.theCase != null) |
6505 |
02 Dec 21 |
nicklas |
172 |
{ |
6505 |
02 Dec 21 |
nicklas |
173 |
jsonFile.put("currentCase", idRef.theCase.asJSONObject()); |
6505 |
02 Dec 21 |
nicklas |
174 |
} |
6495 |
01 Dec 21 |
nicklas |
175 |
if (idRef.idType == SampleIdType.CASE) |
6348 |
16 Aug 21 |
nicklas |
176 |
{ |
7229 |
02 Jun 23 |
nicklas |
177 |
if (idRef.mergeWith != null) |
6573 |
07 Feb 22 |
nicklas |
178 |
{ |
7229 |
02 Jun 23 |
nicklas |
179 |
jsonFile.put("itemType", "Specimen"); |
7229 |
02 Jun 23 |
nicklas |
180 |
jsonFile.put("mergeWithExisting", true); |
7229 |
02 Jun 23 |
nicklas |
181 |
jsonFile.putAll(idRef.mergeWith.asJSONObject()); |
7229 |
02 Jun 23 |
nicklas |
182 |
} |
7229 |
02 Jun 23 |
nicklas |
183 |
else if (idRef.noSpecimen != null) |
7229 |
02 Jun 23 |
nicklas |
184 |
{ |
6582 |
11 Feb 22 |
nicklas |
185 |
matchedNoSpecimen.add(idRef.noSpecimen.getId()); |
6573 |
07 Feb 22 |
nicklas |
186 |
jsonFile.put("itemType", "NoSpecimen"); |
6921 |
02 Dec 22 |
nicklas |
187 |
jsonFile.put("convertToSpecimen", true); |
6924 |
02 Dec 22 |
nicklas |
188 |
idRef.noSpecimen.loadAnnotations(dc, "otherPathNote", Annotationtype.OTHER_PATH_NOTE, null); |
6573 |
07 Feb 22 |
nicklas |
189 |
jsonFile.putAll(idRef.noSpecimen.asJSONObject()); |
6573 |
07 Feb 22 |
nicklas |
190 |
} |
6573 |
07 Feb 22 |
nicklas |
191 |
else |
6573 |
07 Feb 22 |
nicklas |
192 |
{ |
6581 |
10 Feb 22 |
nicklas |
193 |
if (idRef.copyMissingDataFrom != null) |
6581 |
10 Feb 22 |
nicklas |
194 |
{ |
6927 |
02 Dec 22 |
nicklas |
195 |
jsonFile.put("otherPathNote", Annotationtype.OTHER_PATH_NOTE.getAnnotationValue(dc, idRef.copyMissingDataFrom)); |
6583 |
11 Feb 22 |
nicklas |
196 |
ItemSubtype subtype = idRef.copyMissingDataFrom.getItemSubtype(); |
6583 |
11 Feb 22 |
nicklas |
197 |
String subtypeName = subtype == null ? "" : subtype.getName(); |
6583 |
11 Feb 22 |
nicklas |
198 |
boolean specimenExists = "Yes".equals(Annotationtype.EXTERNAL_SPECIMEN_EXISTS.getAnnotationValue(dc, idRef.copyMissingDataFrom)); |
6583 |
11 Feb 22 |
nicklas |
199 |
if ("NoSpecimen".equals(subtypeName) && !specimenExists) |
6583 |
11 Feb 22 |
nicklas |
200 |
{ |
6583 |
11 Feb 22 |
nicklas |
201 |
importFile.addWarningMessage(0, "[HTML]<b>Should "+idRef.copyMissingDataFrom.getName() + " be converted to Specimen instead?</b>"); |
6583 |
11 Feb 22 |
nicklas |
202 |
} |
6583 |
11 Feb 22 |
nicklas |
203 |
importFile.addWarningMessage(0, "[HTML]<b>Missing data is copied from "+subtypeName+": "+idRef.copyMissingDataFrom.getName()+"</b>"); |
6581 |
10 Feb 22 |
nicklas |
204 |
} |
6573 |
07 Feb 22 |
nicklas |
205 |
jsonFile.put("itemType", "Specimen"); |
7000 |
20 Jan 23 |
nicklas |
206 |
jsonFile.put("name", SpecimenTube.getNextSpecimenName(dc, idRef.id, true)); |
6573 |
07 Feb 22 |
nicklas |
207 |
} |
6495 |
01 Dec 21 |
nicklas |
208 |
} |
6495 |
01 Dec 21 |
nicklas |
209 |
else if (idRef.idType == SampleIdType.SPECIMEN) |
6341 |
29 Jun 21 |
nicklas |
210 |
{ |
6341 |
29 Jun 21 |
nicklas |
211 |
jsonFile.put("itemType", "Specimen"); |
6341 |
29 Jun 21 |
nicklas |
212 |
if (idRef.specimen != null) |
6341 |
29 Jun 21 |
nicklas |
213 |
{ |
6341 |
29 Jun 21 |
nicklas |
214 |
jsonFile.putAll(idRef.specimen.asJSONObject()); |
6341 |
29 Jun 21 |
nicklas |
215 |
} |
6341 |
29 Jun 21 |
nicklas |
216 |
} |
6341 |
29 Jun 21 |
nicklas |
217 |
else if (idRef.idType == SampleIdType.PRENORMALISED_RNA) |
6341 |
29 Jun 21 |
nicklas |
218 |
{ |
6341 |
29 Jun 21 |
nicklas |
219 |
jsonFile.put("itemType", "RNA"); |
6341 |
29 Jun 21 |
nicklas |
220 |
if (idRef.rna != null) |
6341 |
29 Jun 21 |
nicklas |
221 |
{ |
6341 |
29 Jun 21 |
nicklas |
222 |
jsonFile.putAll(idRef.rna.asJSONObject()); |
6341 |
29 Jun 21 |
nicklas |
223 |
} |
6341 |
29 Jun 21 |
nicklas |
224 |
} |
6341 |
29 Jun 21 |
nicklas |
225 |
} |
6178 |
23 Mar 21 |
nicklas |
226 |
} |
6341 |
29 Jun 21 |
nicklas |
227 |
jsonFile.put("jsonFile", importFile.asJSONObject()); |
6178 |
23 Mar 21 |
nicklas |
228 |
jsonImportItems.add(jsonFile); |
6178 |
23 Mar 21 |
nicklas |
229 |
} |
6582 |
11 Feb 22 |
nicklas |
230 |
|
6896 |
28 Nov 22 |
nicklas |
231 |
if (file == null) |
6582 |
11 Feb 22 |
nicklas |
232 |
{ |
6896 |
28 Nov 22 |
nicklas |
// Load all NoSpecimen with ExternalSpecimenExists=Yes except those that have been matched to a JSON file |
6896 |
28 Nov 22 |
nicklas |
234 |
ItemQuery<Sample> query = Sample.getQuery(); |
6896 |
28 Nov 22 |
nicklas |
235 |
Subtype.NO_SPECIMEN.addFilter(dc, query); |
6896 |
28 Nov 22 |
nicklas |
236 |
query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT); |
6896 |
28 Nov 22 |
nicklas |
// Must have ExternalSpecimenExists=Yes annotation |
6896 |
28 Nov 22 |
nicklas |
238 |
query.join(Annotations.innerJoin(Annotationtype.EXTERNAL_SPECIMEN_EXISTS.get(dc), "es")); |
6896 |
28 Nov 22 |
nicklas |
239 |
query.restrict(Restrictions.eq(Hql.alias("es"), Expressions.string("Yes"))); |
6896 |
28 Nov 22 |
nicklas |
240 |
query.restrict(Restrictions.not(Restrictions.in(Hql.property("id"), Expressions.parameter("matched")))); |
6896 |
28 Nov 22 |
nicklas |
241 |
query.setParameter("matched", matchedNoSpecimen, Type.INT); |
6896 |
28 Nov 22 |
nicklas |
242 |
for (NoSpecimen ns : NoSpecimen.toList(query.list(dc))) |
6582 |
11 Feb 22 |
nicklas |
243 |
{ |
6896 |
28 Nov 22 |
nicklas |
244 |
Case theCase = ns.getCase(); |
6896 |
28 Nov 22 |
nicklas |
245 |
ns.setAnnotation("itemType", "NoSpecimen"); |
6896 |
28 Nov 22 |
nicklas |
246 |
ns.loadAnnotations(dc, "liasonComment", Annotationtype.LIASON_COMMENT, null); |
6924 |
02 Dec 22 |
nicklas |
247 |
ns.loadAnnotations(dc, "otherPathNote", Annotationtype.OTHER_PATH_NOTE, null); |
6896 |
28 Nov 22 |
nicklas |
248 |
ns.loadAnnotations(dc, "externalSpecimenExists", Annotationtype.EXTERNAL_SPECIMEN_EXISTS, null); |
6896 |
28 Nov 22 |
nicklas |
249 |
ns.loadAnnotations(dc, "externalOperator", Annotationtype.EXTERNAL_OPERATOR, null); |
6896 |
28 Nov 22 |
nicklas |
250 |
ns.setAnnotation("samplingDate", Reggie.CONVERTER_DATE_TO_STRING.convert(ns.getItem().getCreationEvent().getEventDate())); |
6896 |
28 Nov 22 |
nicklas |
251 |
ns.setAnnotation("registered", Reggie.CONVERTER_DATE_TO_STRING.convert(ns.getItem().getEntryDate())); |
6896 |
28 Nov 22 |
nicklas |
252 |
if (theCase != null) |
6896 |
28 Nov 22 |
nicklas |
253 |
{ |
6896 |
28 Nov 22 |
nicklas |
254 |
ns.setAnnotation("currentCase", theCase.asJSONObject()); |
6896 |
28 Nov 22 |
nicklas |
255 |
} |
6896 |
28 Nov 22 |
nicklas |
256 |
jsonImportItems.add(ns.asJSONObject()); |
6582 |
11 Feb 22 |
nicklas |
257 |
} |
6929 |
02 Dec 22 |
nicklas |
258 |
|
6929 |
02 Dec 22 |
nicklas |
259 |
for (String f : ctx.getFilesThatWasNeverRequested()) |
6929 |
02 Dec 22 |
nicklas |
260 |
{ |
6929 |
02 Dec 22 |
nicklas |
261 |
FileMetaData fdata = ctx.getFileInfo(f); |
6929 |
02 Dec 22 |
nicklas |
262 |
JSONObject jsonFastq = new JSONObject(); |
6929 |
02 Dec 22 |
nicklas |
263 |
jsonFastq.put("itemType", "StrayFastq"); |
6929 |
02 Dec 22 |
nicklas |
264 |
jsonFastq.put("name", f); |
6929 |
02 Dec 22 |
nicklas |
265 |
jsonFastq.put("size", fdata.getSize()); |
6929 |
02 Dec 22 |
nicklas |
266 |
jsonFastq.put("lastModified", Reggie.CONVERTER_DATETIME_TO_STRING_WITH_SEPARATOR.convert(new Date(fdata.getLastModifiedTime()))); |
6929 |
02 Dec 22 |
nicklas |
267 |
jsonImportItems.add(jsonFastq); |
6929 |
02 Dec 22 |
nicklas |
268 |
} |
6929 |
02 Dec 22 |
nicklas |
269 |
|
6582 |
11 Feb 22 |
nicklas |
270 |
} |
6898 |
29 Nov 22 |
nicklas |
271 |
sc.setSessionSetting("scan-json-progress", null); |
6178 |
23 Mar 21 |
nicklas |
272 |
json.put("importItems", jsonImportItems); |
6178 |
23 Mar 21 |
nicklas |
273 |
} |
6208 |
12 Apr 21 |
nicklas |
274 |
else if ("DownloadJsonFile".equals(cmd)) |
6208 |
12 Apr 21 |
nicklas |
275 |
{ |
6208 |
12 Apr 21 |
nicklas |
276 |
json = null; // No regular JSON output |
6337 |
16 Jun 21 |
nicklas |
277 |
dc = sc.newDbControl(":Import externally processed samples"); |
6208 |
12 Apr 21 |
nicklas |
278 |
|
6998 |
20 Jan 23 |
nicklas |
279 |
int fileId = Values.getInt(req.getParameter("fileId")); |
6998 |
20 Jan 23 |
nicklas |
280 |
String file = Values.getStringOrNull(req.getParameter("file")); |
6208 |
12 Apr 21 |
nicklas |
281 |
|
6998 |
20 Jan 23 |
nicklas |
282 |
ByteArrayOutputStream jsonBytes = new ByteArrayOutputStream(); |
6998 |
20 Jan 23 |
nicklas |
283 |
if (file != null) |
6208 |
12 Apr 21 |
nicklas |
284 |
{ |
6998 |
20 Jan 23 |
nicklas |
285 |
ScriptUtil.checkValidFilename(file); |
6998 |
20 Jan 23 |
nicklas |
286 |
FileServer fs = Fileserver.IMPORT_GATEWAY.load(dc); |
6998 |
20 Jan 23 |
nicklas |
287 |
String rootPath = ScriptUtil.checkValidPath(fs.getRootPath(), true, false); |
6998 |
20 Jan 23 |
nicklas |
288 |
RemoteSession session = null; |
6965 |
10 Jan 23 |
nicklas |
289 |
try |
6965 |
10 Jan 23 |
nicklas |
290 |
{ |
6998 |
20 Jan 23 |
nicklas |
291 |
RemoteHost host = new RemoteHost(new ConnectionInfo(fs)); |
6998 |
20 Jan 23 |
nicklas |
292 |
session = host.connect(5); |
6998 |
20 Jan 23 |
nicklas |
293 |
FileUtil.copy(session.readFile(rootPath+"/"+file, null), jsonBytes); |
6965 |
10 Jan 23 |
nicklas |
294 |
} |
6998 |
20 Jan 23 |
nicklas |
295 |
finally |
6965 |
10 Jan 23 |
nicklas |
296 |
{ |
6998 |
20 Jan 23 |
nicklas |
297 |
OpenGrid.close(session); |
6965 |
10 Jan 23 |
nicklas |
298 |
} |
6208 |
12 Apr 21 |
nicklas |
299 |
} |
6998 |
20 Jan 23 |
nicklas |
300 |
else |
6208 |
12 Apr 21 |
nicklas |
301 |
{ |
6998 |
20 Jan 23 |
nicklas |
302 |
File f = File.getById(dc, fileId); |
6998 |
20 Jan 23 |
nicklas |
303 |
FileUtil.copy(f.getDownloadStream(0), jsonBytes); |
6208 |
12 Apr 21 |
nicklas |
304 |
} |
6208 |
12 Apr 21 |
nicklas |
305 |
|
6998 |
20 Jan 23 |
nicklas |
306 |
resp.setContentType("application/json"); |
6998 |
20 Jan 23 |
nicklas |
307 |
try |
6998 |
20 Jan 23 |
nicklas |
308 |
{ |
6998 |
20 Jan 23 |
nicklas |
// Try to parse as JSON |
6998 |
20 Jan 23 |
nicklas |
310 |
JSONObject jsonData = (JSONObject)new JSONParser().parse(jsonBytes.toString("UTF-8")); |
6998 |
20 Jan 23 |
nicklas |
// Move entries to an insertion-ordered map |
6998 |
20 Jan 23 |
nicklas |
312 |
Map<String, Object> ordered = new LinkedHashMap<>(); |
6998 |
20 Jan 23 |
nicklas |
313 |
moveJsonObject("SCANB_ID", ordered, jsonData); |
6998 |
20 Jan 23 |
nicklas |
314 |
moveJsonObject("Specimen", ordered, jsonData); |
6998 |
20 Jan 23 |
nicklas |
315 |
moveJsonObject("Lysate", ordered, jsonData); |
6998 |
20 Jan 23 |
nicklas |
316 |
moveJsonObject("RNA", ordered, jsonData); |
6998 |
20 Jan 23 |
nicklas |
317 |
moveJsonObject("DNA", ordered, jsonData); |
6998 |
20 Jan 23 |
nicklas |
318 |
moveJsonObject("FlowThrough", ordered, jsonData); |
6998 |
20 Jan 23 |
nicklas |
319 |
moveJsonObject("Library", ordered, jsonData); |
6998 |
20 Jan 23 |
nicklas |
320 |
moveJsonObject("Pool", ordered, jsonData); |
6998 |
20 Jan 23 |
nicklas |
321 |
moveJsonObject("FlowCell", ordered, jsonData); |
6998 |
20 Jan 23 |
nicklas |
322 |
moveJsonObject("SequencingRun", ordered, jsonData); |
6998 |
20 Jan 23 |
nicklas |
323 |
moveJsonObject("DemuxedSequences", ordered, jsonData); |
6998 |
20 Jan 23 |
nicklas |
324 |
moveJsonObject("MergedSequences", ordered, jsonData); |
6998 |
20 Jan 23 |
nicklas |
325 |
moveJsonObject("fastq", ordered, jsonData); |
6998 |
20 Jan 23 |
nicklas |
// Copy remaining entries |
6998 |
20 Jan 23 |
nicklas |
327 |
ordered.putAll(jsonData); |
6998 |
20 Jan 23 |
nicklas |
328 |
JSONObject.writeJSONString(ordered, resp.getWriter()); |
6998 |
20 Jan 23 |
nicklas |
329 |
} |
6998 |
20 Jan 23 |
nicklas |
330 |
catch (RuntimeException ex) |
6998 |
20 Jan 23 |
nicklas |
331 |
{ |
6998 |
20 Jan 23 |
nicklas |
// If something fails when creating the re-ordered map we send the original file as is |
6998 |
20 Jan 23 |
nicklas |
333 |
FileUtil.copy(new ByteArrayInputStream(jsonBytes.toByteArray()), resp.getOutputStream()); |
6998 |
20 Jan 23 |
nicklas |
334 |
} |
6998 |
20 Jan 23 |
nicklas |
335 |
|
6208 |
12 Apr 21 |
nicklas |
336 |
} |
7173 |
17 May 23 |
nicklas |
337 |
else if ("GetTransportBoxesToMove".equals(cmd)) |
7173 |
17 May 23 |
nicklas |
338 |
{ |
7173 |
17 May 23 |
nicklas |
339 |
dc = sc.newDbControl(":Transport box registration"); |
7173 |
17 May 23 |
nicklas |
340 |
|
7173 |
17 May 23 |
nicklas |
// Find transport boxes |
7173 |
17 May 23 |
nicklas |
342 |
ItemQuery<ItemList> query = ItemList.getQuery(); |
7173 |
17 May 23 |
nicklas |
343 |
query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT); |
7173 |
17 May 23 |
nicklas |
344 |
query.restrict(Restrictions.eq(Hql.property("externalId"), Expressions.string(TransportBoxImporter.WORK_LIST_ID))); |
7187 |
22 May 23 |
nicklas |
345 |
query.join(Annotations.leftJoin(null, Annotationtype.MOVE_DATE.load(dc), "md")); |
7187 |
22 May 23 |
nicklas |
346 |
query.restrict(Restrictions.eq(Hql.alias("md"), null)); |
7173 |
17 May 23 |
nicklas |
347 |
query.order(Orders.asc(Hql.property("id"))); |
7173 |
17 May 23 |
nicklas |
348 |
JSONArray jsonBoxes = new JSONArray(); |
7173 |
17 May 23 |
nicklas |
349 |
for (ItemList list : query.list(dc)) |
7173 |
17 May 23 |
nicklas |
350 |
{ |
7173 |
17 May 23 |
nicklas |
351 |
JSONObject jsonBox = new JSONObject(); |
7173 |
17 May 23 |
nicklas |
352 |
jsonBox.put("id", list.getId()); |
7173 |
17 May 23 |
nicklas |
353 |
jsonBox.put("name", list.getName()); |
7173 |
17 May 23 |
nicklas |
354 |
jsonBox.put("size", list.getSize()); |
7184 |
22 May 23 |
nicklas |
355 |
jsonBox.put("comments", list.getDescription()); |
7173 |
17 May 23 |
nicklas |
356 |
|
7173 |
17 May 23 |
nicklas |
357 |
jsonBoxes.add(jsonBox); |
7173 |
17 May 23 |
nicklas |
358 |
} |
7173 |
17 May 23 |
nicklas |
359 |
json.put("transportBoxes", jsonBoxes); |
7173 |
17 May 23 |
nicklas |
360 |
} |
7173 |
17 May 23 |
nicklas |
361 |
else if ("GetTransportBoxDetailsForMove".equals(cmd)) |
7173 |
17 May 23 |
nicklas |
362 |
{ |
7173 |
17 May 23 |
nicklas |
363 |
int listId = Values.getInt(req.getParameter("listId")); |
7173 |
17 May 23 |
nicklas |
364 |
dc = sc.newDbControl(":Move external samples protocol"); |
7173 |
17 May 23 |
nicklas |
365 |
|
7173 |
17 May 23 |
nicklas |
366 |
ItemList transportBox = ItemList.getById(dc, listId); |
7173 |
17 May 23 |
nicklas |
367 |
JSONObject jsonTransportBox = new JSONObject(); |
7173 |
17 May 23 |
nicklas |
368 |
jsonTransportBox.put("id", transportBox.getId()); |
7173 |
17 May 23 |
nicklas |
369 |
jsonTransportBox.put("name", transportBox.getName()); |
7186 |
22 May 23 |
nicklas |
370 |
jsonTransportBox.put("comments", transportBox.getDescription()); |
7173 |
17 May 23 |
nicklas |
371 |
jsonTransportBox.put("size", transportBox.getSize()); |
7175 |
17 May 23 |
nicklas |
372 |
jsonTransportBox.put("externalRef", Annotationtype.EXTERNAL_REF.getAnnotationValue(dc, transportBox)); |
7173 |
17 May 23 |
nicklas |
373 |
json.put("transportBox", jsonTransportBox); |
7173 |
17 May 23 |
nicklas |
374 |
|
7173 |
17 May 23 |
nicklas |
375 |
List<String> messages = (List<String>)Annotationtype.TRANSPORT_MESSAGES.getAnnotationValues(dc, transportBox); |
7173 |
17 May 23 |
nicklas |
376 |
JSONArray jsonTransportMessages = new JSONArray(); |
7173 |
17 May 23 |
nicklas |
377 |
if (messages != null && messages.size() > 0) |
7173 |
17 May 23 |
nicklas |
378 |
{ |
7173 |
17 May 23 |
nicklas |
379 |
jsonTransportMessages.addAll(messages); |
7173 |
17 May 23 |
nicklas |
380 |
} |
7173 |
17 May 23 |
nicklas |
381 |
jsonTransportBox.put("messages", jsonTransportMessages); |
7173 |
17 May 23 |
nicklas |
382 |
|
7184 |
22 May 23 |
nicklas |
// We want to extract prefixes from Clarity ID. For example: cmd:ALL557A123 --> ALL557A |
7184 |
22 May 23 |
nicklas |
384 |
Pattern prefixPattern = Pattern.compile("^[a-z]*:?((\\w+?)\\d+)$"); |
7184 |
22 May 23 |
nicklas |
385 |
|
7173 |
17 May 23 |
nicklas |
386 |
JSONArray jsonSamples = new JSONArray(); |
7184 |
22 May 23 |
nicklas |
387 |
Set<String> prefixes = new HashSet<String>(); // Prefixes used in Clarity ID for the samples in this box |
7173 |
17 May 23 |
nicklas |
388 |
ItemQuery<MeasuredBioMaterial> query = transportBox.getMembers(); |
7186 |
22 May 23 |
nicklas |
389 |
query.include(Reggie.INCLUDE_IN_CURRENT_PROJECT); |
7173 |
17 May 23 |
nicklas |
390 |
query.join(Hql.innerJoin(null, "bioWell", "bw", true)); |
7173 |
17 May 23 |
nicklas |
391 |
query.join(Hql.innerJoin("bw", "bioPlate", "bp")); |
7173 |
17 May 23 |
nicklas |
392 |
query.order(Orders.asc(Hql.property("bp", "name"))); |
7173 |
17 May 23 |
nicklas |
393 |
query.order(Orders.asc(Hql.property("bw", "row"))); |
7173 |
17 May 23 |
nicklas |
394 |
query.order(Orders.asc(Hql.property("bw", "column"))); |
7173 |
17 May 23 |
nicklas |
395 |
Set<BioPlate> storageBoxes = new LinkedHashSet<>(); |
7173 |
17 May 23 |
nicklas |
396 |
ItemSubtype specimenType = Subtype.SPECIMEN.get(dc); |
7173 |
17 May 23 |
nicklas |
397 |
for (MeasuredBioMaterial bm : query.list(dc)) |
7173 |
17 May 23 |
nicklas |
398 |
{ |
7173 |
17 May 23 |
nicklas |
399 |
JSONObject jsonBM = new JSONObject(); |
7173 |
17 May 23 |
nicklas |
400 |
jsonBM.put("id", bm.getId()); |
7173 |
17 May 23 |
nicklas |
401 |
jsonBM.put("name", bm.getName()); |
7208 |
26 May 23 |
nicklas |
402 |
jsonBM.put("remain", bm.getRemainingQuantity()); |
7208 |
26 May 23 |
nicklas |
403 |
jsonBM.put("type", bm.getItemSubtype().getName()); |
7173 |
17 May 23 |
nicklas |
404 |
|
7173 |
17 May 23 |
nicklas |
405 |
MeasuredBioMaterial parent = bm; |
7173 |
17 May 23 |
nicklas |
406 |
while (!parent.getItemSubtype().equals(specimenType)) |
7173 |
17 May 23 |
nicklas |
407 |
{ |
7173 |
17 May 23 |
nicklas |
408 |
parent = (MeasuredBioMaterial)parent.getParent(); |
7173 |
17 May 23 |
nicklas |
409 |
} |
7184 |
22 May 23 |
nicklas |
410 |
String externalRef = (String)Annotationtype.EXTERNAL_REF.getAnnotationValue(dc, parent); |
7184 |
22 May 23 |
nicklas |
411 |
if (externalRef != null) |
7184 |
22 May 23 |
nicklas |
412 |
{ |
7184 |
22 May 23 |
nicklas |
413 |
Matcher m = prefixPattern.matcher(externalRef); |
7184 |
22 May 23 |
nicklas |
414 |
if (m.matches()) |
7184 |
22 May 23 |
nicklas |
415 |
{ |
7184 |
22 May 23 |
nicklas |
416 |
prefixes.add(m.group(2)); |
7184 |
22 May 23 |
nicklas |
417 |
jsonBM.put("clarityId", m.group(1)); |
7184 |
22 May 23 |
nicklas |
418 |
} |
7184 |
22 May 23 |
nicklas |
419 |
} |
7173 |
17 May 23 |
nicklas |
420 |
|
7184 |
22 May 23 |
nicklas |
421 |
jsonBM.put("externalRef", externalRef); |
7173 |
17 May 23 |
nicklas |
422 |
jsonBM.put("specimenName", parent.getName()); |
7173 |
17 May 23 |
nicklas |
423 |
jsonBM.put("comment", parent.getDescription()); |
7173 |
17 May 23 |
nicklas |
424 |
|
7173 |
17 May 23 |
nicklas |
425 |
BioWell well = bm.getBioWell(); |
7173 |
17 May 23 |
nicklas |
426 |
BioPlate storageBox = well.getPlate(); |
7173 |
17 May 23 |
nicklas |
427 |
storageBoxes.add(storageBox); |
7173 |
17 May 23 |
nicklas |
428 |
jsonBM.put("well", JsonUtil.getBioWellAsJSON(well, true)); |
7173 |
17 May 23 |
nicklas |
429 |
jsonSamples.add(jsonBM); |
7173 |
17 May 23 |
nicklas |
430 |
} |
7173 |
17 May 23 |
nicklas |
431 |
json.put("samples", jsonSamples); |
7184 |
22 May 23 |
nicklas |
432 |
JSONArray jsonPrefixes = new JSONArray(); |
7184 |
22 May 23 |
nicklas |
433 |
jsonPrefixes.addAll(prefixes); |
7184 |
22 May 23 |
nicklas |
434 |
json.put("prefixes", jsonPrefixes); |
7173 |
17 May 23 |
nicklas |
435 |
|
7173 |
17 May 23 |
nicklas |
436 |
JSONArray jsonStorageBoxes = new JSONArray(); |
7173 |
17 May 23 |
nicklas |
437 |
for (BioPlate storageBox : storageBoxes) |
7173 |
17 May 23 |
nicklas |
438 |
{ |
7189 |
22 May 23 |
nicklas |
439 |
Hardware freezer = storageBox.getFreezer(); |
7173 |
17 May 23 |
nicklas |
440 |
JSONObject jsonStorageBox = new JSONObject(); |
7173 |
17 May 23 |
nicklas |
441 |
jsonStorageBox.put("id", storageBox.getId()); |
7173 |
17 May 23 |
nicklas |
442 |
jsonStorageBox.put("name", storageBox.getName()); |
7189 |
22 May 23 |
nicklas |
443 |
if (freezer != null) jsonStorageBox.put("freezer", freezer.getName()); |
7173 |
17 May 23 |
nicklas |
444 |
jsonStorageBoxes.add(jsonStorageBox); |
7173 |
17 May 23 |
nicklas |
445 |
} |
7173 |
17 May 23 |
nicklas |
446 |
json.put("storageBoxes", jsonStorageBoxes); |
7173 |
17 May 23 |
nicklas |
447 |
} |
6178 |
23 Mar 21 |
nicklas |
448 |
} |
6178 |
23 Mar 21 |
nicklas |
449 |
catch (Throwable t) |
6178 |
23 Mar 21 |
nicklas |
450 |
{ |
6178 |
23 Mar 21 |
nicklas |
451 |
t.printStackTrace(); |
6208 |
12 Apr 21 |
nicklas |
452 |
if (json != null) |
6208 |
12 Apr 21 |
nicklas |
453 |
{ |
6208 |
12 Apr 21 |
nicklas |
454 |
json.clear(); |
6208 |
12 Apr 21 |
nicklas |
455 |
json.put("status", "error"); |
6208 |
12 Apr 21 |
nicklas |
456 |
json.put("message", t.getMessage()); |
6208 |
12 Apr 21 |
nicklas |
457 |
json.put("stacktrace", ThrowableUtil.stackTraceToString(t)); |
6208 |
12 Apr 21 |
nicklas |
458 |
} |
6208 |
12 Apr 21 |
nicklas |
459 |
else |
6208 |
12 Apr 21 |
nicklas |
460 |
{ |
6208 |
12 Apr 21 |
nicklas |
461 |
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, t.getMessage()); |
6208 |
12 Apr 21 |
nicklas |
462 |
} |
6178 |
23 Mar 21 |
nicklas |
463 |
} |
6178 |
23 Mar 21 |
nicklas |
464 |
finally |
6178 |
23 Mar 21 |
nicklas |
465 |
{ |
6178 |
23 Mar 21 |
nicklas |
466 |
if (dc != null) dc.close(); |
6208 |
12 Apr 21 |
nicklas |
467 |
if (json != null) json.writeJSONString(resp.getWriter()); |
6178 |
23 Mar 21 |
nicklas |
468 |
} |
6178 |
23 Mar 21 |
nicklas |
469 |
|
6178 |
23 Mar 21 |
nicklas |
470 |
} |
6178 |
23 Mar 21 |
nicklas |
471 |
|
7195 |
24 May 23 |
nicklas |
472 |
@SuppressWarnings("unchecked") |
6178 |
23 Mar 21 |
nicklas |
473 |
@Override |
6178 |
23 Mar 21 |
nicklas |
474 |
protected void doPost(HttpServletRequest req, HttpServletResponse resp) |
6178 |
23 Mar 21 |
nicklas |
475 |
throws ServletException, IOException |
6178 |
23 Mar 21 |
nicklas |
476 |
{ |
6178 |
23 Mar 21 |
nicklas |
477 |
String cmd = req.getParameter("cmd"); |
6178 |
23 Mar 21 |
nicklas |
478 |
JsonUtil.setJsonResponseHeaders(resp); |
6178 |
23 Mar 21 |
nicklas |
479 |
|
6178 |
23 Mar 21 |
nicklas |
480 |
JSONObject json = new JSONObject(); |
6178 |
23 Mar 21 |
nicklas |
481 |
json.put("status", "ok"); |
6178 |
23 Mar 21 |
nicklas |
482 |
JSONArray jsonMessages = new JSONArray(); |
6178 |
23 Mar 21 |
nicklas |
483 |
|
6178 |
23 Mar 21 |
nicklas |
484 |
final SessionControl sc = Reggie.getSessionControl(req); |
6178 |
23 Mar 21 |
nicklas |
485 |
DbControl dc = null; |
7167 |
12 May 23 |
nicklas |
486 |
boolean forceCount = true; |
6178 |
23 Mar 21 |
nicklas |
487 |
try |
6178 |
23 Mar 21 |
nicklas |
488 |
{ |
6178 |
23 Mar 21 |
nicklas |
489 |
|
6178 |
23 Mar 21 |
nicklas |
490 |
if ("ImportFromJSON".equals(cmd)) |
6178 |
23 Mar 21 |
nicklas |
491 |
{ |
6337 |
16 Jun 21 |
nicklas |
492 |
dc = sc.newDbControl(":Import externally processed samples"); |
6178 |
23 Mar 21 |
nicklas |
493 |
|
6178 |
23 Mar 21 |
nicklas |
494 |
ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.ADMINISTRATOR); |
6178 |
23 Mar 21 |
nicklas |
495 |
|
6178 |
23 Mar 21 |
nicklas |
496 |
JSONObject jsonReq = JsonUtil.parseRequest(req); |
6178 |
23 Mar 21 |
nicklas |
497 |
JSONArray jsonItems = (JSONArray)jsonReq.get("items"); |
6211 |
14 Apr 21 |
nicklas |
498 |
JSONObject jsonAutoAnalyze = (JSONObject)jsonReq.get("autoAnalyze"); |
6212 |
14 Apr 21 |
nicklas |
499 |
String operator = Values.getStringOrNull((String)jsonReq.get("operator")); |
6914 |
01 Dec 22 |
nicklas |
500 |
boolean getDebugMessages = Boolean.TRUE.equals(jsonReq.get("getDebugMessages")); |
6178 |
23 Mar 21 |
nicklas |
501 |
|
6211 |
14 Apr 21 |
nicklas |
502 |
OpenGridCluster cluster = null; |
6211 |
14 Apr 21 |
nicklas |
503 |
if (jsonAutoAnalyze != null) |
6178 |
23 Mar 21 |
nicklas |
504 |
{ |
6211 |
14 Apr 21 |
nicklas |
505 |
String clusterId = (String)jsonAutoAnalyze.get("cluster"); |
6211 |
14 Apr 21 |
nicklas |
506 |
cluster = OpenGridService.getInstance().getClusterById(dc, clusterId); |
6211 |
14 Apr 21 |
nicklas |
507 |
if (cluster == null) |
6211 |
14 Apr 21 |
nicklas |
508 |
{ |
6211 |
14 Apr 21 |
nicklas |
509 |
throw new ItemNotFoundException("OpenGridCluster[" + clusterId + "]"); |
6211 |
14 Apr 21 |
nicklas |
510 |
} |
6178 |
23 Mar 21 |
nicklas |
511 |
} |
6211 |
14 Apr 21 |
nicklas |
512 |
|
6209 |
13 Apr 21 |
nicklas |
513 |
FileServer importGateway = Fileserver.IMPORT_GATEWAY.load(dc); |
6209 |
13 Apr 21 |
nicklas |
514 |
FileServer importArchive = Fileserver.IMPORT_ARCHIVE.load(dc); |
7025 |
08 Feb 23 |
nicklas |
515 |
FastDateFormat year = FastDateFormat.getInstance("/yyyy"); |
6209 |
13 Apr 21 |
nicklas |
516 |
|
6209 |
13 Apr 21 |
nicklas |
517 |
String gatewayRoot = ScriptUtil.checkValidPath(importGateway.getRootPath(), true, false); |
6209 |
13 Apr 21 |
nicklas |
518 |
String archiveRoot = ScriptUtil.checkValidPath(importArchive.getRootPath(), true, false); |
6209 |
13 Apr 21 |
nicklas |
519 |
RemoteSession gatewaySession = null; |
6209 |
13 Apr 21 |
nicklas |
520 |
RemoteSession archiveSession = null; |
6193 |
30 Mar 21 |
nicklas |
521 |
try |
6193 |
30 Mar 21 |
nicklas |
522 |
{ |
6209 |
13 Apr 21 |
nicklas |
523 |
gatewaySession = new RemoteHost(new ConnectionInfo(importGateway)).connect(5); |
6209 |
13 Apr 21 |
nicklas |
524 |
archiveSession = new RemoteHost(new ConnectionInfo(importArchive)).connect(5); |
6215 |
16 Apr 21 |
nicklas |
525 |
List<DemuxedSequences> demuxedSequences = new ArrayList<>(); // Collect DemuxedSequences that has been created by the importer |
6913 |
30 Nov 22 |
nicklas |
526 |
|
6913 |
30 Nov 22 |
nicklas |
527 |
SimpleProgressReporter progress = new SimpleProgressReporter(null); |
6913 |
30 Nov 22 |
nicklas |
528 |
sc.setSessionSetting("import-json-progress", progress); |
6913 |
30 Nov 22 |
nicklas |
529 |
progress.display(1, "Importing from JSON files on "+importGateway.getName()+":"+importGateway.getRootPath()+"..."); |
6913 |
30 Nov 22 |
nicklas |
530 |
|
6913 |
30 Nov 22 |
nicklas |
531 |
int numProcessed = 0; |
6913 |
30 Nov 22 |
nicklas |
532 |
int numImported = 0; |
6913 |
30 Nov 22 |
nicklas |
533 |
int numWithError = 0; |
6913 |
30 Nov 22 |
nicklas |
534 |
int numItems = jsonItems.size(); |
6193 |
30 Mar 21 |
nicklas |
535 |
for (int itemNo = 0; itemNo < jsonItems.size(); itemNo++) |
6193 |
30 Mar 21 |
nicklas |
536 |
{ |
6210 |
14 Apr 21 |
nicklas |
// We use one transaction per JSON file |
6337 |
16 Jun 21 |
nicklas |
538 |
if (dc.isClosed()) dc = sc.newDbControl(dc.getName()); |
6210 |
14 Apr 21 |
nicklas |
539 |
|
6736 |
10 May 22 |
nicklas |
540 |
ItemList flaggedRNA = BiomaterialList.FLAGGED_RNA.get(dc); |
6193 |
30 Mar 21 |
nicklas |
541 |
JSONObject jsonItem = (JSONObject)jsonItems.get(itemNo); |
6193 |
30 Mar 21 |
nicklas |
542 |
Number itemId = (Number)jsonItem.get("id"); |
6736 |
10 May 22 |
nicklas |
543 |
boolean flagRNA = Boolean.TRUE.equals(jsonItem.get("flagRNA")); |
6201 |
09 Apr 21 |
nicklas |
544 |
JsonFile jsonFile = new JsonFile(dc, (String)jsonItem.get("jsonFile")); |
6913 |
30 Nov 22 |
nicklas |
545 |
|
6913 |
30 Nov 22 |
nicklas |
546 |
progress.display(2+(85*itemNo)/numItems, "Importing from '"+jsonFile.getName()+"'... ("+(itemNo+1)+" of "+numItems+ |
6913 |
30 Nov 22 |
nicklas |
547 |
" files on " + importGateway.getName()+":"+importGateway.getRootPath()+")"); |
6913 |
30 Nov 22 |
nicklas |
//Thread.sleep(5000); |
6913 |
30 Nov 22 |
nicklas |
549 |
|
6897 |
29 Nov 22 |
nicklas |
550 |
jsonFile.downloadAndParse(gatewaySession, gatewayRoot, true, null, null); |
6212 |
14 Apr 21 |
nicklas |
551 |
if (operator != null) jsonFile.setOperator(operator); |
6913 |
30 Nov 22 |
nicklas |
552 |
|
6913 |
30 Nov 22 |
nicklas |
553 |
numProcessed++; |
6198 |
07 Apr 21 |
nicklas |
554 |
if (jsonFile.hasError()) |
6198 |
07 Apr 21 |
nicklas |
555 |
{ |
6913 |
30 Nov 22 |
nicklas |
556 |
numWithError++; |
6199 |
08 Apr 21 |
nicklas |
557 |
jsonMessages.add("[Error]["+jsonFile.getName()+"] Import failed (see below for more information)"); |
6199 |
08 Apr 21 |
nicklas |
558 |
jsonMessages.addAll(prefix("[Error]["+jsonFile.getName()+"] ", jsonFile.getErrorMessages())); |
6209 |
13 Apr 21 |
nicklas |
559 |
dc.close(); |
6198 |
07 Apr 21 |
nicklas |
560 |
} |
6198 |
07 Apr 21 |
nicklas |
561 |
else |
6198 |
07 Apr 21 |
nicklas |
562 |
{ |
6498 |
01 Dec 21 |
nicklas |
563 |
ExternalSpecimenImporter importer = new ExternalSpecimenImporter(); |
6341 |
29 Jun 21 |
nicklas |
564 |
ImportedItems items = null; |
6341 |
29 Jun 21 |
nicklas |
565 |
MainInfo main = jsonFile.getMain(); |
6341 |
29 Jun 21 |
nicklas |
566 |
ScanBIdRef idRef = main.idRef; |
6495 |
01 Dec 21 |
nicklas |
567 |
if (idRef.idType == SampleIdType.CASE || idRef.idType == SampleIdType.PRENORMALISED_RNA) |
6341 |
29 Jun 21 |
nicklas |
568 |
{ |
7050 |
17 Feb 23 |
nicklas |
569 |
items = importer.doImport(dc, jsonFile, importGateway); |
6341 |
29 Jun 21 |
nicklas |
570 |
} |
6348 |
16 Aug 21 |
nicklas |
571 |
else |
6348 |
16 Aug 21 |
nicklas |
572 |
{ |
6348 |
16 Aug 21 |
nicklas |
573 |
jsonMessages.add("[Error]["+jsonFile.getName()+"] Importing to "+idRef.idType+" is not yet supported"); |
6348 |
16 Aug 21 |
nicklas |
574 |
} |
6734 |
09 May 22 |
nicklas |
575 |
if (items != null && items.importedTo != null) |
6210 |
14 Apr 21 |
nicklas |
576 |
{ |
6913 |
30 Nov 22 |
nicklas |
577 |
numImported++; |
6913 |
30 Nov 22 |
nicklas |
578 |
|
6734 |
09 May 22 |
nicklas |
579 |
String jsonCopyFolder = year.format((jsonFile.getLastModifiedDate()))+"/_NO_FASTQ"; |
6734 |
09 May 22 |
nicklas |
580 |
if (items.demux != null) |
6734 |
09 May 22 |
nicklas |
581 |
{ |
6734 |
09 May 22 |
nicklas |
// Add to FASTQ import pipeline |
6734 |
09 May 22 |
nicklas |
583 |
BiomaterialList.FASTQ_IMPORT_PIPELINE.get(dc).add(items.demux.getItem()); |
6734 |
09 May 22 |
nicklas |
584 |
jsonCopyFolder = (String)Annotationtype.DATA_FILES_FOLDER.getAnnotationValue(dc, items.demux.getItem()); |
6734 |
09 May 22 |
nicklas |
585 |
demuxedSequences.add(items.demux); |
6734 |
09 May 22 |
nicklas |
586 |
} |
6734 |
09 May 22 |
nicklas |
587 |
if (jsonCopyFolder != null) |
6734 |
09 May 22 |
nicklas |
588 |
{ |
6734 |
09 May 22 |
nicklas |
// Save the JSON to Fileserver.IMPORT_ARCHIVE |
6734 |
09 May 22 |
nicklas |
590 |
jsonFile.saveTo(archiveSession, archiveRoot + jsonCopyFolder); |
6960 |
13 Dec 22 |
nicklas |
// Create a link betweem the specimen and archived JSON file |
7240 |
07 Jun 23 |
nicklas |
592 |
importer.createJsonLink(dc, jsonFile, items.importedTo, importArchive, jsonCopyFolder); |
6734 |
09 May 22 |
nicklas |
593 |
} |
6736 |
10 May 22 |
nicklas |
594 |
if (flagRNA && items.rna != null) |
6736 |
10 May 22 |
nicklas |
595 |
{ |
6736 |
10 May 22 |
nicklas |
// Flag the RNA |
6736 |
10 May 22 |
nicklas |
597 |
flaggedRNA.add(items.rna.getExtract()); |
6736 |
10 May 22 |
nicklas |
598 |
Annotationtype.FLAG.setAnnotationValue(dc, items.rna.getExtract(), Rna.FLAG_FASTQ_IMPORT_FAILED); |
6736 |
10 May 22 |
nicklas |
599 |
} |
6736 |
10 May 22 |
nicklas |
600 |
String itemType = ((Subtypable)items.importedTo).getItemSubtype().getName(); |
7032 |
10 Feb 23 |
nicklas |
601 |
ActivityDef.JSON_IMPORT_COMPLETED.merge(dc, 1); |
6348 |
16 Aug 21 |
nicklas |
602 |
dc.commit(); |
6914 |
01 Dec 22 |
nicklas |
603 |
jsonMessages.add("[HTML]"+(jsonFile.hasWarning()?"[Warning]":"")+ |
6914 |
01 Dec 22 |
nicklas |
604 |
"["+jsonFile.getName()+"] Imported data from <b>"+itemType+"</b> ("+ |
6914 |
01 Dec 22 |
nicklas |
605 |
HTML.encodeTags(items.importedTo.getName())+ ") to <b>"+main.endPoint.getName()+"</b> ("+ |
6914 |
01 Dec 22 |
nicklas |
606 |
HTML.encodeTags(main.endPoint.getEndPointItem(items).getName())+"). "+ |
6914 |
01 Dec 22 |
nicklas |
607 |
(jsonFile.hasWarning()?"<b>"+jsonFile.getWarningMessages().size()+" warnings</b>":"")); |
6913 |
30 Nov 22 |
nicklas |
608 |
|
6736 |
10 May 22 |
nicklas |
609 |
if (flagRNA && items.rna != null) |
6736 |
10 May 22 |
nicklas |
610 |
{ |
6736 |
10 May 22 |
nicklas |
611 |
jsonMessages.add("["+jsonFile.getName()+"] Flagged RNA: "+items.rna.getName()); |
6736 |
10 May 22 |
nicklas |
612 |
} |
6734 |
09 May 22 |
nicklas |
613 |
if (jsonCopyFolder != null) |
6734 |
09 May 22 |
nicklas |
614 |
{ |
6734 |
09 May 22 |
nicklas |
// Remove JSON from Filesever.IMPORT_GATEWAY |
6734 |
09 May 22 |
nicklas |
616 |
jsonFile.deleteFrom(gatewaySession, gatewayRoot); |
6734 |
09 May 22 |
nicklas |
617 |
} |
6348 |
16 Aug 21 |
nicklas |
618 |
if (jsonFile.hasError()) |
6348 |
16 Aug 21 |
nicklas |
619 |
{ |
6348 |
16 Aug 21 |
nicklas |
620 |
jsonMessages.addAll(prefix("[Warning]["+jsonFile.getName()+"] ", jsonFile.getErrorMessages())); |
6348 |
16 Aug 21 |
nicklas |
621 |
} |
6210 |
14 Apr 21 |
nicklas |
622 |
} |
6734 |
09 May 22 |
nicklas |
623 |
else |
6734 |
09 May 22 |
nicklas |
624 |
{ |
6913 |
30 Nov 22 |
nicklas |
625 |
numWithError++; |
6734 |
09 May 22 |
nicklas |
626 |
jsonMessages.add("[Error]["+jsonFile.getName()+"] No items created"); |
6913 |
30 Nov 22 |
nicklas |
627 |
dc.close(); |
6734 |
09 May 22 |
nicklas |
628 |
} |
6198 |
07 Apr 21 |
nicklas |
629 |
} |
6198 |
07 Apr 21 |
nicklas |
630 |
|
6914 |
01 Dec 22 |
nicklas |
631 |
if (getDebugMessages) |
6914 |
01 Dec 22 |
nicklas |
632 |
{ |
6914 |
01 Dec 22 |
nicklas |
633 |
jsonMessages.addAll(prefix("[Warning]["+jsonFile.getName()+"] ", jsonFile.getWarningMessages())); |
6914 |
01 Dec 22 |
nicklas |
634 |
jsonMessages.addAll(prefix("[Debug]["+jsonFile.getName()+"] ", jsonFile.getDebugMessages())); |
6914 |
01 Dec 22 |
nicklas |
635 |
} |
6211 |
14 Apr 21 |
nicklas |
636 |
} |
6913 |
30 Nov 22 |
nicklas |
637 |
|
6913 |
30 Nov 22 |
nicklas |
638 |
progress.display(90, "Import complete! Processed " + numProcessed + " JSON files; " + |
6913 |
30 Nov 22 |
nicklas |
639 |
numImported + " successfully imported; "+numWithError+" with error."); |
6913 |
30 Nov 22 |
nicklas |
640 |
Thread.sleep(2000); |
6215 |
16 Apr 21 |
nicklas |
641 |
|
6348 |
16 Aug 21 |
nicklas |
642 |
if (jsonAutoAnalyze != null && demuxedSequences.size() > 0) |
6211 |
14 Apr 21 |
nicklas |
643 |
{ |
6215 |
16 Apr 21 |
nicklas |
644 |
boolean debug = Boolean.TRUE.equals(jsonAutoAnalyze.get("debug")); |
6215 |
16 Apr 21 |
nicklas |
645 |
boolean autoConfirm = Boolean.TRUE.equals(jsonAutoAnalyze.get("autoConfirm")); |
6215 |
16 Apr 21 |
nicklas |
646 |
Number priority = (Number)jsonAutoAnalyze.get("priority"); |
6981 |
17 Jan 23 |
nicklas |
647 |
String partition = Values.getStringOrNull((String)jsonAutoAnalyze.get("partition")); |
6215 |
16 Apr 21 |
nicklas |
648 |
String clusterId = (String)jsonAutoAnalyze.get("cluster"); |
6215 |
16 Apr 21 |
nicklas |
649 |
Number mergeSoftwareId = (Number)jsonAutoAnalyze.get("mergeSoftware"); |
6215 |
16 Apr 21 |
nicklas |
650 |
Number mergeProtocolId = (Number)jsonAutoAnalyze.get("mergeProtocol"); |
7372 |
06 Oct 23 |
nicklas |
651 |
String submitOptions = Values.getStringOrNull((String)jsonReq.get("submitOptionsOverride")); |
6215 |
16 Apr 21 |
nicklas |
652 |
|
6913 |
30 Nov 22 |
nicklas |
653 |
progress.display(95, "Submitting "+demuxedSequences.size()+" FASTQ import jobs to "+cluster.getConnectionInfo().getName()); |
6913 |
30 Nov 22 |
nicklas |
654 |
Thread.sleep(2000); |
6913 |
30 Nov 22 |
nicklas |
655 |
|
6337 |
16 Jun 21 |
nicklas |
656 |
dc = sc.newDbControl(dc.getName()); |
6215 |
16 Apr 21 |
nicklas |
657 |
try |
6210 |
14 Apr 21 |
nicklas |
658 |
{ |
6215 |
16 Apr 21 |
nicklas |
659 |
ImportFastqJobCreator jobCreator = new ImportFastqJobCreator(); |
6215 |
16 Apr 21 |
nicklas |
660 |
jobCreator.setAutoConfirm(autoConfirm); |
6215 |
16 Apr 21 |
nicklas |
661 |
jobCreator.setDebug(debug); |
6215 |
16 Apr 21 |
nicklas |
662 |
if (priority != null) jobCreator.setPriority(priority.intValue()); |
6981 |
17 Jan 23 |
nicklas |
663 |
jobCreator.setPartition(partition); |
7372 |
06 Oct 23 |
nicklas |
664 |
jobCreator.setSubmitOptionsOverride(submitOptions); |
6215 |
16 Apr 21 |
nicklas |
665 |
jobCreator.setMergeProtocol(mergeProtocolId != null ? Protocol.getById(dc, mergeProtocolId.intValue()) : null); |
6215 |
16 Apr 21 |
nicklas |
666 |
jobCreator.setMergeSoftware(mergeSoftwareId != null ? Software.getById(dc, mergeSoftwareId.intValue()) : null); |
6215 |
16 Apr 21 |
nicklas |
667 |
|
6215 |
16 Apr 21 |
nicklas |
668 |
List<JobDefinition> jobDefs = jobCreator.createFastqImportJobs(dc, cluster, demuxedSequences); |
6215 |
16 Apr 21 |
nicklas |
669 |
List<Job> jobs = ScriptUtil.submitJobs(dc, cluster, jobDefs); |
6215 |
16 Apr 21 |
nicklas |
670 |
for (Job job : jobs) |
6211 |
14 Apr 21 |
nicklas |
671 |
{ |
6215 |
16 Apr 21 |
nicklas |
672 |
if (job.getStatus() == Job.Status.ERROR) |
6215 |
16 Apr 21 |
nicklas |
673 |
{ |
6215 |
16 Apr 21 |
nicklas |
674 |
jsonMessages.add("[Warning]Job submission for '" + job.getName() + "' failed: " + job.getStatusMessage()); |
6215 |
16 Apr 21 |
nicklas |
675 |
} |
6215 |
16 Apr 21 |
nicklas |
676 |
else |
6215 |
16 Apr 21 |
nicklas |
677 |
{ |
6215 |
16 Apr 21 |
nicklas |
678 |
jsonMessages.add("Submitted "+job.getName()+" to "+cluster.getConnectionInfo().getName()+" with id "+job.getExternalId()); |
6215 |
16 Apr 21 |
nicklas |
679 |
} |
6211 |
14 Apr 21 |
nicklas |
680 |
} |
6215 |
16 Apr 21 |
nicklas |
681 |
dc.commit(); |
6210 |
14 Apr 21 |
nicklas |
682 |
} |
6215 |
16 Apr 21 |
nicklas |
683 |
catch (Exception ex) |
6215 |
16 Apr 21 |
nicklas |
684 |
{ |
6215 |
16 Apr 21 |
nicklas |
685 |
jsonMessages.add("[Warning]Job submission for FASTQ import failed: "+ ex.getMessage()); |
6215 |
16 Apr 21 |
nicklas |
686 |
} |
6193 |
30 Mar 21 |
nicklas |
687 |
} |
6913 |
30 Nov 22 |
nicklas |
688 |
|
6913 |
30 Nov 22 |
nicklas |
689 |
sc.setSessionSetting("import-json-progress", null); |
6193 |
30 Mar 21 |
nicklas |
690 |
} |
6193 |
30 Mar 21 |
nicklas |
691 |
finally |
6178 |
23 Mar 21 |
nicklas |
692 |
{ |
6209 |
13 Apr 21 |
nicklas |
693 |
OpenGrid.close(gatewaySession); |
6209 |
13 Apr 21 |
nicklas |
694 |
OpenGrid.close(archiveSession); |
6178 |
23 Mar 21 |
nicklas |
695 |
} |
6178 |
23 Mar 21 |
nicklas |
696 |
} |
7139 |
27 Apr 23 |
nicklas |
697 |
else if ("PreValidateTransportFile".equals(cmd) || "ImportFromTransportFile".equals(cmd)) |
7139 |
27 Apr 23 |
nicklas |
698 |
{ |
7139 |
27 Apr 23 |
nicklas |
699 |
String path = Values.getStringOrNull(req.getParameter("path")); |
7139 |
27 Apr 23 |
nicklas |
700 |
String sheet = Values.getStringOrNull(req.getParameter("sheet")); |
7142 |
04 May 23 |
nicklas |
701 |
boolean validateOnly = "PreValidateTransportFile".equals(cmd); |
7167 |
12 May 23 |
nicklas |
702 |
if (validateOnly) forceCount = false; |
7139 |
27 Apr 23 |
nicklas |
703 |
|
7139 |
27 Apr 23 |
nicklas |
704 |
dc = sc.newDbControl(":Import specimen from transport boxes"); |
7162 |
12 May 23 |
nicklas |
705 |
|
7162 |
12 May 23 |
nicklas |
706 |
SimpleProgressReporter progress = new SimpleProgressReporter(null); |
7162 |
12 May 23 |
nicklas |
707 |
sc.setSessionSetting("transport-box-import-progress", progress); |
7161 |
11 May 23 |
nicklas |
708 |
|
7161 |
11 May 23 |
nicklas |
709 |
TransportBoxImporter importer = new TransportBoxImporter(); |
7139 |
27 Apr 23 |
nicklas |
710 |
if (!validateOnly) |
7139 |
27 Apr 23 |
nicklas |
711 |
{ |
7139 |
27 Apr 23 |
nicklas |
712 |
ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.ADMINISTRATOR); |
7161 |
11 May 23 |
nicklas |
713 |
JSONObject jsonReq = JsonUtil.parseRequest(req); |
7191 |
23 May 23 |
nicklas |
714 |
importer.setRequestParameters(jsonReq); |
7139 |
27 Apr 23 |
nicklas |
715 |
} |
7139 |
27 Apr 23 |
nicklas |
716 |
File importFile = File.getByPath(dc, new Path(path, Path.Type.FILE), false); |
7139 |
27 Apr 23 |
nicklas |
717 |
boolean fileIsValidForImport = false; |
7139 |
27 Apr 23 |
nicklas |
718 |
List<String> sheetNames = null; |
7139 |
27 Apr 23 |
nicklas |
719 |
JSONObject jsonImportFile = new JSONObject(); |
7185 |
22 May 23 |
nicklas |
720 |
|
7185 |
22 May 23 |
nicklas |
721 |
fileIsValidForImport = importer.doImport(dc, importFile, sheet, validateOnly, progress); |
7185 |
22 May 23 |
nicklas |
722 |
sheetNames = importer.getWorksheets(); |
7185 |
22 May 23 |
nicklas |
723 |
String fileName = importFile.getName(); |
7185 |
22 May 23 |
nicklas |
724 |
if (sheetNames != null) fileName += "/" + importer.getParsedWorksheet(); |
7185 |
22 May 23 |
nicklas |
725 |
jsonImportFile.put("filename", fileName); |
6178 |
23 Mar 21 |
nicklas |
726 |
|
7139 |
27 Apr 23 |
nicklas |
727 |
jsonImportFile.put("valid", fileIsValidForImport); |
7141 |
02 May 23 |
nicklas |
728 |
jsonImportFile.put("warnings", importer.getTotalWarnings()); |
7141 |
02 May 23 |
nicklas |
729 |
jsonImportFile.put("errors", importer.getTotalErrors()); |
7143 |
05 May 23 |
nicklas |
730 |
jsonImportFile.put("numSamples", importer.getNumSamples()); |
7139 |
27 Apr 23 |
nicklas |
731 |
jsonImportFile.put("numBoxes", importer.getNumBoxes()); |
7143 |
05 May 23 |
nicklas |
732 |
jsonImportFile.put("numMappedToSpecimen", importer.getMappedToSpecimen()); |
7143 |
05 May 23 |
nicklas |
733 |
jsonImportFile.put("numMappedToNoSpecimen", importer.getMappedToNoSpecimen()); |
7143 |
05 May 23 |
nicklas |
734 |
jsonImportFile.put("numMappedToCase", importer.getMappedToCase()); |
7143 |
05 May 23 |
nicklas |
735 |
jsonImportFile.put("numMappedToBlood", importer.getMappedToBlood()); |
7143 |
05 May 23 |
nicklas |
736 |
jsonImportFile.put("numMappedToNothing", importer.getMappedToNothing()); |
7143 |
05 May 23 |
nicklas |
737 |
jsonImportFile.put("numNoConsent", importer.getNumNoConsent()); |
7143 |
05 May 23 |
nicklas |
738 |
|
7139 |
27 Apr 23 |
nicklas |
739 |
if (sheetNames != null) jsonImportFile.put("sheetNames", sheetNames); |
7139 |
27 Apr 23 |
nicklas |
740 |
json.put("importFile", jsonImportFile); |
7139 |
27 Apr 23 |
nicklas |
741 |
|
7191 |
23 May 23 |
nicklas |
742 |
JSONArray jsonBoxes = new JSONArray(); |
7191 |
23 May 23 |
nicklas |
743 |
for (Box b : importer.getBoxes()) |
7191 |
23 May 23 |
nicklas |
744 |
{ |
7191 |
23 May 23 |
nicklas |
745 |
jsonBoxes.add(b.toJSONObject()); |
7191 |
23 May 23 |
nicklas |
746 |
} |
7191 |
23 May 23 |
nicklas |
747 |
json.put("boxes", jsonBoxes); |
7191 |
23 May 23 |
nicklas |
748 |
|
7139 |
27 Apr 23 |
nicklas |
749 |
JSONArray jsonSpecimen = new JSONArray(); |
7139 |
27 Apr 23 |
nicklas |
750 |
for (SampleEntry s : importer.getSpecimen()) |
7139 |
27 Apr 23 |
nicklas |
751 |
{ |
7139 |
27 Apr 23 |
nicklas |
752 |
jsonSpecimen.add(s.toJSONObject()); |
7139 |
27 Apr 23 |
nicklas |
753 |
} |
7139 |
27 Apr 23 |
nicklas |
754 |
json.put("specimen", jsonSpecimen); |
7139 |
27 Apr 23 |
nicklas |
755 |
|
7142 |
04 May 23 |
nicklas |
756 |
if (validateOnly) |
7139 |
27 Apr 23 |
nicklas |
757 |
{ |
7142 |
04 May 23 |
nicklas |
758 |
jsonMessages.addAll(importer.getMessages()); |
7139 |
27 Apr 23 |
nicklas |
759 |
} |
7139 |
27 Apr 23 |
nicklas |
760 |
else |
7139 |
27 Apr 23 |
nicklas |
761 |
{ |
7142 |
04 May 23 |
nicklas |
762 |
if (fileIsValidForImport) |
7139 |
27 Apr 23 |
nicklas |
763 |
{ |
7142 |
04 May 23 |
nicklas |
764 |
jsonMessages.addAll(importer.getMessages()); |
7144 |
05 May 23 |
nicklas |
765 |
jsonMessages.addAll(importer.getDebugMessages()); |
7144 |
05 May 23 |
nicklas |
766 |
ActivityDef.TRANSPORT_BOX_IMPORT_COMPLETED.merge(dc, importer.getNumBoxes(), importer.getNumSamples()); |
7173 |
17 May 23 |
nicklas |
767 |
progress.display(99, "Saving to database..."); |
7186 |
22 May 23 |
nicklas |
768 |
dc.commit(); |
7139 |
27 Apr 23 |
nicklas |
769 |
} |
7142 |
04 May 23 |
nicklas |
770 |
else |
7142 |
04 May 23 |
nicklas |
771 |
{ |
7142 |
04 May 23 |
nicklas |
772 |
jsonMessages.add("[Error] Import failed"); |
7142 |
04 May 23 |
nicklas |
773 |
jsonMessages.addAll(importer.getErrorMessages()); |
7142 |
04 May 23 |
nicklas |
774 |
} |
7139 |
27 Apr 23 |
nicklas |
775 |
} |
7139 |
27 Apr 23 |
nicklas |
776 |
} |
7186 |
22 May 23 |
nicklas |
777 |
else if ("RegisterMoveComplete".equals(cmd)) |
7186 |
22 May 23 |
nicklas |
778 |
{ |
7186 |
22 May 23 |
nicklas |
779 |
dc = sc.newDbControl(":Move external specimen"); |
7186 |
22 May 23 |
nicklas |
780 |
|
7186 |
22 May 23 |
nicklas |
781 |
ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.SAMPLE_PREP, ReggieRole.ADMINISTRATOR); |
7186 |
22 May 23 |
nicklas |
782 |
JSONObject jsonReq = JsonUtil.parseRequest(req); |
7186 |
22 May 23 |
nicklas |
783 |
JSONArray jsonMissing = (JSONArray)jsonReq.get("missingSamples"); |
7186 |
22 May 23 |
nicklas |
784 |
Number boxId = (Number)jsonReq.get("transportBox"); |
7186 |
22 May 23 |
nicklas |
785 |
Date moveDate = Reggie.CONVERTER_STRING_TO_DATE.convert((String)jsonReq.get("moveDate")); |
7186 |
22 May 23 |
nicklas |
786 |
String moveOperator = Values.getStringOrNull((String)jsonReq.get("moveOperator")); |
7186 |
22 May 23 |
nicklas |
787 |
String extraSamples = Values.getStringOrNull((String)jsonReq.get("extraSamples")); |
7186 |
22 May 23 |
nicklas |
788 |
String comments = Values.getStringOrNull((String)jsonReq.get("comments")); |
7186 |
22 May 23 |
nicklas |
789 |
|
7186 |
22 May 23 |
nicklas |
790 |
ItemList transportBox = ItemList.getById(dc, boxId.intValue()); |
7186 |
22 May 23 |
nicklas |
791 |
Annotationtype.MOVE_DATE.setAnnotationValue(dc, transportBox, moveDate); |
7186 |
22 May 23 |
nicklas |
792 |
Annotationtype.MOVE_OPERATOR.setAnnotationValue(dc, transportBox, moveOperator); |
7195 |
24 May 23 |
nicklas |
793 |
List<String> transportMessages = new ArrayList<>((List<String>)Annotationtype.TRANSPORT_MESSAGES.getAnnotationValues(dc, transportBox)); |
7195 |
24 May 23 |
nicklas |
794 |
int numMessages = transportMessages.size(); |
7195 |
24 May 23 |
nicklas |
795 |
if (extraSamples != null) transportMessages.add("Extra samples left in the box: "+extraSamples); |
7186 |
22 May 23 |
nicklas |
796 |
transportBox.setDescription(comments); |
7186 |
22 May 23 |
nicklas |
797 |
|
7195 |
24 May 23 |
nicklas |
// Register missing sample tubes |
7195 |
24 May 23 |
nicklas |
799 |
for (int missingNo = 0; missingNo < jsonMissing.size(); missingNo++) |
7186 |
22 May 23 |
nicklas |
800 |
{ |
7195 |
24 May 23 |
nicklas |
801 |
JSONObject jm = (JSONObject)jsonMissing.get(missingNo); |
7195 |
24 May 23 |
nicklas |
802 |
Number itemId = (Number)jm.get("id"); |
7195 |
24 May 23 |
nicklas |
803 |
String clarityId = (String)jm.get("clarityId"); |
7195 |
24 May 23 |
nicklas |
804 |
MeasuredBioMaterial missing = transportBox.getMemberType().getById(dc, itemId.intValue()); |
7195 |
24 May 23 |
nicklas |
805 |
Annotationtype.FLAG.setAnnotationValue(dc, missing, SpecimenTube.FLAG_MISSING_IN_TRANSPORT_BOX); |
7195 |
24 May 23 |
nicklas |
806 |
transportMessages.add(clarityId + " ("+missing.getName()+") was missing in the transport box"); |
7186 |
22 May 23 |
nicklas |
807 |
} |
7186 |
22 May 23 |
nicklas |
808 |
|
7195 |
24 May 23 |
nicklas |
// Clear the ExternalSpecimenExists annotation |
7186 |
22 May 23 |
nicklas |
810 |
ItemQuery<MeasuredBioMaterial> query = transportBox.getMembers(); |
7186 |
22 May 23 |
nicklas |
811 |
query.include(Reggie.INCLUDE_IN_CURRENT_PROJECT); |
7186 |
22 May 23 |
nicklas |
812 |
for (MeasuredBioMaterial bm : query.list(dc)) |
7186 |
22 May 23 |
nicklas |
813 |
{ |
7186 |
22 May 23 |
nicklas |
814 |
Annotationtype.EXTERNAL_SPECIMEN_EXISTS.setAnnotationValue(dc, bm, null); |
7186 |
22 May 23 |
nicklas |
815 |
} |
7195 |
24 May 23 |
nicklas |
816 |
if (transportMessages.size() > numMessages) |
7195 |
24 May 23 |
nicklas |
817 |
{ |
7195 |
24 May 23 |
nicklas |
818 |
Annotationtype.TRANSPORT_MESSAGES.setAnnotationValues(dc, transportBox, transportMessages); |
7195 |
24 May 23 |
nicklas |
819 |
} |
7186 |
22 May 23 |
nicklas |
820 |
|
7195 |
24 May 23 |
nicklas |
821 |
int movedSamples = transportBox.getSize()-jsonMissing.size(); |
7186 |
22 May 23 |
nicklas |
822 |
ActivityDef.TRANSPORT_BOX_SAMPLES_MOVED.merge(dc, 1, movedSamples); |
7186 |
22 May 23 |
nicklas |
823 |
jsonMessages.add("Moved "+movedSamples+" samples from "+transportBox.getName()); |
7195 |
24 May 23 |
nicklas |
824 |
if (jsonMissing.size() > 0) |
7186 |
22 May 23 |
nicklas |
825 |
{ |
7195 |
24 May 23 |
nicklas |
826 |
jsonMessages.add("There was " + jsonMissing.size() + " missing sample(s)"); |
7186 |
22 May 23 |
nicklas |
827 |
} |
7186 |
22 May 23 |
nicklas |
828 |
dc.commit(); |
7186 |
22 May 23 |
nicklas |
829 |
} |
7139 |
27 Apr 23 |
nicklas |
830 |
|
6178 |
23 Mar 21 |
nicklas |
831 |
json.put("messages", jsonMessages); |
7167 |
12 May 23 |
nicklas |
832 |
if (forceCount) CounterService.getInstance().setForceCount(); |
6178 |
23 Mar 21 |
nicklas |
833 |
} |
6178 |
23 Mar 21 |
nicklas |
834 |
catch (Throwable t) |
6178 |
23 Mar 21 |
nicklas |
835 |
{ |
6178 |
23 Mar 21 |
nicklas |
836 |
t.printStackTrace(); |
6178 |
23 Mar 21 |
nicklas |
837 |
json.clear(); |
6178 |
23 Mar 21 |
nicklas |
838 |
json.put("status", "error"); |
6178 |
23 Mar 21 |
nicklas |
839 |
json.put("message", t.getMessage()); |
6178 |
23 Mar 21 |
nicklas |
840 |
json.put("stacktrace", ThrowableUtil.stackTraceToString(t)); |
6178 |
23 Mar 21 |
nicklas |
841 |
} |
6178 |
23 Mar 21 |
nicklas |
842 |
finally |
6178 |
23 Mar 21 |
nicklas |
843 |
{ |
6178 |
23 Mar 21 |
nicklas |
844 |
if (dc != null) dc.close(); |
6178 |
23 Mar 21 |
nicklas |
845 |
json.writeJSONString(resp.getWriter()); |
6198 |
07 Apr 21 |
nicklas |
846 |
} |
6178 |
23 Mar 21 |
nicklas |
847 |
} |
6178 |
23 Mar 21 |
nicklas |
848 |
|
6199 |
08 Apr 21 |
nicklas |
849 |
/** |
6199 |
08 Apr 21 |
nicklas |
Add a prefix to all messages. |
6199 |
08 Apr 21 |
nicklas |
851 |
*/ |
6199 |
08 Apr 21 |
nicklas |
852 |
private List<String> prefix(String prefix, List<String> messages) |
6199 |
08 Apr 21 |
nicklas |
853 |
{ |
6199 |
08 Apr 21 |
nicklas |
854 |
if (messages.size() == 0) return Collections.emptyList(); |
6199 |
08 Apr 21 |
nicklas |
855 |
List<String> out = new ArrayList<>(messages.size()); |
6199 |
08 Apr 21 |
nicklas |
856 |
for (String m : messages) |
6199 |
08 Apr 21 |
nicklas |
857 |
{ |
6199 |
08 Apr 21 |
nicklas |
858 |
out.add(prefix+m); |
6199 |
08 Apr 21 |
nicklas |
859 |
} |
6199 |
08 Apr 21 |
nicklas |
860 |
return out; |
6199 |
08 Apr 21 |
nicklas |
861 |
} |
6199 |
08 Apr 21 |
nicklas |
862 |
|
6965 |
10 Jan 23 |
nicklas |
863 |
/** |
6965 |
10 Jan 23 |
nicklas |
Move entries from one map to another. If the entry is a JSONObject |
6965 |
10 Jan 23 |
nicklas |
also sort it by key. |
6965 |
10 Jan 23 |
nicklas |
866 |
*/ |
6965 |
10 Jan 23 |
nicklas |
867 |
private void moveJsonObject(String key, Map<String, Object> to, Map<String, Object> from) |
6965 |
10 Jan 23 |
nicklas |
868 |
{ |
6965 |
10 Jan 23 |
nicklas |
869 |
Object t = from.remove(key); |
6965 |
10 Jan 23 |
nicklas |
870 |
if (t != null) |
6965 |
10 Jan 23 |
nicklas |
871 |
{ |
6965 |
10 Jan 23 |
nicklas |
872 |
if (t instanceof JSONObject) t = new TreeMap<>((JSONObject)t); |
6965 |
10 Jan 23 |
nicklas |
873 |
to.put(key, t); |
6965 |
10 Jan 23 |
nicklas |
874 |
} |
6965 |
10 Jan 23 |
nicklas |
875 |
} |
6965 |
10 Jan 23 |
nicklas |
876 |
|
6178 |
23 Mar 21 |
nicklas |
877 |
} |