Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SNAP transmission changes #565

Merged
merged 6 commits into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions crontab
Original file line number Diff line number Diff line change
@@ -1,7 +1,2 @@
# Run weekly on Wednesday at Noon PDT
# 0 19 * * WED java -Dserver.port=9191 -jar /opt/form-flow-starter-app/app.jar transmit

# Run every 5 minutes
*/5 * * * * java -Dserver.port=9191 -jar /opt/form-flow-starter-app/app.jar transferSubmissions


2 changes: 2 additions & 0 deletions src/main/java/org/ladocuploader/app/LaDocUploader.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication(scanBasePackages = {"org.ladocuploader.app", "formflow.library"})
@EntityScan(basePackages = {"org.ladocuploader.app", "formflow.library"})
@EnableConfigurationProperties
@EnableScheduling
public class LaDocUploader {

public static void main(String[] args) {
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/org/ladocuploader/app/cli/FtpsClientImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ public FtpsClientImpl(@Value("${ftps.username:}") String username, @Value("${ftp
public void uploadFile(String zipFilename, byte[] data) throws IOException {
FTPSClient ftp = new FTPSClient();

ftp.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));

ftp.connect(uploadUrl);

ftp.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));

int reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
Expand Down
21 changes: 20 additions & 1 deletion src/main/java/org/ladocuploader/app/cli/MockFtpsClientImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,33 @@
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

@Slf4j
@Component
@Profile({"dev", "test", "demo"})
public class MockFtpsClientImpl implements FtpsClient {
public static final String MOCK_SERVER_NAME = "mockTransferServer";

@Override
public void uploadFile(String zipFilename, byte[] data) {
// Do nothing
log.info("Mock uploading file " + zipFilename);
try {
File dir = new File(MOCK_SERVER_NAME);
if (!dir.exists() && !dir.mkdir()) {
throw new IllegalStateException("Cannot make directory");
}
File file = new File(MOCK_SERVER_NAME + "/" + zipFilename);
if (!file.exists() && !file.createNewFile()) {
throw new IllegalStateException("Cannot create file");
}
FileOutputStream out = new FileOutputStream(file);
out.write(data);
out.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

@Slf4j
@Component
@Profile({"dev", "test", "demo"})
@Profile({"dev", "test"})
public class MockPGPEncryptorImpl implements PGPEncryptor {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

@Slf4j
@Component
@Profile({"production", "staging"})
@Profile({"production", "staging", "demo"})
public class PGPEncryptorImpl implements PGPEncryptor {

@Value("${pgp.sigkey-password}")
Expand Down
16 changes: 4 additions & 12 deletions src/main/java/org/ladocuploader/app/cli/SubmissionTransfer.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,9 @@
import org.ladocuploader.app.data.enums.TransmissionStatus;
import org.ladocuploader.app.data.enums.TransmissionType;
import org.ladocuploader.app.submission.StringEncryptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.data.domain.Sort;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileOutputStream;
Expand All @@ -32,7 +30,7 @@
import static org.ladocuploader.app.file.DocTypeEnum.*;

@Slf4j
@ShellComponent
@Service
public class SubmissionTransfer {
private static final Map<String, String> DOCTYPE_FORMAT_MAP = new HashMap<>();

Expand Down Expand Up @@ -66,9 +64,6 @@ public class SubmissionTransfer {
private final StringEncryptor encryptor;
private final FtpsClient ftpsClient;

@Autowired
private ConfigurableApplicationContext context;

public SubmissionTransfer(TransmissionRepository transmissionRepository, UserFileRepositoryService fileRepositoryService, CloudFileRepository fileRepository, PdfService pdfService, PGPEncryptor pgpEncryptor, StringEncryptor encryptor, FtpsClient ftpsClient) {
this.transmissionRepository = transmissionRepository;
this.fileRepositoryService = fileRepositoryService;
Expand All @@ -79,15 +74,14 @@ public SubmissionTransfer(TransmissionRepository transmissionRepository, UserFil
this.ftpsClient = ftpsClient;
}

@ShellMethod(key = "transferSubmissions")
@Scheduled(fixedRateString ="${transmissions.snap-transmission-rate}")
public void transferSubmissions() {
// Give a 2-hour wait for folks to upload documents
OffsetDateTime submittedAtCutoff = OffsetDateTime.now().minusHours(TWO_HOURS);
List<Submission> queuedSubmissions = transmissionRepository.submissionsToTransmit(Sort.unsorted(), TransmissionType.SNAP);
int totalQueued = queuedSubmissions.size();
if (queuedSubmissions.isEmpty()) {
log.info("Nothing to transmit. Exiting.");
context.close();
return;
}
log.info("Found %s queued transmissions".formatted(totalQueued));
Expand All @@ -97,7 +91,6 @@ public void transferSubmissions() {
log.info("Excluding %s submitted within last 2 hours".formatted(totalQueued - queuedSubmissions.size()));
if (queuedSubmissions.isEmpty()) {
log.info("No submissions older than 2 hour to transmit. Exiting.");
context.close();
return;
}
log.info("Found %s transmissions to transmit".formatted(queuedSubmissions.size()));
Expand All @@ -109,7 +102,6 @@ public void transferSubmissions() {
transferSubmissionBatch(submissionBatch);
}
log.info("Done transmitting batches. Transmitted %s of %s batches. Exiting.".formatted(transmittedCount, submissionBatches.size()));
context.close();
}

private void transferSubmissionBatch(List<Submission> submissionsBatch) {
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ server:
servlet:
session:
persistent: true
transmissions:
snap-transmission-rate: ${SNAP_TRANSMISSION_RATE:PT5M}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not familiar with this syntax but It looks like this is setting the snap-transmission-rate to 5 minutes.

Is that right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup! "PT5M" is the default duration and it's in the "Duration" notation

ftps:
username: ${FTPS_USERNAME:-""}
password: ${FTPS_PASSWORD:-""}
Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/logback-spring.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
</layout>
</appender>

<springProfile name="dev | test">
<springProfile name="dev | test | demo">
<root level="INFO">
<appender-ref ref="LocalConsole"/>
</root>
</springProfile>

<springProfile name="staging | demo | production">
<springProfile name="staging | production">
<root level="INFO | WARN | ERROR">
<appender-ref ref="JsonConsole"/>
</root>
Expand Down
43 changes: 14 additions & 29 deletions src/test/java/org/ladocuploader/app/cli/SubmissionTransferTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import formflow.library.file.CloudFileRepository;
import formflow.library.pdf.PdfService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.ladocuploader.app.data.Transmission;
import org.ladocuploader.app.data.TransmissionRepository;
Expand All @@ -21,7 +20,6 @@

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.time.OffsetDateTime;
import java.util.*;
Expand All @@ -33,13 +31,12 @@
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItem;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.*;
import static org.ladocuploader.app.cli.MockFtpsClientImpl.MOCK_SERVER_NAME;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.when;

@ActiveProfiles("test")
@SpringBootTest
@Disabled
class SubmissionTransferTest {

@Autowired
Expand All @@ -54,32 +51,22 @@ class SubmissionTransferTest {
@Autowired
UserFileRepository userFileRepository;

@Autowired
FtpsClient ftpsClient;

@MockBean
PdfService pdfService;

@MockBean
CloudFileRepository fileRepository;

@MockBean
FtpsClient ftpsClient;

private Submission submissionWithDocs;
private Submission submissionWithoutDocs;
private Submission invalidSubmission;
private Submission submittedBeforeDelayCutoff;

@BeforeEach
void setup() throws IOException {
doAnswer(args -> {
String zipfilename = (String) args.getArguments()[0];
String transmitlocation = "mocktransmit_" + args.getArguments()[0];
try (FileInputStream instream = new FileInputStream(zipfilename);
FileOutputStream outstream = new FileOutputStream(transmitlocation)) {
outstream.write(instream.readAllBytes());
}
return null;
}).when(ftpsClient).uploadFile(anyString(), any());

submissionWithoutDocs = queueSubmissionWithoutDocs();
submissionWithDocs = queueSubmissionWithDocs();
invalidSubmission = queueInvalidSubmission();
Expand All @@ -94,11 +81,9 @@ void setup() throws IOException {
public void transmitZipFile() throws IOException {
submissionTransfer.transferSubmissions();

File zipFile = new File("mocktransmit_00050000000.zip");
File zipFile = new File(MOCK_SERVER_NAME + "/00050000000.zip.gpg");
assertTrue(zipFile.exists());

verify(ftpsClient).uploadFile(any(), any());

Transmission transmittedWithDocs = transmissionRepository.findBySubmissionAndTransmissionType(submissionWithDocs, TransmissionType.SNAP);
assertThat(transmittedWithDocs.getStatus(), equalTo(TransmissionStatus.Complete));
assertNull(transmittedWithDocs.getDocumentationErrors());
Expand All @@ -118,13 +103,13 @@ public void transmitZipFile() throws IOException {
String destDir = "output";
List<String> fileNames = unzip(zipFile.getPath(), destDir);

assertThat(fileNames, hasItem("output/1/"));
assertThat(fileNames, hasItem("output/1/SNAP_application.pdf"));
assertThat(fileNames, hasItem("output/2/"));
assertThat(fileNames, hasItem("output/2/SNAP_application.pdf"));
assertThat(fileNames, hasItem("output/2/originalFilename.png"));
assertThat(fileNames, hasItem("output/2/2_originalFilename.png"));
assertThat(fileNames, hasItem("output/2/weird/:\\filename.jpg"));
assertThat(fileNames, hasItem("output/00050000000/1/"));
assertThat(fileNames, hasItem("output/00050000000/1/SNAP_application.pdf"));
assertThat(fileNames, hasItem("output/00050000000/2/"));
assertThat(fileNames, hasItem("output/00050000000/2/SNAP_application.pdf"));
assertThat(fileNames, hasItem("output/00050000000/2/originalFilename.png"));
assertThat(fileNames, hasItem("output/00050000000/2/2_originalFilename.png"));
assertThat(fileNames, hasItem("output/00050000000/2/weird/:\\filename.jpg"));
assertThat(fileNames, hasItem("output/00050000000.txt"));
assertEquals(8, fileNames.size());

Expand Down
Loading