Add more submission logic.
This commit is contained in:
parent
1ade7ffe66
commit
52be976286
|
@ -13,16 +13,20 @@ import nl.andrewlalis.gymboard_api.domains.submission.model.Submission;
|
|||
import nl.andrewlalis.gymboard_api.domains.api.service.cdn_client.CdnClient;
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.dao.UserRepository;
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.model.User;
|
||||
import nl.andrewlalis.gymboard_api.domains.submission.model.SubmissionProperties;
|
||||
import nl.andrewlalis.gymboard_api.util.ULID;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Service which handles the rather mundane tasks associated with exercise
|
||||
|
@ -89,17 +93,23 @@ public class ExerciseSubmissionService {
|
|||
if (weightUnit == WeightUnit.POUNDS) {
|
||||
metricWeight = WeightUnit.toKilograms(rawWeight);
|
||||
}
|
||||
Submission submission = submissionRepository.saveAndFlush(new Submission(
|
||||
ulid.nextULID(), gym, exercise, user,
|
||||
SubmissionProperties properties = new SubmissionProperties(
|
||||
exercise,
|
||||
performedAt,
|
||||
payload.taskId(),
|
||||
rawWeight, weightUnit, metricWeight, payload.reps()
|
||||
));
|
||||
rawWeight,
|
||||
weightUnit,
|
||||
payload.reps()
|
||||
);
|
||||
|
||||
Submission submission = new Submission(ulid.nextULID(), gym, user, payload.taskId(), properties);
|
||||
try {
|
||||
cdnClient.uploads.startTask(submission.getVideoProcessingTaskId());
|
||||
submission.setProcessing(true);
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to start video processing task for submission " + submission.getId(), e);
|
||||
log.error("Failed to start video processing task for submission.", e);
|
||||
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Failed to start video processing.");
|
||||
}
|
||||
submission = submissionRepository.save(submission);
|
||||
return new SubmissionResponse(submission);
|
||||
}
|
||||
|
||||
|
@ -125,7 +135,7 @@ public class ExerciseSubmissionService {
|
|||
|
||||
try {
|
||||
var status = cdnClient.uploads.getVideoProcessingTaskStatus(data.taskId());
|
||||
if (!status.status().equalsIgnoreCase("NOT_STARTED")) {
|
||||
if (status == null || !status.status().equalsIgnoreCase("NOT_STARTED")) {
|
||||
response.addMessage("Invalid video processing task.");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -156,6 +166,14 @@ public class ExerciseSubmissionService {
|
|||
submissionRepository.delete(submission);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is invoked when the CDN calls this API's endpoint to notify
|
||||
* us that a video processing task has completed. If the task completed
|
||||
* successfully, we can set any related submissions' video and thumbnail
|
||||
* file ids and remove its "processing" flag. Otherwise, we should delete
|
||||
* the failed submission.
|
||||
* @param payload The information about the task.
|
||||
*/
|
||||
@Transactional
|
||||
public void handleVideoProcessingComplete(VideoProcessingCompletePayload payload) {
|
||||
var submissionsToUpdate = submissionRepository.findUnprocessedByTaskId(payload.taskId());
|
||||
|
@ -164,6 +182,7 @@ public class ExerciseSubmissionService {
|
|||
if (payload.status().equalsIgnoreCase("COMPLETE")) {
|
||||
submission.setVideoFileId(payload.videoFileId());
|
||||
submission.setThumbnailFileId(payload.thumbnailFileId());
|
||||
submission.setProcessing(false);
|
||||
submissionRepository.save(submission);
|
||||
// TODO: Send notification of successful processing to the user!
|
||||
} else if (payload.status().equalsIgnoreCase("FAILED")) {
|
||||
|
@ -172,4 +191,94 @@ public class ExerciseSubmissionService {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A scheduled task that checks and resolves issues with any submission that
|
||||
* stays in the "processing" state for too long.
|
||||
* TODO: Find some way to clean up this mess of logic!
|
||||
*/
|
||||
@Scheduled(fixedDelay = 5, timeUnit = TimeUnit.MINUTES)
|
||||
public void checkProcessingSubmissions() {
|
||||
var processingSubmissions = submissionRepository.findAllByProcessingTrue();
|
||||
LocalDateTime actionCutoff = LocalDateTime.now().minus(Duration.ofMinutes(10));
|
||||
LocalDateTime deleteCutoff = LocalDateTime.now().minus(Duration.ofMinutes(30));
|
||||
for (var submission : processingSubmissions) {
|
||||
if (submission.getCreatedAt().isBefore(actionCutoff)) {
|
||||
// Sanity check to remove any inconsistent submission that doesn't have a task id for whatever reason.
|
||||
if (submission.getVideoProcessingTaskId() == null) {
|
||||
log.warn(
|
||||
"Removing long-processing submission {} for user {} because it doesn't have a task id.",
|
||||
submission.getId(), submission.getUser().getEmail()
|
||||
);
|
||||
submissionRepository.delete(submission);
|
||||
// TODO: Send notification to user.
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
var status = cdnClient.uploads.getVideoProcessingTaskStatus(submission.getVideoProcessingTaskId());
|
||||
if (status == null) {
|
||||
// The task no longer exists on the CDN, so remove the submission.
|
||||
log.warn(
|
||||
"Removing long-processing submission {} for user {} because its task no longer exists on the CDN.",
|
||||
submission.getId(), submission.getUser().getEmail()
|
||||
);
|
||||
submissionRepository.delete(submission);
|
||||
// TODO: Send notification to user.
|
||||
} else if (status.status().equalsIgnoreCase("FAILED")) {
|
||||
// The task failed, so we should remove the submission.
|
||||
log.warn(
|
||||
"Removing long-processing submission {} for user {} because its task failed.",
|
||||
submission.getId(), submission.getUser().getEmail()
|
||||
);
|
||||
submissionRepository.delete(submission);
|
||||
// TODO: Send notification to user.
|
||||
} else if (status.status().equalsIgnoreCase("COMPLETED")) {
|
||||
// The submission should be marked as complete.
|
||||
submission.setVideoFileId(status.videoFileId());
|
||||
submission.setThumbnailFileId(status.thumbnailFileId());
|
||||
submission.setProcessing(false);
|
||||
submissionRepository.save(submission);
|
||||
// TODO: Send notification to user.
|
||||
} else if (status.status().equalsIgnoreCase("NOT_STARTED")) {
|
||||
// If for whatever reason the submission's video processing never started, start now.
|
||||
try {
|
||||
cdnClient.uploads.startTask(submission.getVideoProcessingTaskId());
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to start processing task " + submission.getVideoProcessingTaskId(), e);
|
||||
if (submission.getCreatedAt().isBefore(deleteCutoff)) {
|
||||
log.warn(
|
||||
"Removing long-processing submission {} for user {} because it is waiting or processing for too long.",
|
||||
submission.getId(), submission.getUser().getEmail()
|
||||
);
|
||||
submissionRepository.delete(submission);
|
||||
// TODO: Send notification to user.
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// The task is waiting or processing, so delete the submission if it's been in that state for an unreasonably long time.
|
||||
if (submission.getCreatedAt().isBefore(deleteCutoff)) {
|
||||
log.warn(
|
||||
"Removing long-processing submission {} for user {} because it is waiting or processing for too long.",
|
||||
submission.getId(), submission.getUser().getEmail()
|
||||
);
|
||||
submissionRepository.delete(submission);
|
||||
// TODO: Send notification to user.
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Couldn't fetch status of long-processing submission " + submission.getId() + " for user " + submission.getUser().getEmail(), e);
|
||||
// We can't reliably remove this submission yet, so we'll try again on the next pass.
|
||||
if (submission.getCreatedAt().isBefore(deleteCutoff)) {
|
||||
log.warn(
|
||||
"Removing long-processing submission {} for user {} because it is waiting or processing for too long.",
|
||||
submission.getId(), submission.getUser().getEmail()
|
||||
);
|
||||
submissionRepository.delete(submission);
|
||||
// TODO: Send notification to user.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@ public interface SubmissionRepository extends JpaRepository<Submission, String>,
|
|||
|
||||
@Query("SELECT s FROM Submission s " +
|
||||
"WHERE s.videoProcessingTaskId = :taskId AND " +
|
||||
"(s.videoFileId IS NULL OR s.thumbnailFileId IS NULL)")
|
||||
"s.processing = TRUE")
|
||||
List<Submission> findUnprocessedByTaskId(long taskId);
|
||||
|
||||
List<Submission> findAllByProcessingTrue();
|
||||
}
|
||||
|
|
|
@ -10,34 +10,39 @@ public record SubmissionResponse(
|
|||
String id,
|
||||
String createdAt,
|
||||
GymSimpleResponse gym,
|
||||
ExerciseResponse exercise,
|
||||
UserResponse user,
|
||||
String performedAt,
|
||||
long videoProcessingTaskId,
|
||||
String videoFileId,
|
||||
String thumbnailFileId,
|
||||
boolean processing,
|
||||
boolean verified,
|
||||
|
||||
// From SubmissionProperties
|
||||
ExerciseResponse exercise,
|
||||
String performedAt,
|
||||
double rawWeight,
|
||||
String weightUnit,
|
||||
double metricWeight,
|
||||
int reps,
|
||||
boolean verified
|
||||
int reps
|
||||
) {
|
||||
public SubmissionResponse(Submission submission) {
|
||||
this(
|
||||
submission.getId(),
|
||||
StandardDateFormatter.format(submission.getCreatedAt()),
|
||||
new GymSimpleResponse(submission.getGym()),
|
||||
new ExerciseResponse(submission.getExercise()),
|
||||
new UserResponse(submission.getUser()),
|
||||
StandardDateFormatter.format(submission.getPerformedAt()),
|
||||
submission.getVideoProcessingTaskId(),
|
||||
submission.getVideoFileId(),
|
||||
submission.getThumbnailFileId(),
|
||||
submission.getRawWeight().doubleValue(),
|
||||
submission.getWeightUnit().name(),
|
||||
submission.getMetricWeight().doubleValue(),
|
||||
submission.getReps(),
|
||||
submission.isVerified()
|
||||
submission.isProcessing(),
|
||||
submission.isVerified(),
|
||||
|
||||
new ExerciseResponse(submission.getProperties().getExercise()),
|
||||
StandardDateFormatter.format(submission.getCreatedAt()),
|
||||
submission.getProperties().getRawWeight().doubleValue(),
|
||||
submission.getProperties().getWeightUnit().name(),
|
||||
submission.getProperties().getMetricWeight().doubleValue(),
|
||||
submission.getProperties().getReps()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,33 @@
|
|||
package nl.andrewlalis.gymboard_api.domains.submission.model;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import nl.andrewlalis.gymboard_api.domains.api.model.Exercise;
|
||||
import nl.andrewlalis.gymboard_api.domains.api.model.Gym;
|
||||
import nl.andrewlalis.gymboard_api.domains.api.model.WeightUnit;
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.model.User;
|
||||
import org.hibernate.annotations.CreationTimestamp;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* The Submission entity represents a user's posted video of a lift they did at
|
||||
* a gym.
|
||||
* <p>
|
||||
* A submission is created in the front-end using the following flow:
|
||||
* </p>
|
||||
* <ol>
|
||||
* <li>User uploads a raw video of their lift.</li>
|
||||
* <li>User enters some basic information about the lift.</li>
|
||||
* <li>User submits the lift.</li>
|
||||
* <li>API validates the information.</li>
|
||||
* <li>API creates a new Submission, and tells the CDN service to process
|
||||
* the uploaded video.</li>
|
||||
* <li>Once processing completes successfully, the CDN sends the final video
|
||||
* and thumbnail file ids to the API and the Submission's "processing" flag
|
||||
* is removed.</li>
|
||||
* <li>If for whatever reason the CDN's video processing fails or never
|
||||
* completes, the Submission is deleted and the user is notified of the
|
||||
* issue.</li>
|
||||
* </ol>
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "submission")
|
||||
public class Submission {
|
||||
|
@ -23,22 +41,16 @@ public class Submission {
|
|||
@ManyToOne(optional = false, fetch = FetchType.LAZY)
|
||||
private Gym gym;
|
||||
|
||||
@ManyToOne(optional = false, fetch = FetchType.LAZY)
|
||||
private Exercise exercise;
|
||||
|
||||
@ManyToOne(optional = false, fetch = FetchType.LAZY)
|
||||
private User user;
|
||||
|
||||
@Column(nullable = false)
|
||||
private LocalDateTime performedAt;
|
||||
|
||||
/**
|
||||
* The id of the video processing task that a user gives to us when they
|
||||
* create the submission, so that when the task finishes processing, we can
|
||||
* route its data to the right submission.
|
||||
*/
|
||||
@Column(nullable = false, updatable = false)
|
||||
private long videoProcessingTaskId;
|
||||
@Column
|
||||
private Long videoProcessingTaskId;
|
||||
|
||||
/**
|
||||
* The id of the video file that was submitted for this submission. It lives
|
||||
|
@ -55,18 +67,19 @@ public class Submission {
|
|||
@Column(length = 26)
|
||||
private String thumbnailFileId = null;
|
||||
|
||||
@Column(nullable = false, precision = 7, scale = 2)
|
||||
private BigDecimal rawWeight;
|
||||
/**
|
||||
* The user-specified properties of the submission.
|
||||
*/
|
||||
@Embedded
|
||||
private SubmissionProperties properties;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
/**
|
||||
* A flag that indicates whether this submission is currently processing.
|
||||
* A submission is processing until its associated processing task completes
|
||||
* either successfully or unsuccessfully.
|
||||
*/
|
||||
@Column(nullable = false)
|
||||
private WeightUnit weightUnit;
|
||||
|
||||
@Column(nullable = false, precision = 7, scale = 2)
|
||||
private BigDecimal metricWeight;
|
||||
|
||||
@Column(nullable = false)
|
||||
private int reps;
|
||||
private boolean processing;
|
||||
|
||||
@Column(nullable = false)
|
||||
private boolean verified;
|
||||
|
@ -76,25 +89,15 @@ public class Submission {
|
|||
public Submission(
|
||||
String id,
|
||||
Gym gym,
|
||||
Exercise exercise,
|
||||
User user,
|
||||
LocalDateTime performedAt,
|
||||
long videoProcessingTaskId,
|
||||
BigDecimal rawWeight,
|
||||
WeightUnit unit,
|
||||
BigDecimal metricWeight,
|
||||
int reps
|
||||
SubmissionProperties properties
|
||||
) {
|
||||
this.id = id;
|
||||
this.gym = gym;
|
||||
this.exercise = exercise;
|
||||
this.user = user;
|
||||
this.performedAt = performedAt;
|
||||
this.videoProcessingTaskId = videoProcessingTaskId;
|
||||
this.rawWeight = rawWeight;
|
||||
this.weightUnit = unit;
|
||||
this.metricWeight = metricWeight;
|
||||
this.reps = reps;
|
||||
this.properties = properties;
|
||||
this.verified = false;
|
||||
}
|
||||
|
||||
|
@ -110,11 +113,7 @@ public class Submission {
|
|||
return gym;
|
||||
}
|
||||
|
||||
public Exercise getExercise() {
|
||||
return exercise;
|
||||
}
|
||||
|
||||
public long getVideoProcessingTaskId() {
|
||||
public Long getVideoProcessingTaskId() {
|
||||
return videoProcessingTaskId;
|
||||
}
|
||||
|
||||
|
@ -138,24 +137,16 @@ public class Submission {
|
|||
return user;
|
||||
}
|
||||
|
||||
public LocalDateTime getPerformedAt() {
|
||||
return performedAt;
|
||||
public SubmissionProperties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public BigDecimal getRawWeight() {
|
||||
return rawWeight;
|
||||
public boolean isProcessing() {
|
||||
return processing;
|
||||
}
|
||||
|
||||
public WeightUnit getWeightUnit() {
|
||||
return weightUnit;
|
||||
}
|
||||
|
||||
public BigDecimal getMetricWeight() {
|
||||
return metricWeight;
|
||||
}
|
||||
|
||||
public int getReps() {
|
||||
return reps;
|
||||
public void setProcessing(boolean processing) {
|
||||
this.processing = processing;
|
||||
}
|
||||
|
||||
public boolean isVerified() {
|
||||
|
|
|
@ -1,129 +0,0 @@
|
|||
package nl.andrewlalis.gymboard_api.domains.submission.model;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import nl.andrewlalis.gymboard_api.domains.api.model.Exercise;
|
||||
import nl.andrewlalis.gymboard_api.domains.api.model.Gym;
|
||||
import nl.andrewlalis.gymboard_api.domains.api.model.WeightUnit;
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.model.User;
|
||||
import org.hibernate.annotations.CreationTimestamp;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* A submission draft is a temporary entity that exists while a user is
|
||||
* preparing their submission. It includes all the data needed to make a
|
||||
* submission, so when the user has finished editing, they can "submit" their
|
||||
* draft and video processing will then begin, and once done, their submission
|
||||
* will be published.
|
||||
* <p>
|
||||
* <strong>This is not yet implemented!</strong>
|
||||
* </p>
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "submission_draft")
|
||||
public class SubmissionDraft {
|
||||
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@CreationTimestamp
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@ManyToOne(optional = false, fetch = FetchType.LAZY)
|
||||
private User user;
|
||||
|
||||
@ManyToOne(optional = false, fetch = FetchType.LAZY)
|
||||
private Gym gym;
|
||||
|
||||
// All of the following properties are editable while this draft has not yet
|
||||
// been submitted. They will be validated upon submission.
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
private Exercise exercise;
|
||||
|
||||
@Column
|
||||
private LocalDateTime performedAt;
|
||||
|
||||
@Column(precision = 7, scale = 2)
|
||||
private BigDecimal rawWeight;
|
||||
|
||||
@Column @Enumerated(EnumType.STRING)
|
||||
private WeightUnit weightUnit;
|
||||
|
||||
@Column
|
||||
private int reps;
|
||||
|
||||
@Column
|
||||
private long videoProcessingTaskId;
|
||||
|
||||
public SubmissionDraft() {}
|
||||
|
||||
public SubmissionDraft(User user, Gym gym) {
|
||||
this.user = user;
|
||||
this.gym = gym;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public Gym getGym() {
|
||||
return gym;
|
||||
}
|
||||
|
||||
public Exercise getExercise() {
|
||||
return exercise;
|
||||
}
|
||||
|
||||
public LocalDateTime getPerformedAt() {
|
||||
return performedAt;
|
||||
}
|
||||
|
||||
public BigDecimal getRawWeight() {
|
||||
return rawWeight;
|
||||
}
|
||||
|
||||
public WeightUnit getWeightUnit() {
|
||||
return weightUnit;
|
||||
}
|
||||
|
||||
public int getReps() {
|
||||
return reps;
|
||||
}
|
||||
|
||||
public long getVideoProcessingTaskId() {
|
||||
return videoProcessingTaskId;
|
||||
}
|
||||
|
||||
public void setExercise(Exercise exercise) {
|
||||
this.exercise = exercise;
|
||||
}
|
||||
|
||||
public void setPerformedAt(LocalDateTime performedAt) {
|
||||
this.performedAt = performedAt;
|
||||
}
|
||||
|
||||
public void setRawWeight(BigDecimal rawWeight) {
|
||||
this.rawWeight = rawWeight;
|
||||
}
|
||||
|
||||
public void setWeightUnit(WeightUnit weightUnit) {
|
||||
this.weightUnit = weightUnit;
|
||||
}
|
||||
|
||||
public void setReps(int reps) {
|
||||
this.reps = reps;
|
||||
}
|
||||
|
||||
public void setVideoProcessingTaskId(long videoProcessingTaskId) {
|
||||
this.videoProcessingTaskId = videoProcessingTaskId;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package nl.andrewlalis.gymboard_api.domains.submission.model;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import nl.andrewlalis.gymboard_api.domains.api.model.Exercise;
|
||||
import nl.andrewlalis.gymboard_api.domains.api.model.WeightUnit;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* Basic user-specified properties about a Submission.
|
||||
*/
|
||||
@Embeddable
|
||||
public class SubmissionProperties {
|
||||
@ManyToOne(optional = false, fetch = FetchType.LAZY)
|
||||
private Exercise exercise;
|
||||
|
||||
@Column(nullable = false)
|
||||
private LocalDateTime performedAt;
|
||||
|
||||
@Column(nullable = false, precision = 7, scale = 2)
|
||||
private BigDecimal rawWeight;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(nullable = false)
|
||||
private WeightUnit weightUnit;
|
||||
|
||||
@Column(nullable = false, precision = 7, scale = 2)
|
||||
private BigDecimal metricWeight;
|
||||
|
||||
@Column(nullable = false)
|
||||
private int reps;
|
||||
|
||||
public SubmissionProperties() {}
|
||||
|
||||
public SubmissionProperties(
|
||||
Exercise exercise,
|
||||
LocalDateTime performedAt,
|
||||
BigDecimal rawWeight,
|
||||
WeightUnit weightUnit,
|
||||
int reps
|
||||
) {
|
||||
this.exercise = exercise;
|
||||
this.performedAt = performedAt;
|
||||
this.rawWeight = rawWeight;
|
||||
this.weightUnit = weightUnit;
|
||||
this.metricWeight = WeightUnit.toKilograms(rawWeight, weightUnit);
|
||||
this.reps = reps;
|
||||
}
|
||||
|
||||
public Exercise getExercise() {
|
||||
return exercise;
|
||||
}
|
||||
|
||||
public LocalDateTime getPerformedAt() {
|
||||
return performedAt;
|
||||
}
|
||||
|
||||
public BigDecimal getRawWeight() {
|
||||
return rawWeight;
|
||||
}
|
||||
|
||||
public WeightUnit getWeightUnit() {
|
||||
return weightUnit;
|
||||
}
|
||||
|
||||
public BigDecimal getMetricWeight() {
|
||||
return metricWeight;
|
||||
}
|
||||
|
||||
public int getReps() {
|
||||
return reps;
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ import nl.andrewlalis.gymboard_api.domains.api.service.cdn_client.CdnClient;
|
|||
import nl.andrewlalis.gymboard_api.domains.api.service.cdn_client.UploadsClient;
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.dao.UserRepository;
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.model.User;
|
||||
import nl.andrewlalis.gymboard_api.domains.submission.model.SubmissionProperties;
|
||||
import nl.andrewlalis.gymboard_api.util.ULID;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -50,6 +51,8 @@ public class SampleSubmissionGenerator implements SampleDataGenerator {
|
|||
|
||||
@Override
|
||||
public void generate() throws Exception {
|
||||
// First we generate a small set of uploaded files that all the
|
||||
// submissions can link to, instead of having them all upload new content.
|
||||
var uploads = generateUploads();
|
||||
|
||||
// Now that uploads are complete, we can proceed with generating the submissions.
|
||||
|
@ -76,8 +79,6 @@ public class SampleSubmissionGenerator implements SampleDataGenerator {
|
|||
submissions.add(submission);
|
||||
}
|
||||
submissionRepository.saveAll(submissions);
|
||||
|
||||
// After adding all the submissions, we'll signal to CDN that it can start processing.
|
||||
}
|
||||
|
||||
private Submission generateRandomSubmission(
|
||||
|
@ -97,20 +98,23 @@ public class SampleSubmissionGenerator implements SampleDataGenerator {
|
|||
weightUnit = WeightUnit.POUNDS;
|
||||
rawWeight = metricWeight.multiply(new BigDecimal("2.2046226218"));
|
||||
}
|
||||
SubmissionProperties properties = new SubmissionProperties(
|
||||
randomChoice(exercises, random),
|
||||
time,
|
||||
rawWeight,
|
||||
weightUnit,
|
||||
random.nextInt(13) + 1
|
||||
);
|
||||
|
||||
var submission = new Submission(
|
||||
ulid.nextULID(),
|
||||
randomChoice(gyms, random),
|
||||
randomChoice(exercises, random),
|
||||
randomChoice(users, random),
|
||||
time,
|
||||
randomChoice(new ArrayList<>(uploads.keySet()), random),
|
||||
rawWeight,
|
||||
weightUnit,
|
||||
metricWeight,
|
||||
random.nextInt(13) + 1
|
||||
properties
|
||||
);
|
||||
submission.setVerified(true);
|
||||
submission.setProcessing(false);
|
||||
var uploadData = uploads.get(submission.getVideoProcessingTaskId());
|
||||
submission.setVideoFileId(uploadData.getFirst());
|
||||
submission.setThumbnailFileId(uploadData.getSecond());
|
||||
|
|
Loading…
Reference in New Issue