Skip to content

Commit d252e42

Browse files
committed
Implement json endpoint
1 parent ae0f5df commit d252e42

2 files changed

Lines changed: 83 additions & 14 deletions

File tree

src/main/java/massbank_export_api/api/ConvertApiDelegateImpl.java

Lines changed: 61 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package massbank_export_api.api;
22

3+
import com.fasterxml.jackson.databind.ObjectMapper;
34
import massbank.RecordParser;
45
import massbank.export.RecordToNIST_MSP;
56
import massbank.export.RecordToRIKEN_MSP;
@@ -10,6 +11,7 @@
1011
import org.springframework.beans.factory.annotation.Autowired;
1112
import org.springframework.context.annotation.Primary;
1213
import org.springframework.core.io.ByteArrayResource;
14+
import org.springframework.core.io.InputStreamResource;
1315
import org.springframework.core.io.Resource;
1416
import org.springframework.http.HttpHeaders;
1517
import org.springframework.http.MediaType;
@@ -18,6 +20,8 @@
1820

1921
import java.io.ByteArrayOutputStream;
2022
import java.io.IOException;
23+
import java.io.PipedInputStream;
24+
import java.io.PipedOutputStream;
2125
import java.nio.charset.StandardCharsets;
2226
import java.util.HashSet;
2327
import java.util.Objects;
@@ -46,9 +50,9 @@ public ConvertApiDelegateImpl(RecordServiceImplementation recordServiceImplement
4650
@Override
4751
public ResponseEntity<Resource> convertPost(Conversion conversion) {
4852
String formatValue = conversion.getFormat() != null ? conversion.getFormat().getValue() : "";
49-
final ByteArrayResource resource;
50-
final String filename;
51-
final MediaType mediaType;
53+
Resource resource = null;
54+
String filename = null;
55+
MediaType mediaType = null;
5256

5357
final RecordParser recordparser = new RecordParser(new HashSet<>());
5458

@@ -103,9 +107,9 @@ public ResponseEntity<Resource> convertPost(Conversion conversion) {
103107
record.indexOf("\n", record.indexOf("ACCESSION:"))).trim();
104108
try {
105109
final ZipEntry entry = new ZipEntry(accession + ".txt");
106-
synchronized (zos) { // Synchronize access to ZipOutputStream
110+
synchronized (zos) {
107111
zos.putNextEntry(entry);
108-
zos.write(record.toString().getBytes(StandardCharsets.UTF_8));
112+
zos.write(record.getBytes(StandardCharsets.UTF_8));
109113
zos.closeEntry();
110114
}
111115
} catch (IOException e) {
@@ -118,6 +122,40 @@ public ResponseEntity<Resource> convertPost(Conversion conversion) {
118122
throw new RuntimeException("Error creating zip file", e);
119123
}
120124
break;
125+
case "json":
126+
mediaType = MediaType.parseMediaType("application/jsonl");
127+
try {
128+
PipedOutputStream pos = new PipedOutputStream();
129+
PipedInputStream pis = new PipedInputStream(pos);
130+
new Thread(() -> {
131+
try {
132+
ObjectMapper mapper = new ObjectMapper();
133+
boolean first = true;
134+
for (String accession : conversion.getRecordList()) {
135+
DbRecord dbRecord = recordServiceImplementation.findByAccession(accession);
136+
if (dbRecord == null) continue;
137+
Result parseResult = recordparser.parse(dbRecord.getContent());
138+
if (!parseResult.isSuccess()) continue;
139+
massbank.Record record = (massbank.Record) parseResult.get();
140+
String json = mapper.writeValueAsString(massbank.export.RecordToJson.convert(record));
141+
if (!first) {
142+
pos.write('\n');
143+
} else {
144+
first = false;
145+
}
146+
pos.write(json.getBytes(StandardCharsets.UTF_8));
147+
}
148+
pos.close();
149+
} catch (IOException e) {
150+
throw new RuntimeException("Error streaming JSONL", e);
151+
}
152+
}).start();
153+
resource = new InputStreamResource(pis);
154+
} catch (IOException e) {
155+
throw new RuntimeException("Error creating stream for JSONL", e);
156+
}
157+
filename = null;
158+
break;
121159
default:
122160
String message = "Missing or unsupported format value.";
123161
resource = new ByteArrayResource(message.getBytes(StandardCharsets.UTF_8));
@@ -126,14 +164,24 @@ public ResponseEntity<Resource> convertPost(Conversion conversion) {
126164
.body(resource);
127165
}
128166

129-
HttpHeaders headers = new HttpHeaders();
130-
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + filename);
131-
132-
return ResponseEntity.ok()
133-
.headers(headers)
134-
.contentLength(resource.contentLength())
135-
.contentType(mediaType)
136-
.body(resource);
167+
if ("json".equals(formatValue)) {
168+
// Kein Download, sondern Stream
169+
return ResponseEntity.ok()
170+
.contentType(mediaType)
171+
.body(resource);
172+
} else {
173+
HttpHeaders headers = new HttpHeaders();
174+
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + filename);
175+
long contentLength = -1;
176+
try {
177+
contentLength = resource.contentLength();
178+
} catch (IOException ignored) {}
179+
return ResponseEntity.ok()
180+
.headers(headers)
181+
.contentLength(contentLength)
182+
.contentType(mediaType)
183+
.body(resource);
184+
}
137185
}
138186

139187
}

src/test/java/massbank_export_api/ExportApiControllerTest.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,4 +525,25 @@ public void testValidation() throws Exception {
525525
.andExpect(content().json(expectedResponse));
526526
}
527527

528-
}
528+
@Test
529+
public void testCreateConversionTaskJsonL() throws Exception {
530+
String requestBody = "{ \"record_list\": [\"MSBNK-IPB_Halle-PB001341\", \"MSBNK-IPB_Halle-PB000125\"], \"format\": \"json\" }";
531+
532+
var mvcResult = mockMvc.perform(post("/convert")
533+
.contentType("application/json")
534+
.content(requestBody))
535+
.andExpect(status().isOk())
536+
.andExpect(content().contentType("application/jsonl"))
537+
.andReturn();
538+
539+
String response = mvcResult.getResponse().getContentAsString();
540+
String[] lines = response.split("\\n");
541+
assertEquals(2, lines.length, "Es sollten zwei JSON-Objekte im Stream sein");
542+
for (String line : lines) {
543+
assertDoesNotThrow(() -> {
544+
new com.fasterxml.jackson.databind.ObjectMapper().readTree(line);
545+
}, "Zeile ist kein valides JSON: " + line);
546+
}
547+
}
548+
549+
}

0 commit comments

Comments
 (0)