Skip to content

Commit

Permalink
[CCAP-420] Updating FFL short code configs to be set per flow and not…
Browse files Browse the repository at this point in the history
… per project (#613)

* [CCAP-420] Updating FFL short code configs to be set per flow and not per project

* Cleanup from review

* Cleanup from review
  • Loading branch information
cram-cfa authored Oct 22, 2024
1 parent 910f0e8 commit 871f961
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 86 deletions.
26 changes: 14 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -554,18 +554,20 @@ forced uppercase, character set, and creation point.
```yaml
form-flow:
short-code:
# default = 8
length: 8
# default = alphanumeric | options: alphanumeric (A-z 0-9), alpha (A-z), numeric (0-9)
type: alphanumeric
# default = true | options: true, false
uppercase: false
# default = submission | options: submission, creation
creation-point: submission
# default = null
prefix: IL-
# default = null
suffix: -APP
flowNameHere:
short-code-configs:
# default = 8
length: 8
# default = alphanumeric | options: alphanumeric (A-z 0-9), alpha (A-z), numeric (0-9)
type: alphanumeric
# default = true | options: true, false
uppercase: false
# default = submission | options: submission, creation
creation-point: submission
# default = null
prefix: IL-
# default = null
suffix: -APP
```

On creation of the short code, uniqueness is guaranteed. Because of that, it is incredibly important to
Expand Down
11 changes: 8 additions & 3 deletions src/main/java/formflow/library/ScreenController.java
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,11 @@ private ModelAndView handlePost(
submission.setInputData(formSubmission.getFormData());
}

ShortCodeConfig.Config config = shortCodeConfig.getConfig(flow);
if (config == null) {
log.info("No shortcode configuration found for flow {}, no shortcode will be generated.", flow);
}

// handle marking the record as submitted, if necessary
if (submitSubmission) {
log.info(
Expand All @@ -348,15 +353,15 @@ private ModelAndView handlePost(
);
submission.setSubmittedAt(OffsetDateTime.now());

if (shortCodeConfig.isCreateShortCodeAtSubmission()) {
if (config != null && config.isCreateShortCodeAtSubmission()) {
submissionRepositoryService.generateAndSetUniqueShortCode(submission);
}
}

actionManager.handleBeforeSaveAction(currentScreen, submission);
submission = saveToRepository(submission);

if (shortCodeConfig.isCreateShortCodeAtCreation()) {
if (config != null && config.isCreateShortCodeAtCreation()) {
submissionRepositoryService.generateAndSetUniqueShortCode(submission);
}

Expand Down Expand Up @@ -540,7 +545,7 @@ RedirectView postSubflowScreen(
actionManager.handleBeforeSaveAction(currentScreen, submission, iterationUuid);
submission = saveToRepository(submission, subflowName);

if (shortCodeConfig.isCreateShortCodeAtCreation()) {
if (shortCodeConfig.getConfig(flow) != null && shortCodeConfig.getConfig(flow).isCreateShortCodeAtCreation()) {
submissionRepositoryService.generateAndSetUniqueShortCode(submission);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,44 +1,56 @@
package formflow.library.config.submission;

import java.util.Map;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Getter
@Configuration
@ConfigurationProperties(prefix = "form-flow.short-code")
public class ShortCodeConfig {

public enum ShortCodeType {
alphanumeric, alpha, numeric;
private Map<String, Config> shortCodeConfigs;

public Config getConfig(String flowName) {
return shortCodeConfigs != null ? shortCodeConfigs.get(flowName) : null;
}

public enum ShortCodeCreationPoint {
creation, submission
public void setShortCodeConfigs(Map<String, Config> shortCodeConfigs) {
this.shortCodeConfigs = shortCodeConfigs;
}

@Value("${form-flow.short-code.length:6}")
private int codeLength;
@Setter
@Getter
public static class Config {

@Value("${form-flow.short-code.type:alphanumeric}")
private ShortCodeType codeType;
public enum ShortCodeType {
alphanumeric, alpha, numeric;
}

@Value("${form-flow.short-code.uppercase: true}")
private boolean uppercase;
public enum ShortCodeCreationPoint {
creation, submission
}

@Value("${form-flow.short-code.creation-point:submission}")
private ShortCodeCreationPoint creationPoint;
private int codeLength = 6;

@Value("${form-flow.short-code.prefix:#{null}}")
private String prefix;
private ShortCodeType codeType = ShortCodeType.alphanumeric;

@Value("${form-flow.short-code.suffix:#{null}}")
private String suffix;
private boolean uppercase = true;

public boolean isCreateShortCodeAtCreation() {
return ShortCodeCreationPoint.creation.equals(creationPoint);
}
private ShortCodeCreationPoint creationPoint = ShortCodeCreationPoint.submission;

private String prefix = null;

private String suffix = null;

public boolean isCreateShortCodeAtCreation() {
return ShortCodeCreationPoint.creation.equals(creationPoint);
}

public boolean isCreateShortCodeAtSubmission() {
return ShortCodeCreationPoint.submission.equals(creationPoint);
}

public boolean isCreateShortCodeAtSubmission() {
return ShortCodeCreationPoint.submission.equals(creationPoint);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -117,31 +117,37 @@ public void removeSubflowCSRF(Submission submission, String subflowName) {
public synchronized void generateAndSetUniqueShortCode(Submission submission) {

if (submission.getShortCode() != null) {
log.warn("Unable to create short code for submission {}", submission.getId());
log.warn("Unable to create short code for submission {} because one already exists.", submission.getId());
return;
}

log.info("Attempting to create short code for submission {}", submission.getId());

ShortCodeConfig.Config config = shortCodeConfig.getConfig(submission.getFlow());
if (config == null) {
log.error("Unable to find shortcode configuration for flow {}", submission.getFlow());
return;
}

// If there is no short code for this submission in the database, generate one
int codeLength = shortCodeConfig.getCodeLength();
int codeLength = config.getCodeLength();
do {
String newCode = switch (shortCodeConfig.getCodeType()) {
String newCode = switch (config.getCodeType()) {
case alphanumeric -> RandomStringUtils.randomAlphanumeric(codeLength);
case alpha -> RandomStringUtils.randomAlphabetic(codeLength);
case numeric -> RandomStringUtils.randomNumeric(codeLength);
};

if (shortCodeConfig.isUppercase()) {
if (config.isUppercase()) {
newCode = newCode.toUpperCase();
}

if (shortCodeConfig.getPrefix() != null) {
newCode = shortCodeConfig.getPrefix() + newCode;
if (config.getPrefix() != null) {
newCode = config.getPrefix() + newCode;
}

if (shortCodeConfig.getSuffix() != null) {
newCode = newCode + shortCodeConfig.getSuffix();
if (config.getSuffix() != null) {
newCode = newCode + config.getSuffix();
}

boolean exists = repository.existsByShortCode(newCode);
Expand Down
22 changes: 12 additions & 10 deletions src/test/java/formflow/library/config/ShortCodeConfigAlphaTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
@ActiveProfiles("test")
@SpringBootTest(properties = {
"form-flow.path=flows-config/test-flow.yaml",
"form-flow.short-code.length=5",
"form-flow.short-code.type=alpha",
"form-flow.short-code.suffix=-TEST"
"form-flow.short-code.short-code-configs.testFlow.code-length=5",
"form-flow.short-code.short-code-configs.testFlow.code-type=alpha",
"form-flow.short-code.short-code-configs.testFlow.suffix=-TEST"
})

class ShortCodeConfigAlphaTest {
Expand All @@ -36,19 +36,21 @@ void testShortCodeGeneration_Numeric() {

submissionRepositoryService.generateAndSetUniqueShortCode(submission);

int expectedLength = shortCodeConfig.getCodeLength() +
(shortCodeConfig.getPrefix() != null ? shortCodeConfig.getPrefix().length() : 0) +
(shortCodeConfig.getSuffix() != null ? shortCodeConfig.getSuffix().length() : 0);
ShortCodeConfig.Config config = shortCodeConfig.getConfig(submission.getFlow());

int expectedLength = config.getCodeLength() +
(config.getPrefix() != null ? config.getPrefix().length() : 0) +
(config.getSuffix() != null ? config.getSuffix().length() : 0);

assertThat(submission.getShortCode().length()).isEqualTo(expectedLength);

String coreOfCode = submission.getShortCode();
if (shortCodeConfig.getPrefix() != null) {
coreOfCode = submission.getShortCode().substring(shortCodeConfig.getPrefix().length());
if (config.getPrefix() != null) {
coreOfCode = submission.getShortCode().substring(config.getPrefix().length());
}

if (shortCodeConfig.getSuffix() != null) {
coreOfCode = coreOfCode.substring(0, coreOfCode.length() - shortCodeConfig.getSuffix().length());
if (config.getSuffix() != null) {
coreOfCode = coreOfCode.substring(0, coreOfCode.length() - config.getSuffix().length());
}

assertThat(coreOfCode.matches("[A-Za-z]+")).isEqualTo(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
@ActiveProfiles("test")
@SpringBootTest(properties = {
"form-flow.path=flows-config/test-flow.yaml",
"form-flow.short-code.length=7",
"form-flow.short-code.type=numeric"
"form-flow.short-code.short-code-configs.testFlow.code-length=7",
"form-flow.short-code.short-code-configs.testFlow.code-type=numeric"
})
class ShortCodeConfigNumericTest {

Expand All @@ -34,19 +34,21 @@ void testShortCodeGeneration_Numeric() {

submissionRepositoryService.generateAndSetUniqueShortCode(submission);

int expectedLength = shortCodeConfig.getCodeLength() +
(shortCodeConfig.getPrefix() != null ? shortCodeConfig.getPrefix().length() : 0) +
(shortCodeConfig.getSuffix() != null ? shortCodeConfig.getSuffix().length() : 0);
ShortCodeConfig.Config config = shortCodeConfig.getConfig(submission.getFlow());

int expectedLength = config.getCodeLength() +
(config.getPrefix() != null ? config.getPrefix().length() : 0) +
(config.getSuffix() != null ? config.getSuffix().length() : 0);

assertThat(submission.getShortCode().length()).isEqualTo(expectedLength);

String coreOfCode = submission.getShortCode();
if (shortCodeConfig.getPrefix() != null) {
coreOfCode = submission.getShortCode().substring(shortCodeConfig.getPrefix().length());
if (config.getPrefix() != null) {
coreOfCode = submission.getShortCode().substring(config.getPrefix().length());
}

if (shortCodeConfig.getSuffix() != null) {
coreOfCode = coreOfCode.substring(0, coreOfCode.length() - shortCodeConfig.getSuffix().length());
if (config.getSuffix() != null) {
coreOfCode = coreOfCode.substring(0, coreOfCode.length() - config.getSuffix().length());
}

assertThat(coreOfCode.matches("[0-9]+")).isEqualTo(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
@ActiveProfiles("test")
@SpringBootTest(properties = {
"form-flow.path=flows-config/test-flow.yaml",
"form-flow.short-code.length=5",
"form-flow.short-code.type=alpha",
"form-flow.short-code.uppercase=true"
"form-flow.short-code.short-code-configs.testFlow.code-length=5",
"form-flow.short-code.short-code-configs.testFlow.code-type=alpha",
"form-flow.short-code.short-code-configs.testFlow.uppercase=true"
})
class ShortCodeConfigUpperAlphaTest {

Expand All @@ -35,19 +35,21 @@ void testShortCodeGeneration_Numeric() {

submissionRepositoryService.generateAndSetUniqueShortCode(submission);

int expectedLength = shortCodeConfig.getCodeLength() +
(shortCodeConfig.getPrefix() != null ? shortCodeConfig.getPrefix().length() : 0) +
(shortCodeConfig.getSuffix() != null ? shortCodeConfig.getSuffix().length() : 0);
ShortCodeConfig.Config config = shortCodeConfig.getConfig(submission.getFlow());

int expectedLength = config.getCodeLength() +
(config.getPrefix() != null ? config.getPrefix().length() : 0) +
(config.getSuffix() != null ? config.getSuffix().length() : 0);

assertThat(submission.getShortCode().length()).isEqualTo(expectedLength);

String coreOfCode = submission.getShortCode();
if (shortCodeConfig.getPrefix() != null) {
coreOfCode = submission.getShortCode().substring(shortCodeConfig.getPrefix().length());
if (config.getPrefix() != null) {
coreOfCode = submission.getShortCode().substring(config.getPrefix().length());
}

if (shortCodeConfig.getSuffix() != null) {
coreOfCode = coreOfCode.substring(0, coreOfCode.length() - shortCodeConfig.getSuffix().length());
if (config.getSuffix() != null) {
coreOfCode = coreOfCode.substring(0, coreOfCode.length() - config.getSuffix().length());
}
assertThat(coreOfCode.matches("[A-Z]+")).isEqualTo(true);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,19 +81,21 @@ void testFindByShortCode() {

submissionRepositoryService.generateAndSetUniqueShortCode(submission);

int expectedLength = shortCodeConfig.getCodeLength() +
(shortCodeConfig.getPrefix() != null ? shortCodeConfig.getPrefix().length() : 0) +
(shortCodeConfig.getSuffix() != null ? shortCodeConfig.getSuffix().length() : 0);
ShortCodeConfig.Config config = shortCodeConfig.getConfig(submission.getFlow());

int expectedLength = config.getCodeLength() +
(config.getPrefix() != null ? config.getPrefix().length() : 0) +
(config.getSuffix() != null ? config.getSuffix().length() : 0);

assertThat(submission.getShortCode().length()).isEqualTo(expectedLength);

String coreOfCode = submission.getShortCode();
if (shortCodeConfig.getPrefix() != null) {
coreOfCode = submission.getShortCode().substring(shortCodeConfig.getPrefix().length());
if (config.getPrefix() != null) {
coreOfCode = submission.getShortCode().substring(config.getPrefix().length());
}

if (shortCodeConfig.getSuffix() != null) {
coreOfCode = coreOfCode.substring(0, coreOfCode.length() - shortCodeConfig.getSuffix().length());
if (config.getSuffix() != null) {
coreOfCode = coreOfCode.substring(0, coreOfCode.length() - config.getSuffix().length());
}

assertThat(coreOfCode.matches("[A-Za-z0-9]+")).isEqualTo(true);
Expand Down
10 changes: 6 additions & 4 deletions src/test/resources/application-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@ form-flow:
domain: 'mail.forms-starter.cfa-platforms.org'
sender-email: 'Testing <[email protected]>'
short-code:
length: 8
type: alphanumeric
uppercase: false
prefix: "IL-"
short-code-configs:
testFlow:
length: 8
type: alphanumeric
uppercase: false
prefix: "IL-"
spring:
main:
allow-bean-definition-overriding: true
Expand Down

0 comments on commit 871f961

Please sign in to comment.