From 6a8a0a44fbf942ea6224ab3d8d4b3bcc6c79c5b4 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Thu, 27 Jan 2022 12:43:58 -0500 Subject: [PATCH 1/5] chore(main): release 2.1.4-SNAPSHOT (#334) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- build.gradle | 2 +- versions.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 2af47fe51..997621553 100644 --- a/build.gradle +++ b/build.gradle @@ -26,7 +26,7 @@ apply plugin: 'io.github.gradle-nexus.publish-plugin' group = "com.google.api" archivesBaseName = "api-common" -project.version = "2.1.3" // {x-version-update:api-common:current} +project.version = "2.1.4-SNAPSHOT" // {x-version-update:api-common:current} sourceCompatibility = 1.8 targetCompatibility = 1.8 diff --git a/versions.txt b/versions.txt index dfce69814..95d79688f 100644 --- a/versions.txt +++ b/versions.txt @@ -1,4 +1,4 @@ # Format: # module:released-version:current-version -api-common:2.1.3:2.1.3 +api-common:2.1.3:2.1.4-SNAPSHOT From 309521b3e6666d6ba86b47714c898a3b15d843bd Mon Sep 17 00:00:00 2001 From: Blake Li Date: Fri, 4 Feb 2022 14:00:52 -0500 Subject: [PATCH 2/5] Support delimiters(_-.~) as start or end characters for a segment. (#336) Support delimiters(_-.~) as start or end characters for a segment if the segment does not contain complex resource names. A segment can start with a delimiter, as long as there is no { right after it. A segment can end with a delimiter, as long as there is no } right before it. A segment like .{well}-{known} or {well}-{known}. is invalid. A segment like .well-known, .well-{known} or .-~{well-known} is considered a literal hence is valid. --- .../google/api/pathtemplate/PathTemplate.java | 18 ++++- .../api/pathtemplate/PathTemplateTest.java | 77 ++++++++++++++++++- 2 files changed, 89 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/google/api/pathtemplate/PathTemplate.java b/src/main/java/com/google/api/pathtemplate/PathTemplate.java index 4e4e770e6..4458e5ed6 100644 --- a/src/main/java/com/google/api/pathtemplate/PathTemplate.java +++ b/src/main/java/com/google/api/pathtemplate/PathTemplate.java @@ -887,9 +887,7 @@ private static ImmutableList parseTemplate(String template) { boolean isLastSegment = (template.indexOf(seg) + seg.length()) == template.length(); boolean isCollectionWildcard = !isLastSegment && (seg.equals("-") || seg.equals("-}")); - if (!isCollectionWildcard - && (COMPLEX_DELIMITER_PATTERN.matcher(seg.substring(0, 1)).find() - || COMPLEX_DELIMITER_PATTERN.matcher(seg.substring(seg.length() - 1)).find())) { + if (!isCollectionWildcard && isSegmentBeginOrEndInvalid(seg)) { throw new ValidationException("parse error: invalid begin or end character in '%s'", seg); } // Disallow zero or multiple delimiters between variable names. @@ -1015,6 +1013,20 @@ private static ImmutableList parseTemplate(String template) { return builder.build(); } + private static boolean isSegmentBeginOrEndInvalid(String seg) { + // A segment is invalid if it contains only one character and the character is a delimiter + if (seg.length() == 1 && COMPLEX_DELIMITER_PATTERN.matcher(seg).find()) { + return true; + } + // A segment can start with a delimiter, as long as there is no { right after it. + // A segment can end with a delimiter, as long as there is no } right before it. + // e.g. Invalid: .{well}-{known}, {well}-{known}- + // Valid: .well-known, .well-{known}, .-~{well-known}, these segments are all considered as literals for matching + return (COMPLEX_DELIMITER_PATTERN.matcher(seg.substring(0, 1)).find() && seg.charAt(1) == '{') + || (COMPLEX_DELIMITER_PATTERN.matcher(seg.substring(seg.length() - 1)).find() + && seg.charAt(seg.length() - 2) == '}'); + } + private static List parseComplexResourceId(String seg) { List segments = new ArrayList<>(); List separatorIndices = new ArrayList<>(); diff --git a/src/test/java/com/google/api/pathtemplate/PathTemplateTest.java b/src/test/java/com/google/api/pathtemplate/PathTemplateTest.java index 49b64e6d4..6e4f02557 100644 --- a/src/test/java/com/google/api/pathtemplate/PathTemplateTest.java +++ b/src/test/java/com/google/api/pathtemplate/PathTemplateTest.java @@ -487,9 +487,6 @@ public void complexResourceBasicInvalidIds() { @Test public void complexResourceMultipleDelimiters() { thrown.expect(ValidationException.class); - PathTemplate.create("projects/*/zones/.-~{zone_a}"); - thrown.expectMessage( - String.format("parse error: invalid begin or end character in '%s'", ".-~{zone_a}")); PathTemplate.create("projects/*/zones/{zone_a}~.{zone_b}"); thrown.expectMessage( @@ -717,6 +714,80 @@ public void instantiateWithCustomVerbs() { Truth.assertThat(template.matches(templateInstance)).isTrue(); } + @Test + public void instantiateWithASegmentStartsWithADelimiter() { + PathTemplate pathTemplate = + PathTemplate.create( + "v1beta1/{parent=projects/*/locations/*/clusters/*}/.well-known/openid-configuration"); + String pattern = + "v1beta1/projects/abc/locations/def/clusters/yte/.well-known/openid-configuration"; + Truth.assertThat(pathTemplate.matches(pattern)).isTrue(); + } + + @Test + public void instantiateWithASegmentContainingComplexResourceNamesAndStartsWithADelimiter() { + thrown.expect(ValidationException.class); + PathTemplate.create( + "v1beta1/{parent=projects/*/locations/*/clusters/*}/.{well}-{known}/openid-configuration"); + thrown.expectMessage( + String.format("parse error: invalid begin or end character in '%s'", ".{well}-{known}")); + } + + @Test + public void + instantiateWithASegmentContainingNoComplexResourceNamesAndStartsWithMultipleDelimiters() { + PathTemplate pathTemplate = + PathTemplate.create( + "v1beta1/{parent=projects/*/locations/*/clusters/*}/.-~well-known/openid-configuration"); + String pattern = + "v1beta1/projects/abc/locations/def/clusters/yte/.-~well-known/openid-configuration"; + Truth.assertThat(pathTemplate.matches(pattern)).isTrue(); + } + + @Test + public void instantiateWithASegmentOnlyContainingOneDelimiter() { + thrown.expect(ValidationException.class); + PathTemplate.create("v1/publishers/{publisher}/books/."); + thrown.expectMessage(String.format("parse error: invalid begin or end character in '%s'", ".")); + } + + @Test + public void instantiateWithASegmentOnlyContainingOneCharacter() { + PathTemplate pathTemplate = PathTemplate.create("v1/publishers/{publisher}/books/a"); + String pattern = "v1/publishers/o'reilly/books/a"; + Truth.assertThat(pathTemplate.matches(pattern)).isTrue(); + } + + @Test + public void instantiateWithASegmentEndsWithADelimiter() { + PathTemplate pathTemplate = + PathTemplate.create( + "v1beta1/{parent=projects/*/locations/*/clusters/*}/well-known./openid-configuration"); + String pattern = + "v1beta1/projects/abc/locations/def/clusters/yte/well-known./openid-configuration"; + Truth.assertThat(pathTemplate.matches(pattern)).isTrue(); + } + + @Test + public void instantiateWithASegmentContainingComplexResourceNamesAndEndsWithADelimiter() { + thrown.expect(ValidationException.class); + PathTemplate.create( + "v1beta1/{parent=projects/*/locations/*/clusters/*}/{well}-{known}./openid-configuration"); + thrown.expectMessage( + String.format("parse error: invalid begin or end character in '%s'", "{well}-{known}.")); + } + + @Test + public void + instantiateWithASegmentContainingNoComplexResourceNamesAndEndsWithMultipleDelimiters() { + PathTemplate pathTemplate = + PathTemplate.create( + "v1beta1/{parent=projects/*/locations/*/clusters/*}/well-known.-~/openid-configuration"); + String pattern = + "v1beta1/projects/abc/locations/def/clusters/yte/well-known.-~/openid-configuration"; + Truth.assertThat(pathTemplate.matches(pattern)).isTrue(); + } + // Other // ===== From fb048ca4037dac220169ba27dc149b36a73ee919 Mon Sep 17 00:00:00 2001 From: Blake Li Date: Fri, 4 Feb 2022 21:47:22 -0500 Subject: [PATCH 3/5] Add unit tests for explicit dynamic routing header feature. (#337) --- .../api/pathtemplate/PathTemplateTest.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/test/java/com/google/api/pathtemplate/PathTemplateTest.java b/src/test/java/com/google/api/pathtemplate/PathTemplateTest.java index 6e4f02557..ae829c5ad 100644 --- a/src/test/java/com/google/api/pathtemplate/PathTemplateTest.java +++ b/src/test/java/com/google/api/pathtemplate/PathTemplateTest.java @@ -178,6 +178,36 @@ public void matchWithUnboundInMiddle() { assertPositionalMatch(template.match("bar/foo/foo/foo/bar"), "foo/foo", "bar"); } + @Test + public void matchWithNamedBindings() { + PathTemplate template = PathTemplate.create("projects/*/{instance_id=instances/*}/**"); + Map actual = + template.match("projects/proj_foo/instances/instance_bar/table/table_baz"); + Truth.assertThat(actual).containsEntry("instance_id", "instances/instance_bar"); + } + + @Test + public void matchFailWithNamedBindingsWhenPathMismatches() { + PathTemplate template = PathTemplate.create("projects/*/{instance_id=instances/*}/**"); + Map actual = + template.match("projects/proj_foo/instances_fail/instance_bar/table/table_baz"); + Truth.assertThat(actual).isNull(); + } + + @Test + public void matchWithNamedBindingsThatHasOnlyWildcard() { + PathTemplate template = PathTemplate.create("profiles/{routing_id=*}"); + Map actual = template.match("profiles/prof_qux"); + Truth.assertThat(actual).containsEntry("routing_id", "prof_qux"); + } + + @Test + public void matchFailWithNamedBindingsThatHasOnlyWildcardWhenPathMismatches() { + PathTemplate template = PathTemplate.create("profiles/{routing_id=*}"); + Map actual = template.match("profiles/prof_qux/fail"); + Truth.assertThat(actual).isNull(); + } + @Test public void matchWithCustomVerbs() { PathTemplate template = PathTemplate.create("**:foo"); From b2eba9e7497fe13f7132e05a658ca936de5aa9c5 Mon Sep 17 00:00:00 2001 From: Neenu Shaji Date: Mon, 7 Feb 2022 18:13:37 -0500 Subject: [PATCH 4/5] fix: Support delimiters(_-.~) as start or end characters for a segment (#338) * fix: Support delimiters(_-.~) as start or end characters for a segment * Update versions.txt From 11380dd34e4b7780079cfe4b00898267996fc705 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Mon, 7 Feb 2022 18:22:38 -0500 Subject: [PATCH 5/5] chore(main): release 2.1.4 (#339) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- CHANGELOG.md | 7 +++++++ build.gradle | 2 +- versions.txt | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd8e11a66..689fcd2ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +### [2.1.4](https://github.com/googleapis/api-common-java/compare/v2.1.3...v2.1.4) (2022-02-07) + + +### Bug Fixes + +* Support delimiters(_-.~) as start or end characters for a segment ([#338](https://github.com/googleapis/api-common-java/issues/338)) ([b2eba9e](https://github.com/googleapis/api-common-java/commit/b2eba9e7497fe13f7132e05a658ca936de5aa9c5)) + ### [2.1.3](https://github.com/googleapis/api-common-java/compare/v2.1.2...v2.1.3) (2022-01-25) diff --git a/build.gradle b/build.gradle index 997621553..907bc9bf5 100644 --- a/build.gradle +++ b/build.gradle @@ -26,7 +26,7 @@ apply plugin: 'io.github.gradle-nexus.publish-plugin' group = "com.google.api" archivesBaseName = "api-common" -project.version = "2.1.4-SNAPSHOT" // {x-version-update:api-common:current} +project.version = "2.1.4" // {x-version-update:api-common:current} sourceCompatibility = 1.8 targetCompatibility = 1.8 diff --git a/versions.txt b/versions.txt index 95d79688f..3dbfb03b7 100644 --- a/versions.txt +++ b/versions.txt @@ -1,4 +1,4 @@ # Format: # module:released-version:current-version -api-common:2.1.3:2.1.4-SNAPSHOT +api-common:2.1.4:2.1.4