WIP: Submit transcoding jobs via a HTTP API #6

Draft
ansv7779 wants to merge 22 commits from api-submission into master
5 changed files with 46 additions and 25 deletions
Showing only changes of commit f59eec2ded - Show all commits

View File

@ -70,22 +70,22 @@ public class JDBCTranscriptionRepository implements TranscriptionRepository {
}
@Override
public List<String> getFiles(Transcription transcription) {
public List<SourceFile> getFiles(Transcription transcription) {
return jdbcClient.sql("""
SELECT filename
SELECT id, filename, transcribed_result_uri
FROM transcriptions_files
WHERE transcription_id = :transcription_id
""")
.param("transcription_id", transcription.id())
.query(String.class)
.query(SourceFileRowMapper.INSTANCE)
.list();
}
@Override
public void createNewJob(Transcription transcription, Job job) {
jdbcClient.sql("""
INSERT INTO jobs (id, transcription_id, result_file_absolute_path, error_message)
VALUES (:id, :transcription_id, :result_file, :error_message)
INSERT INTO jobs (id, transcription_id, result_file_absolute_path, error_message, source_file_id)
VALUES (:id, :transcription_id, :result_file, :error_message, :source_file_id)
""")
.param("id", job.id())
.param("transcription_id", transcription.id())
@ -98,15 +98,17 @@ public class JDBCTranscriptionRepository implements TranscriptionRepository {
case Job.Status.Completed(JobCompletion.Failure(String errorMessage)) -> errorMessage;
default -> null;
})
.param("source_file_id", job.sourceFile().id())
.update();
}
@Override
public Optional<Job> findJobById(UUID jobId) {
return jdbcClient.sql("""
SELECT id, result_file_absolute_path, error_message
SELECT jobs.id as jobId, result_file_absolute_path, error_message, tf.id, tf.filename, tf.transcribed_result_uri
FROM jobs
WHERE id = :id
INNER JOIN transcriptions_files tf on jobs.source_file_id = tf.id
WHERE jobs.id = :id
""")
.param("id", jobId)
.query(JobRowMapper.INSTANCE)
@ -153,9 +155,10 @@ public class JDBCTranscriptionRepository implements TranscriptionRepository {
@Override
public List<Job> getJobs(Transcription transcription) {
return jdbcClient.sql("""
SELECT id, result_file_absolute_path, error_message
SELECT jobs.id as jobId, result_file_absolute_path, error_message, tf.id, tf.filename, tf.transcribed_result_uri
FROM jobs
WHERE transcription_id = :transcription_id
INNER JOIN transcriptions_files tf on jobs.source_file_id = tf.id
WHERE jobs.transcription_id = :transcription_id
""")
.param("transcription_id", transcription.id())
.query(JobRowMapper.INSTANCE)
@ -225,8 +228,9 @@ public class JDBCTranscriptionRepository implements TranscriptionRepository {
@Override
public Job mapRow(ResultSet rs, int rowNum) throws SQLException {
UUID id = UUID.fromString(rs.getString("id"));
return new Job(id, getStatus(rs));
SourceFile sourceFile = SourceFileRowMapper.INSTANCE.mapRow(rs, rowNum);
UUID id = UUID.fromString(rs.getString("jobId"));
return new Job(id, getStatus(rs), sourceFile);
}
private Job.Status getStatus(ResultSet rs) throws SQLException {
@ -246,4 +250,18 @@ public class JDBCTranscriptionRepository implements TranscriptionRepository {
record SimplePrincipal(String getName) implements Principal {
}
private enum SourceFileRowMapper implements RowMapper<SourceFile> {
INSTANCE;
@Override
public SourceFile mapRow(ResultSet rs, int rowNum)
throws SQLException
{
UUID id = UUID.fromString(rs.getString("id"));
String filename = rs.getString("filename");
URI downloadUri = URI.create(rs.getString("transcribed_result_uri"));
return new SourceFile(id, filename, downloadUri);
}
}
}

View File

@ -2,7 +2,7 @@ package se.su.dsv.whisperapi.core;
import java.util.UUID;
public record Job(UUID id, Status status) {
public record Job(UUID id, Status status, SourceFile sourceFile) {
public sealed interface Status {
record Pending() implements Status {}
record Completed(JobCompletion completion) implements Status {}

View File

@ -14,10 +14,10 @@ public interface TranscriptionRepository {
void addFileToTranscription(Transcription transcription, SourceFile sourceFile);
/**
* @return the list of filenames that have been {@link #addFileToTranscription added}
* @return all the files that have been {@link #addFileToTranscription added}
* to the transcription.
*/
List<String> getFiles(Transcription transcription);
List<SourceFile> getFiles(Transcription transcription);
/**
* @param transcription the transcription this specific job is a part of

View File

@ -72,10 +72,10 @@ public class TranscriptionService {
public void submitTranscriptionJob(Transcription transcription, CallbackUriGenerator callbackUriGenerator) {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
List<String> filenames = transcriptionRepository.getFiles(transcription);
for (String filename : filenames) {
List<SourceFile> files = transcriptionRepository.getFiles(transcription);
for (SourceFile file : files) {
UUID jobId = UUID.randomUUID();
Path fileToBeTranscribed = fileDirectory.resolve(transcription.id().toString()).resolve(filename);
Path fileToBeTranscribed = fileDirectory.resolve(transcription.id().toString()).resolve(file.id().toString());
Path jobFile = jobsDirectory.resolve(jobId + ".json");
URI callbackUri = callbackUriGenerator.generateCallbackUri(jobId);
@ -94,7 +94,7 @@ public class TranscriptionService {
try (var out = Files.newOutputStream(jobFile, StandardOpenOption.CREATE_NEW)) {
objectMapper.writeValue(out, whisperJob);
Job job = new Job(jobId, new Job.Status.Pending());
Job job = new Job(jobId, new Job.Status.Pending(), file);
transcriptionRepository.createNewJob(transcription, job);
} catch (IOException e) {
throw new UncheckedIOException(e);
@ -158,12 +158,13 @@ public class TranscriptionService {
URI callbackUri = transcription.callbackUri();
List<Callback.File> files = jobs.stream()
.<Callback.File>map(job -> {
SourceFile sourceFile = job.sourceFile();
switch (job.status()) {
case Job.Status.Completed(JobCompletion.Success ignored) -> {
return new Callback.File.Transcribed("<unknown>", "http://"); //job.transcribedDownloadLink());
return new Callback.File.Transcribed(sourceFile.filename(), sourceFile.downloadUri().toString());
}
case Job.Status.Completed(JobCompletion.Failure(String errorMessage)) -> {
return new Callback.File.Failed("<unknown>", errorMessage);
return new Callback.File.Failed(sourceFile.filename(), errorMessage);
}
case Job.Status.Pending() -> throw new IllegalStateException("Job should be completed");
}
@ -175,11 +176,7 @@ public class TranscriptionService {
HttpRequest request = HttpRequest.newBuilder()
.uri(callbackUri)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString("""
{
"id": "%s",
"status": "completed"
}"""))
.POST(HttpRequest.BodyPublishers.ofString(objectMapper.writeValueAsString(callback)))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
return response.statusCode() == 200;

View File

@ -0,0 +1,6 @@
ALTER TABLE `jobs`
ADD COLUMN `source_file_id` UUID NOT NULL;
ALTER TABLE `jobs`
ADD CONSTRAINT `FK_jobs_transcription_files_source_file`
FOREIGN KEY (`source_file_id`) REFERENCES `transcriptions_files` (`id`);