From baff7e1c5f7ccb2bb11e43a62eef55e3ca3a1406 Mon Sep 17 00:00:00 2001 From: Satyam Saxena Date: Thu, 2 Jan 2025 16:58:17 +0530 Subject: [PATCH 1/9] Add formatterRegistry --- .../id/formatter/Base36IdFormatter.java | 5 ++++ .../id/formatter/DefaultIdFormatter.java | 5 ++++ .../bundle/id/formatter/IdFormatter.java | 2 ++ .../bundle/id/formatter/IdFormatters.java | 19 +++++++++++-- .../discovery/bundle/id/IdFormattersTest.java | 28 +++++++++++++++++++ 5 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/IdFormattersTest.java diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/Base36IdFormatter.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/Base36IdFormatter.java index 15db24bb..f91bc447 100644 --- a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/Base36IdFormatter.java +++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/Base36IdFormatter.java @@ -29,6 +29,11 @@ public Base36IdFormatter(IdFormatter idFormatter) { this.idFormatter = idFormatter; } + @Override + public int getType() { + return 1; + } + @Override public String format(final DateTime dateTime, final int nodeId, diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/DefaultIdFormatter.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/DefaultIdFormatter.java index cac2bbcb..e757b688 100644 --- a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/DefaultIdFormatter.java +++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/DefaultIdFormatter.java @@ -28,6 +28,11 @@ public class DefaultIdFormatter implements IdFormatter { private static final Pattern PATTERN = Pattern.compile("(.*)([0-9]{15})([0-9]{4})([0-9]{3})"); private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyMMddHHmmssSSS"); + @Override + public int getType() { + return 0; + } + @Override public String format(final DateTime dateTime, final int nodeId, diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdFormatter.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdFormatter.java index 9cd3219e..8ff98130 100644 --- a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdFormatter.java +++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdFormatter.java @@ -22,6 +22,8 @@ public interface IdFormatter { + int getType(); + String format(final DateTime dateTime, final int nodeId, final int randomNonce); diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdFormatters.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdFormatters.java index 6d344f53..3dde78d3 100644 --- a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdFormatters.java +++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdFormatters.java @@ -20,6 +20,7 @@ import lombok.extern.slf4j.Slf4j; import lombok.val; +import java.util.Map; import java.util.Optional; import java.util.regex.Pattern; @@ -27,11 +28,15 @@ @UtilityClass public class IdFormatters { private static final int MINIMUM_ID_LENGTH = 22; - private static final Pattern PATTERN = Pattern.compile("(.*)([0-9]{22})"); + private static final Pattern PATTERN = Pattern.compile("([A-Za-z]*)([0-9]{22})([0-9]{2})?(.*)"); private static final IdFormatter originalIdFormatter = new DefaultIdFormatter(); private static final IdFormatter base36IdFormatter = new Base36IdFormatter(originalIdFormatter); + private final Map formatterRegistry = Map.of( + originalIdFormatter.getType(), originalIdFormatter + ); + public static IdFormatter original() { return originalIdFormatter; } @@ -55,7 +60,17 @@ public Optional parse(final String idString) { if (!matcher.find()) { return Optional.empty(); } - return originalIdFormatter.parse(idString); + + val formatterType = matcher.group(3); + + if (formatterType == null) + return originalIdFormatter.parse(idString); + + val formatter = formatterRegistry.get(Integer.parseInt(matcher.group(3))); + if (formatter == null) + return Optional.empty(); + + return formatter.parse(idString); } catch (Exception e) { log.warn("Could not parse idString {}", e.getMessage()); return Optional.empty(); diff --git a/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/IdFormattersTest.java b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/IdFormattersTest.java new file mode 100644 index 00000000..0a26b19b --- /dev/null +++ b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/IdFormattersTest.java @@ -0,0 +1,28 @@ +package io.appform.ranger.discovery.bundle.id; + +import io.appform.ranger.discovery.bundle.id.formatter.IdFormatters; +import lombok.val; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class IdFormattersTest { + + @Test + void testDefaultId() throws ParseException { + val id = "T2407101232336168748798"; + val parsedId = IdFormatters.parse(id).orElse(null); + Assertions.assertNotNull(parsedId); + Assertions.assertEquals(id, parsedId.getId()); + Assertions.assertEquals(798, parsedId.getExponent()); + Assertions.assertEquals(8748, parsedId.getNode()); + assertDate("240710123233616", parsedId.getGeneratedDate()); + } + + private void assertDate(final String dateString, final Date date) throws ParseException { + Assertions.assertEquals(new SimpleDateFormat("yyMMddHHmmssSSS").parse(dateString), date); + } +} From 6f3679f13aaa30437937af4fe63017feae1aa9fb Mon Sep 17 00:00:00 2001 From: Satyam Saxena Date: Mon, 3 Feb 2025 14:27:36 +0530 Subject: [PATCH 2/9] Add braces --- .../ranger/discovery/bundle/id/formatter/IdFormatters.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdFormatters.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdFormatters.java index 3dde78d3..6424f9ae 100644 --- a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdFormatters.java +++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdFormatters.java @@ -63,12 +63,14 @@ public Optional parse(final String idString) { val formatterType = matcher.group(3); - if (formatterType == null) + if (formatterType == null) { return originalIdFormatter.parse(idString); + } val formatter = formatterRegistry.get(Integer.parseInt(matcher.group(3))); - if (formatter == null) + if (formatter == null) { return Optional.empty(); + } return formatter.parse(idString); } catch (Exception e) { From 136501baa30d7e7505049eb21f9ec30b4aefadea Mon Sep 17 00:00:00 2001 From: Satyam Saxena Date: Mon, 3 Feb 2025 16:38:37 +0530 Subject: [PATCH 3/9] Add support for suffix --- .../ranger/discovery/bundle/id/Id.java | 2 ++ .../discovery/bundle/id/IdGenerator.java | 25 +++++++++++++++++++ .../id/formatter/DefaultIdFormatter.java | 4 ++- .../bundle/id/generator/IdGeneratorBase.java | 22 +++++++++++++++- .../bundle/id/request/IdGenerationInput.java | 1 + .../id/request/IdGenerationRequest.java | 1 + .../discovery/bundle/id/IdGeneratorTest.java | 21 ++++++++++++++-- 7 files changed, 72 insertions(+), 4 deletions(-) diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/Id.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/Id.java index c270770f..e57a0e11 100644 --- a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/Id.java +++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/Id.java @@ -31,6 +31,8 @@ @ToString public class Id { private String id; + private String prefix; + private String suffix; private Date generatedDate; private int node; private int exponent; diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/IdGenerator.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/IdGenerator.java index c021ff9b..d16fa3e3 100644 --- a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/IdGenerator.java +++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/IdGenerator.java @@ -89,6 +89,10 @@ public static Id generate(String prefix) { return baseGenerator.generate(prefix); } + public static Id generate(String prefix, String suffix) { + return baseGenerator.generate(prefix, suffix); + } + public static Id generate(final String prefix, final IdFormatter idFormatter) { return baseGenerator.generate(prefix, idFormatter); @@ -136,6 +140,13 @@ public static Optional generateWithConstraints( return generateWithConstraints(prefix, inConstraints, false); } + public static Optional generateWithConstraints( + String prefix, + String suffix, + final List inConstraints) { + return generateWithConstraints(prefix, suffix, inConstraints, false); + } + /** * Generate id by parsing given string * @@ -168,6 +179,20 @@ public static Optional generateWithConstraints( .build()); } + public static Optional generateWithConstraints( + String prefix, + String suffix, + final List inConstraints, + boolean skipGlobal) { + return generate(IdGenerationRequest.builder() + .prefix(prefix) + .suffix(suffix) + .constraints(inConstraints) + .skipGlobal(skipGlobal) + .idFormatter(IdFormatters.original()) + .build()); + } + /** * Generate id that matches all passed constraints. * NOTE: There are performance implications for this. diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/DefaultIdFormatter.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/DefaultIdFormatter.java index e757b688..74697e43 100644 --- a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/DefaultIdFormatter.java +++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/DefaultIdFormatter.java @@ -25,7 +25,7 @@ import java.util.regex.Pattern; public class DefaultIdFormatter implements IdFormatter { - private static final Pattern PATTERN = Pattern.compile("(.*)([0-9]{15})([0-9]{4})([0-9]{3})"); + private static final Pattern PATTERN = Pattern.compile("([A-Za-z]*)([0-9]{15})([0-9]{4})([0-9]{3})([0-9]*)"); private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyMMddHHmmssSSS"); @Override @@ -48,6 +48,8 @@ public Optional parse(final String idString) { } return Optional.of(Id.builder() .id(idString) + .prefix(matcher.group(1)) + .suffix(matcher.group(5)) .node(Integer.parseInt(matcher.group(3))) .exponent(Integer.parseInt(matcher.group(4))) .generatedDate(DATE_TIME_FORMATTER.parseDateTime(matcher.group(2)).toDate()) 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 d8807e2e..9b729d13 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 @@ -98,10 +98,25 @@ public final Id getIdFromIdInfo(final NonceInfo nonceInfo, final String namespac .build(); } + public final Id getIdFromIdInfo(final NonceInfo nonceInfo, final String namespace, final String suffix, final IdFormatter idFormatter) { + val dateTime = new DateTime(nonceInfo.getTime()); + val id = String.format("%s%s%s", namespace, idFormatter.format(dateTime, getNodeId(), nonceInfo.getExponent()), suffix != null ? suffix : ""); + return Id.builder() + .id(id) + .exponent(nonceInfo.getExponent()) + .generatedDate(dateTime.toDate()) + .node(getNodeId()) + .build(); + } + public final Id getIdFromIdInfo(final NonceInfo nonceInfo, final String namespace) { return getIdFromIdInfo(nonceInfo, namespace, idFormatter); } + public final Id getIdFromIdInfo(final NonceInfo nonceInfo, final String namespace, final String suffix) { + return getIdFromIdInfo(nonceInfo, namespace, suffix, idFormatter); + } + public final IdValidationState validateId(final List inConstraints, final Id id, final boolean skipGlobal) { // First evaluate global constraints val failedGlobalConstraint @@ -143,6 +158,10 @@ public final Id generate(final String namespace) { return getIdFromIdInfo(idInfo, namespace); } + public final Id generate(final String namespace, final String suffix) { + val idInfo = nonceGenerator.generate(namespace); + return getIdFromIdInfo(idInfo, namespace, suffix); + } public final Id generate(final String namespace, final IdFormatter idFormatter) { val idInfo = nonceGenerator.generate(namespace); @@ -175,12 +194,13 @@ public final Optional generateWithConstraints(final IdGenerationRequest requ val domain = request.getDomain() != null ? registeredDomains.getOrDefault(request.getDomain(), Domain.DEFAULT) : Domain.DEFAULT; val idGenerationInput = IdGenerationInput.builder() .prefix(request.getPrefix()) + .suffix(request.getSuffix()) .domain(domain) .build(); return Optional.ofNullable(retryer.get( () -> { val idInfoOptional = nonceGenerator.generateWithConstraints(idGenerationInput); - val id = getIdFromIdInfo(idInfoOptional, request.getPrefix(), request.getIdFormatter()); + val id = getIdFromIdInfo(idInfoOptional, request.getPrefix(), request.getSuffix(), request.getIdFormatter()); return new GenerationResult( idInfoOptional, validateId(request.getConstraints(), id, request.isSkipGlobal()), diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/request/IdGenerationInput.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/request/IdGenerationInput.java index 4a251748..55436cce 100644 --- a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/request/IdGenerationInput.java +++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/request/IdGenerationInput.java @@ -8,6 +8,7 @@ @Builder public class IdGenerationInput { String prefix; + String suffix; Domain domain; } diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/request/IdGenerationRequest.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/request/IdGenerationRequest.java index a4affc21..8ad36159 100644 --- a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/request/IdGenerationRequest.java +++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/request/IdGenerationRequest.java @@ -27,6 +27,7 @@ public class IdGenerationRequest { String prefix; + String suffix; String domain; boolean skipGlobal; List constraints; 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 b7c70371..f4ea31bf 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 @@ -181,7 +181,7 @@ void testConstraintFailure() { @Test void testNodeId() { - val generatedId = IdGenerator.generate("TEST123"); + val generatedId = IdGenerator.generate("TEST"); val parsedId = IdGenerator.parse(generatedId.getId()).orElse(null); Assertions.assertNotNull(parsedId); Assertions.assertEquals(parsedId.getNode(), nodeId); @@ -226,9 +226,26 @@ void testParseSuccess() { @Test void testParseSuccessAfterGeneration() { - val generatedId = IdGenerator.generate("TEST123"); + val prefix = "TEST"; + val generatedId = IdGenerator.generate(prefix); val parsedId = IdGenerator.parse(generatedId.getId()).orElse(null); Assertions.assertNotNull(parsedId); + Assertions.assertEquals(prefix, parsedId.getPrefix()); + Assertions.assertEquals(parsedId.getId(), generatedId.getId()); + Assertions.assertEquals(parsedId.getExponent(), generatedId.getExponent()); + Assertions.assertEquals(parsedId.getNode(), generatedId.getNode()); + Assertions.assertEquals(parsedId.getGeneratedDate(), generatedId.getGeneratedDate()); + } + + @Test + void testParseSuccessAfterGenerationWithSuffix() { + val prefix = "TEST"; + val suffix = "007"; + val generatedId = IdGenerator.generate(prefix, suffix); + val parsedId = IdGenerator.parse(generatedId.getId()).orElse(null); + Assertions.assertNotNull(parsedId); + Assertions.assertEquals(prefix, parsedId.getPrefix()); + Assertions.assertEquals(suffix, parsedId.getSuffix()); Assertions.assertEquals(parsedId.getId(), generatedId.getId()); Assertions.assertEquals(parsedId.getExponent(), generatedId.getExponent()); Assertions.assertEquals(parsedId.getNode(), generatedId.getNode()); From 1d8aab81a8258cc1112ad8d34b036bfc4a272f45 Mon Sep 17 00:00:00 2001 From: Satyam Saxena Date: Tue, 4 Feb 2025 22:49:34 +0530 Subject: [PATCH 4/9] Add SuffixIdFormatter --- .../discovery/bundle/id/IdGenerator.java | 25 -------- .../id/formatter/DefaultIdFormatter.java | 4 +- .../bundle/id/formatter/IdFormatters.java | 8 ++- .../id/formatter/SuffixIdFormatter.java | 59 +++++++++++++++++++ .../id/generator/DefaultIdGenerator.java | 6 ++ .../bundle/id/generator/IdGeneratorBase.java | 12 ++++ .../discovery/bundle/id/IdFormattersTest.java | 17 ++++++ .../discovery/bundle/id/IdGeneratorTest.java | 16 ----- 8 files changed, 102 insertions(+), 45 deletions(-) create mode 100644 ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/SuffixIdFormatter.java diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/IdGenerator.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/IdGenerator.java index d16fa3e3..c021ff9b 100644 --- a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/IdGenerator.java +++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/IdGenerator.java @@ -89,10 +89,6 @@ public static Id generate(String prefix) { return baseGenerator.generate(prefix); } - public static Id generate(String prefix, String suffix) { - return baseGenerator.generate(prefix, suffix); - } - public static Id generate(final String prefix, final IdFormatter idFormatter) { return baseGenerator.generate(prefix, idFormatter); @@ -140,13 +136,6 @@ public static Optional generateWithConstraints( return generateWithConstraints(prefix, inConstraints, false); } - public static Optional generateWithConstraints( - String prefix, - String suffix, - final List inConstraints) { - return generateWithConstraints(prefix, suffix, inConstraints, false); - } - /** * Generate id by parsing given string * @@ -179,20 +168,6 @@ public static Optional generateWithConstraints( .build()); } - public static Optional generateWithConstraints( - String prefix, - String suffix, - final List inConstraints, - boolean skipGlobal) { - return generate(IdGenerationRequest.builder() - .prefix(prefix) - .suffix(suffix) - .constraints(inConstraints) - .skipGlobal(skipGlobal) - .idFormatter(IdFormatters.original()) - .build()); - } - /** * Generate id that matches all passed constraints. * NOTE: There are performance implications for this. diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/DefaultIdFormatter.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/DefaultIdFormatter.java index 74697e43..e757b688 100644 --- a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/DefaultIdFormatter.java +++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/DefaultIdFormatter.java @@ -25,7 +25,7 @@ import java.util.regex.Pattern; public class DefaultIdFormatter implements IdFormatter { - private static final Pattern PATTERN = Pattern.compile("([A-Za-z]*)([0-9]{15})([0-9]{4})([0-9]{3})([0-9]*)"); + private static final Pattern PATTERN = Pattern.compile("(.*)([0-9]{15})([0-9]{4})([0-9]{3})"); private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyMMddHHmmssSSS"); @Override @@ -48,8 +48,6 @@ public Optional parse(final String idString) { } return Optional.of(Id.builder() .id(idString) - .prefix(matcher.group(1)) - .suffix(matcher.group(5)) .node(Integer.parseInt(matcher.group(3))) .exponent(Integer.parseInt(matcher.group(4))) .generatedDate(DATE_TIME_FORMATTER.parseDateTime(matcher.group(2)).toDate()) diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdFormatters.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdFormatters.java index 6424f9ae..5651b596 100644 --- a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdFormatters.java +++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdFormatters.java @@ -31,16 +31,22 @@ public class IdFormatters { private static final Pattern PATTERN = Pattern.compile("([A-Za-z]*)([0-9]{22})([0-9]{2})?(.*)"); private static final IdFormatter originalIdFormatter = new DefaultIdFormatter(); + private static final IdFormatter suffixIdFormatter = new SuffixIdFormatter(); private static final IdFormatter base36IdFormatter = new Base36IdFormatter(originalIdFormatter); private final Map formatterRegistry = Map.of( - originalIdFormatter.getType(), originalIdFormatter + originalIdFormatter.getType(), originalIdFormatter, + suffixIdFormatter.getType(), suffixIdFormatter ); public static IdFormatter original() { return originalIdFormatter; } + public static IdFormatter suffix() { + return suffixIdFormatter; + } + public static IdFormatter base36() { return base36IdFormatter; } diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/SuffixIdFormatter.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/SuffixIdFormatter.java new file mode 100644 index 00000000..50803131 --- /dev/null +++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/SuffixIdFormatter.java @@ -0,0 +1,59 @@ +/* + * Copyright 2024 Authors, Flipkart Internet Pvt. Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.appform.ranger.discovery.bundle.id.formatter; + +import io.appform.ranger.discovery.bundle.id.Id; +import lombok.val; +import org.joda.time.DateTime; +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; + +import java.util.Optional; +import java.util.regex.Pattern; + +public class SuffixIdFormatter implements IdFormatter { + private static final int TYPE = 10; + private static final Pattern PATTERN = Pattern.compile("([A-Za-z]*)([0-9]{15})([0-9]{4})([0-9]{3})([0-9]{2})([0-9]*)"); + private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyMMddHHmmssSSS"); + + @Override + public int getType() { + return TYPE; + } + + @Override + public String format(final DateTime dateTime, + final int nodeId, + final int randomNonce) { + return String.format("%s%04d%03d%02d", DATE_TIME_FORMATTER.print(dateTime), nodeId, randomNonce, TYPE); + } + + @Override + public Optional parse(final String idString) { + val matcher = PATTERN.matcher(idString); + if (!matcher.find()) { + return Optional.empty(); + } + return Optional.of(Id.builder() + .id(idString) + .prefix(matcher.group(1)) + .suffix(matcher.group(6)) + .node(Integer.parseInt(matcher.group(3))) + .exponent(Integer.parseInt(matcher.group(4))) + .generatedDate(DATE_TIME_FORMATTER.parseDateTime(matcher.group(2)).toDate()) + .build()); + } +} diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/generator/DefaultIdGenerator.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/generator/DefaultIdGenerator.java index c66b5929..7f55f7f1 100644 --- a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/generator/DefaultIdGenerator.java +++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/generator/DefaultIdGenerator.java @@ -1,6 +1,8 @@ package io.appform.ranger.discovery.bundle.id.generator; +import io.appform.ranger.discovery.bundle.id.formatter.IdFormatter; import io.appform.ranger.discovery.bundle.id.formatter.IdFormatters; +import io.appform.ranger.discovery.bundle.id.nonce.NonceGenerator; import io.appform.ranger.discovery.bundle.id.nonce.RandomNonceGenerator; public class DefaultIdGenerator extends IdGeneratorBase { @@ -8,4 +10,8 @@ public class DefaultIdGenerator extends IdGeneratorBase { public DefaultIdGenerator() { super(IdFormatters.original(), new RandomNonceGenerator()); } + + public DefaultIdGenerator(final IdFormatter idFormatter) { + super(idFormatter, new RandomNonceGenerator()); + } } 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 9b729d13..73a34db7 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 @@ -190,6 +190,18 @@ public final Optional generateWithConstraints(final String namespace, final return generateWithConstraints(request); } + public Optional generateWithConstraints( + String namespace, + String suffix, + final List inConstraints) { + return generateWithConstraints(IdGenerationRequest.builder() + .prefix(namespace) + .constraints(inConstraints) + .skipGlobal(false) + .idFormatter(idFormatter) + .build()); + } + public final Optional generateWithConstraints(final IdGenerationRequest request) { val domain = request.getDomain() != null ? registeredDomains.getOrDefault(request.getDomain(), Domain.DEFAULT) : Domain.DEFAULT; val idGenerationInput = IdGenerationInput.builder() diff --git a/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/IdFormattersTest.java b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/IdFormattersTest.java index 0a26b19b..a0f9c91f 100644 --- a/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/IdFormattersTest.java +++ b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/IdFormattersTest.java @@ -1,6 +1,7 @@ package io.appform.ranger.discovery.bundle.id; import io.appform.ranger.discovery.bundle.id.formatter.IdFormatters; +import io.appform.ranger.discovery.bundle.id.generator.DefaultIdGenerator; import lombok.val; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -25,4 +26,20 @@ void testDefaultId() throws ParseException { private void assertDate(final String dateString, final Date date) throws ParseException { Assertions.assertEquals(new SimpleDateFormat("yyMMddHHmmssSSS").parse(dateString), date); } + + @Test + void testParseSuccessAfterGenerationWithSuffix() { + val idGenerator = new DefaultIdGenerator(IdFormatters.suffix()); + val prefix = "TEST"; + val suffix = "007"; + val generatedId = idGenerator.generate(prefix, suffix); + val parsedId = IdGenerator.parse(generatedId.getId()).orElse(null); + Assertions.assertNotNull(parsedId); + Assertions.assertEquals(prefix, parsedId.getPrefix()); + Assertions.assertEquals(suffix, parsedId.getSuffix()); + Assertions.assertEquals(parsedId.getId(), generatedId.getId()); + Assertions.assertEquals(parsedId.getExponent(), generatedId.getExponent()); + Assertions.assertEquals(parsedId.getNode(), generatedId.getNode()); + Assertions.assertEquals(parsedId.getGeneratedDate(), generatedId.getGeneratedDate()); + } } 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 f4ea31bf..d70e7c8a 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 @@ -237,22 +237,6 @@ void testParseSuccessAfterGeneration() { Assertions.assertEquals(parsedId.getGeneratedDate(), generatedId.getGeneratedDate()); } - @Test - void testParseSuccessAfterGenerationWithSuffix() { - val prefix = "TEST"; - val suffix = "007"; - val generatedId = IdGenerator.generate(prefix, suffix); - val parsedId = IdGenerator.parse(generatedId.getId()).orElse(null); - Assertions.assertNotNull(parsedId); - Assertions.assertEquals(prefix, parsedId.getPrefix()); - Assertions.assertEquals(suffix, parsedId.getSuffix()); - Assertions.assertEquals(parsedId.getId(), generatedId.getId()); - Assertions.assertEquals(parsedId.getExponent(), generatedId.getExponent()); - Assertions.assertEquals(parsedId.getNode(), generatedId.getNode()); - Assertions.assertEquals(parsedId.getGeneratedDate(), generatedId.getGeneratedDate()); - } - - @SuppressWarnings("SameParameterValue") private Date generateDate(int year, int month, int day, int hour, int min, int sec, int ms, ZoneId zoneId) { return Date.from( From 376ee852f4476522fdcee0df2178708e7bad1b00 Mon Sep 17 00:00:00 2001 From: Satyam Saxena Date: Wed, 19 Feb 2025 21:16:38 +0530 Subject: [PATCH 5/9] Update IdParsersTest --- .../discovery/bundle/id/formatter/IdParsers.java | 15 +++++++-------- .../{IdFormattersTest.java => IdParsersTest.java} | 6 +++--- 2 files changed, 10 insertions(+), 11 deletions(-) rename ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/{IdFormattersTest.java => IdParsersTest.java} (83%) diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdParsers.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdParsers.java index 39b431cb..88ffa260 100644 --- a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdParsers.java +++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdParsers.java @@ -31,7 +31,7 @@ public class IdParsers { private static final int MINIMUM_ID_LENGTH = 22; private static final Pattern PATTERN = Pattern.compile("([A-Za-z]*)([0-9]{22})([0-9]{2})?(.*)"); - private final Map formatterRegistry = Map.of( + private final Map parserRegistry = Map.of( IdFormatters.original().getType(), IdFormatters.original() ); @@ -51,18 +51,17 @@ public Optional parse(final String idString) { return Optional.empty(); } - val formatterType = matcher.group(3); - - if (formatterType == null) { + val parserType = matcher.group(3); + if (parserType == null) { return IdFormatters.original().parse(idString); } - val formatter = formatterRegistry.get(Integer.parseInt(matcher.group(3))); - if (formatter == null) { + val parser = parserRegistry.get(Integer.parseInt(matcher.group(3))); + if (parser == null) { + log.warn("Could not parse idString {}, Invalid formatter type {}", idString, parserType); return Optional.empty(); } - - return formatter.parse(idString); + return parser.parse(idString); } catch (Exception e) { log.warn("Could not parse idString {}", e.getMessage()); return Optional.empty(); diff --git a/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/IdFormattersTest.java b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/IdParsersTest.java similarity index 83% rename from ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/IdFormattersTest.java rename to ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/IdParsersTest.java index 0a26b19b..0d1d0e06 100644 --- a/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/IdFormattersTest.java +++ b/ranger-discovery-bundle/src/test/java/io/appform/ranger/discovery/bundle/id/IdParsersTest.java @@ -1,6 +1,6 @@ package io.appform.ranger.discovery.bundle.id; -import io.appform.ranger.discovery.bundle.id.formatter.IdFormatters; +import io.appform.ranger.discovery.bundle.id.formatter.IdParsers; import lombok.val; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -9,12 +9,12 @@ import java.text.SimpleDateFormat; import java.util.Date; -public class IdFormattersTest { +public class IdParsersTest { @Test void testDefaultId() throws ParseException { val id = "T2407101232336168748798"; - val parsedId = IdFormatters.parse(id).orElse(null); + val parsedId = IdParsers.parse(id).orElse(null); Assertions.assertNotNull(parsedId); Assertions.assertEquals(id, parsedId.getId()); Assertions.assertEquals(798, parsedId.getExponent()); From 2e906e2cad76c29ddcf91e409d2fce0daecb0660 Mon Sep 17 00:00:00 2001 From: Satyam Saxena Date: Wed, 19 Feb 2025 22:14:04 +0530 Subject: [PATCH 6/9] Update Parser test case --- .../appform/ranger/discovery/bundle/id/IdGeneratorTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 b7c70371..9e570c5c 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 @@ -181,7 +181,7 @@ void testConstraintFailure() { @Test void testNodeId() { - val generatedId = IdGenerator.generate("TEST123"); + val generatedId = IdGenerator.generate("TEST"); val parsedId = IdGenerator.parse(generatedId.getId()).orElse(null); Assertions.assertNotNull(parsedId); Assertions.assertEquals(parsedId.getNode(), nodeId); @@ -226,7 +226,7 @@ void testParseSuccess() { @Test void testParseSuccessAfterGeneration() { - val generatedId = IdGenerator.generate("TEST123"); + val generatedId = IdGenerator.generate("TEST"); val parsedId = IdGenerator.parse(generatedId.getId()).orElse(null); Assertions.assertNotNull(parsedId); Assertions.assertEquals(parsedId.getId(), generatedId.getId()); From 6eeb30f69624079594926069246ede5e7b5ad376 Mon Sep 17 00:00:00 2001 From: Satyam Saxena Date: Thu, 20 Feb 2025 15:17:07 +0530 Subject: [PATCH 7/9] Add Exception for Base36IdFormatter type --- .../ranger/discovery/bundle/id/formatter/Base36IdFormatter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/Base36IdFormatter.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/Base36IdFormatter.java index f91bc447..50182014 100644 --- a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/Base36IdFormatter.java +++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/Base36IdFormatter.java @@ -31,7 +31,7 @@ public Base36IdFormatter(IdFormatter idFormatter) { @Override public int getType() { - return 1; + throw new UnsupportedOperationException(); } @Override From 60f2ea96780de691a0578ecd00d8bb4fc146b2d5 Mon Sep 17 00:00:00 2001 From: Satyam Saxena Date: Tue, 25 Feb 2025 22:15:54 +0530 Subject: [PATCH 8/9] Add test case for numeric prefix --- .../ranger/discovery/bundle/id/IdGeneratorTest.java | 7 +++++++ 1 file changed, 7 insertions(+) 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 9e570c5c..98020083 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 @@ -224,6 +224,13 @@ void testParseSuccess() { id.getGeneratedDate()); } + @Test + void testParseFailAfterGeneration() { + val generatedId = IdGenerator.generate("TEST123"); + val parsedId = IdGenerator.parse(generatedId.getId()).orElse(null); + Assertions.assertNull(parsedId); + } + @Test void testParseSuccessAfterGeneration() { val generatedId = IdGenerator.generate("TEST"); From dea19d739d85886eec1930c416c777ee7abbacdf Mon Sep 17 00:00:00 2001 From: Satyam Saxena Date: Wed, 26 Feb 2025 22:27:47 +0530 Subject: [PATCH 9/9] Add IdParserType enum --- .../bundle/id/formatter/Base36IdFormatter.java | 2 +- .../bundle/id/formatter/DefaultIdFormatter.java | 4 ++-- .../discovery/bundle/id/formatter/IdFormatter.java | 2 +- .../bundle/id/formatter/IdParserType.java | 14 ++++++++++++++ .../discovery/bundle/id/formatter/IdParsers.java | 2 +- 5 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdParserType.java diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/Base36IdFormatter.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/Base36IdFormatter.java index 50182014..e53aac78 100644 --- a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/Base36IdFormatter.java +++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/Base36IdFormatter.java @@ -30,7 +30,7 @@ public Base36IdFormatter(IdFormatter idFormatter) { } @Override - public int getType() { + public IdParserType getType() { throw new UnsupportedOperationException(); } diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/DefaultIdFormatter.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/DefaultIdFormatter.java index e757b688..3cb6ac51 100644 --- a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/DefaultIdFormatter.java +++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/DefaultIdFormatter.java @@ -29,8 +29,8 @@ public class DefaultIdFormatter implements IdFormatter { private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyMMddHHmmssSSS"); @Override - public int getType() { - return 0; + public IdParserType getType() { + return IdParserType.DEFAULT; } @Override diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdFormatter.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdFormatter.java index 8ff98130..0fa33809 100644 --- a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdFormatter.java +++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdFormatter.java @@ -22,7 +22,7 @@ public interface IdFormatter { - int getType(); + IdParserType getType(); String format(final DateTime dateTime, final int nodeId, diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdParserType.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdParserType.java new file mode 100644 index 00000000..89038f79 --- /dev/null +++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdParserType.java @@ -0,0 +1,14 @@ +package io.appform.ranger.discovery.bundle.id.formatter; + +import lombok.Getter; + +@Getter +public enum IdParserType { + DEFAULT (0); + + private final int value; + + IdParserType(final int value) { + this.value = value; + } +} diff --git a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdParsers.java b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdParsers.java index 88ffa260..ef77fcce 100644 --- a/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdParsers.java +++ b/ranger-discovery-bundle/src/main/java/io/appform/ranger/discovery/bundle/id/formatter/IdParsers.java @@ -32,7 +32,7 @@ public class IdParsers { private static final Pattern PATTERN = Pattern.compile("([A-Za-z]*)([0-9]{22})([0-9]{2})?(.*)"); private final Map parserRegistry = Map.of( - IdFormatters.original().getType(), IdFormatters.original() + IdFormatters.original().getType().getValue(), IdFormatters.original() ); /**