diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/generator/IdGeneratorBase.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/generator/IdGeneratorBase.java index a91d91ca..050866d4 100644 --- a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/generator/IdGeneratorBase.java +++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/generator/IdGeneratorBase.java @@ -38,6 +38,7 @@ public class IdGeneratorBase { private final List globalConstraints = new ArrayList<>(); private final Map registeredDomains = new ConcurrentHashMap<>(Map.of(Domain.DEFAULT_DOMAIN_NAME, Domain.DEFAULT)); private final FailsafeExecutor retryer; + private final String ID_REGEX = "^[a-zA-Z]+$"; protected final IdFormatter idFormatter; protected final NonceGenerator nonceGenerator; @@ -84,6 +85,7 @@ public final synchronized void registerDomainSpecificConstraints( } public final Id getIdFromIdInfo(final NonceInfo nonceInfo, final String namespace, final IdFormatter idFormatter) { + validateIdRegex(namespace); val dateTime = new DateTime(nonceInfo.getTime()); val id = String.format("%s%s", namespace, idFormatter.format(dateTime, getNodeId(), nonceInfo.getExponent())); return Id.builder() @@ -192,4 +194,13 @@ public final void setNodeId(int nodeId) { } this.nodeId = nodeId; } + + private void validateIdRegex(final String namespace) { + Preconditions.checkArgument( + namespace != null && !namespace.isEmpty(), + "Namespace cannot be null or empty"); + Preconditions.checkArgument( + namespace.matches(ID_REGEX), + "Prefix does not match the required regex: " + ID_REGEX); + } } diff --git a/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/IdGeneratorTest.java b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/IdGeneratorTest.java index 98020083..298a21de 100644 --- a/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/IdGeneratorTest.java +++ b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/IdGeneratorTest.java @@ -242,6 +242,39 @@ void testParseSuccessAfterGeneration() { Assertions.assertEquals(parsedId.getGeneratedDate(), generatedId.getGeneratedDate()); } + @Test + void testGenerateWithNumericalPrefix() { + val prefix = "10"; + val exception = Assertions.assertThrows(IllegalArgumentException.class, () -> IdGenerator.generate(prefix)); + Assertions.assertEquals("Prefix does not match the required regex: ^[a-zA-Z]+$", exception.getMessage()); + } + + @Test + void testGenerateWithEmptyPrefix() { + val prefix = ""; + val exception = Assertions.assertThrows(IllegalArgumentException.class, () -> IdGenerator.generate(prefix)); + Assertions.assertEquals("Namespace cannot be null or empty", exception.getMessage()); + } + + @Test + void testGenerateWithConstraintsWithNumericalPrefix() { + val prefix = "10"; + val domain = "TEST"; + IdGenerator.registerDomainSpecificConstraints(domain, Collections.singletonList(id -> true)); + val exception = Assertions.assertThrows(IllegalArgumentException.class, + () -> IdGenerator.generateWithConstraints(prefix, domain)); + Assertions.assertEquals("Prefix does not match the required regex: ^[a-zA-Z]+$", exception.getMessage()); + } + + @Test + void testGenerateWithConstraintsWithEmptyPrefix() { + val prefix = ""; + val domain = "TEST"; + IdGenerator.registerDomainSpecificConstraints(domain, Collections.singletonList(id -> true)); + val exception = Assertions.assertThrows(IllegalArgumentException.class, + () -> IdGenerator.generateWithConstraints(prefix, domain)); + Assertions.assertEquals("Namespace cannot be null or empty", exception.getMessage()); + } @SuppressWarnings("SameParameterValue") private Date generateDate(int year, int month, int day, int hour, int min, int sec, int ms, ZoneId zoneId) {