From 7cca5e88b506bd63aadcd828c551cecf3bd25229 Mon Sep 17 00:00:00 2001 From: Mira Leung Date: Mon, 23 Nov 2020 13:05:07 -0800 Subject: [PATCH 1/2] feat: add parsing for language_settings in gapic.yaml --- .../gapic/model/GapicLanguageSettings.java | 53 +++++++++++ .../GapicLanguageSettingsParser.java | 92 +++++++++++++++++++ .../generator/gapic/protoparser/BUILD.bazel | 1 + .../GapicLanguageSettingsParserTest.java | 57 ++++++++++++ 4 files changed, 203 insertions(+) create mode 100644 src/main/java/com/google/api/generator/gapic/model/GapicLanguageSettings.java create mode 100644 src/main/java/com/google/api/generator/gapic/protoparser/GapicLanguageSettingsParser.java create mode 100644 src/test/java/com/google/api/generator/gapic/protoparser/GapicLanguageSettingsParserTest.java diff --git a/src/main/java/com/google/api/generator/gapic/model/GapicLanguageSettings.java b/src/main/java/com/google/api/generator/gapic/model/GapicLanguageSettings.java new file mode 100644 index 0000000000..cc2db91ead --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/model/GapicLanguageSettings.java @@ -0,0 +1,53 @@ +// Copyright 2020 Google LLC +// +// 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 com.google.api.generator.gapic.model; + +import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableMap; +import java.util.Collections; +import java.util.Map; + +/** Represents the LRO retry settings in a gapic.yaml file. */ +@AutoValue +public abstract class GapicLanguageSettings { + // The Java package mapping. + public abstract String pakkage(); + + // Private. + abstract ImmutableMap protoServiceToJavaClass(); + + public String getJavaFullName(String protoPackage, String protoRpcName) { + String protoFullName = String.format("%s.%s", protoPackage, protoRpcName); + String finalProtoRpcName = protoRpcName; + if (protoServiceToJavaClass().containsKey(protoFullName)) { + finalProtoRpcName = protoServiceToJavaClass().get(protoFullName); + } + return String.format("%s.%s", pakkage(), finalProtoRpcName); + } + + public static Builder builder() { + return new AutoValue_GapicLanguageSettings.Builder() + .setProtoServiceToJavaClass(Collections.emptyMap()); + } + + @AutoValue.Builder + public abstract static class Builder { + public abstract Builder setPakkage(String pakkage); + + public abstract Builder setProtoServiceToJavaClass(Map protoServiceToJavaClass); + + public abstract GapicLanguageSettings build(); + } +} diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/GapicLanguageSettingsParser.java b/src/main/java/com/google/api/generator/gapic/protoparser/GapicLanguageSettingsParser.java new file mode 100644 index 0000000000..7c117b4b07 --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/protoparser/GapicLanguageSettingsParser.java @@ -0,0 +1,92 @@ +// Copyright 2020 Google LLC +// +// 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 com.google.api.generator.gapic.protoparser; + +import com.google.api.generator.gapic.model.GapicLanguageSettings; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Strings; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Map; +import java.util.Optional; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.SafeConstructor; + +public class GapicLanguageSettingsParser { + private static final String YAML_KEY_LANGUAGE_SETTINGS = "language_settings"; + private static final String YAML_KEY_JAVA = "java"; + private static final String YAML_KEY_PACKAGE_NAME = "package_name"; + private static final String YAML_KEY_INTERFACE_NAMES = "interface_names"; + + public static Optional parse(Optional gapicYamlConfigFilePathOpt) { + return gapicYamlConfigFilePathOpt.isPresent() + ? parse(gapicYamlConfigFilePathOpt.get()) + : Optional.empty(); + } + + @VisibleForTesting + static Optional parse(String gapicYamlConfigFilePath) { + if (Strings.isNullOrEmpty(gapicYamlConfigFilePath) + || !(new File(gapicYamlConfigFilePath)).exists()) { + return Optional.empty(); + } + + String fileContents = null; + + try { + fileContents = new String(Files.readAllBytes(Paths.get(gapicYamlConfigFilePath))); + } catch (IOException e) { + return Optional.empty(); + } + + Yaml yaml = new Yaml(new SafeConstructor()); + Map yamlMap = yaml.load(fileContents); + return parseFromMap(yamlMap); + } + + private static Optional parseFromMap(Map yamlMap) { + if (!yamlMap.containsKey(YAML_KEY_LANGUAGE_SETTINGS)) { + return Optional.empty(); + } + + Map languageYamlConfig = + (Map) yamlMap.get(YAML_KEY_LANGUAGE_SETTINGS); + if (!languageYamlConfig.containsKey(YAML_KEY_JAVA)) { + return Optional.empty(); + } + + Map javaYamlConfig = + (Map) languageYamlConfig.get(YAML_KEY_JAVA); + if (!javaYamlConfig.containsKey(YAML_KEY_PACKAGE_NAME)) { + return Optional.empty(); + } + + GapicLanguageSettings.Builder gapicLanguageSettingsBuilder = + GapicLanguageSettings.builder() + .setPakkage((String) javaYamlConfig.get(YAML_KEY_PACKAGE_NAME)); + + if (!javaYamlConfig.containsKey(YAML_KEY_INTERFACE_NAMES)) { + return Optional.of(gapicLanguageSettingsBuilder.build()); + } + + return Optional.of( + gapicLanguageSettingsBuilder + .setProtoServiceToJavaClass( + (Map) javaYamlConfig.get(YAML_KEY_INTERFACE_NAMES)) + .build()); + } +} diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/BUILD.bazel b/src/test/java/com/google/api/generator/gapic/protoparser/BUILD.bazel index dda78e43ad..abf6a5e00a 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/BUILD.bazel +++ b/src/test/java/com/google/api/generator/gapic/protoparser/BUILD.bazel @@ -4,6 +4,7 @@ package(default_visibility = ["//visibility:public"]) TESTS = [ "BatchingSettingsConfigParserTest", + "GapicLanguageSettingsParserTest", "GapicLroRetrySettingsParserTest", "HttpRuleParserTest", "MethodSignatureParserTest", diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/GapicLanguageSettingsParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/GapicLanguageSettingsParserTest.java new file mode 100644 index 0000000000..f2a6fcbe07 --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/protoparser/GapicLanguageSettingsParserTest.java @@ -0,0 +1,57 @@ +// Copyright 2020 Google LLC +// +// 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 com.google.api.generator.gapic.protoparser; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertTrue; + +import com.google.api.generator.gapic.model.GapicLanguageSettings; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Optional; +import org.junit.Test; + +public class GapicLanguageSettingsParserTest { + private static final String YAML_DIRECTORY = + "src/test/java/com/google/api/generator/gapic/testdata/"; + + @Test + public void parseLanguageSettings_onlyInterfacePresent() { + String filename = "datastore_gapic.yaml"; + Path path = Paths.get(YAML_DIRECTORY, filename); + Optional settingsOpt = + GapicLanguageSettingsParser.parse(path.toString()); + assertTrue(settingsOpt.isPresent()); + GapicLanguageSettings settings = settingsOpt.get(); + assertEquals("com.google.cloud.datastore.v1", settings.pakkage()); + assertEquals( + "com.google.cloud.datastore.v1.FooBar", + settings.getJavaFullName("google.datastore.v1", "FooBar")); + } + + @Test + public void parseLanguageSettings_methodNameOverridesPresent() { + String filename = "logging_gapic.yaml"; + Path path = Paths.get(YAML_DIRECTORY, filename); + Optional settingsOpt = + GapicLanguageSettingsParser.parse(path.toString()); + assertTrue(settingsOpt.isPresent()); + GapicLanguageSettings settings = settingsOpt.get(); + assertEquals("com.google.cloud.logging.v2", settings.pakkage()); + assertEquals( + "com.google.cloud.logging.v2.Logging", + settings.getJavaFullName("google.logging.v2", "LoggingServiceV2")); + } +} From 4593cc0bd535efc7936d9f0d1bd0ba6e31db68da Mon Sep 17 00:00:00 2001 From: Mira Leung Date: Mon, 23 Nov 2020 13:06:02 -0800 Subject: [PATCH 2/2] fix: restructure GapicServiceConfig table-processing into ctor --- .../gapic/model/GapicServiceConfig.java | 74 ++++++++++--------- 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/src/main/java/com/google/api/generator/gapic/model/GapicServiceConfig.java b/src/main/java/com/google/api/generator/gapic/model/GapicServiceConfig.java index 4e814b9508..73a36f1e7d 100644 --- a/src/main/java/com/google/api/generator/gapic/model/GapicServiceConfig.java +++ b/src/main/java/com/google/api/generator/gapic/model/GapicServiceConfig.java @@ -42,18 +42,20 @@ public class GapicServiceConfig { private final List methodConfigs; private final Map methodConfigTable; - private final Map lroRetrySettingsTable; - private final Map batchingSettingsTable; + private final Map lroRetrySettingsTable = + new HashMap<>(); + private final Map batchingSettingsTable = + new HashMap<>(); private GapicServiceConfig( List methodConfigs, Map methodConfigTable, - Map lroRetrySettingsTable, - Map batchingSettingsTable) { + Optional> lroRetrySettingsOpt, + Optional> batchingSettingsOpt) { this.methodConfigs = methodConfigs; this.methodConfigTable = methodConfigTable; - this.lroRetrySettingsTable = lroRetrySettingsTable; - this.batchingSettingsTable = batchingSettingsTable; + setLroRetrySettings(lroRetrySettingsOpt); + setBatchingRestrySettings(batchingSettingsOpt); } public static GapicServiceConfig create( @@ -70,36 +72,42 @@ public static GapicServiceConfig create( } } - Map lroRetrySettingsTable = new HashMap<>(); - if (lroRetrySettingsOpt.isPresent()) { - for (GapicLroRetrySettings lroRetrySetting : lroRetrySettingsOpt.get()) { - lroRetrySettingsTable.put( - MethodConfig.Name.newBuilder() - .setService( - String.format( - "%s.%s", lroRetrySetting.protoPakkage(), lroRetrySetting.serviceName())) - .setMethod(lroRetrySetting.methodName()) - .build(), - lroRetrySetting); - } - } + return new GapicServiceConfig( + methodConfigs, methodConfigTable, lroRetrySettingsOpt, batchingSettingsOpt); + } - Map batchingSettingsTable = new HashMap<>(); - if (batchingSettingsOpt.isPresent()) { - for (GapicBatchingSettings batchingSetting : batchingSettingsOpt.get()) { - batchingSettingsTable.put( - MethodConfig.Name.newBuilder() - .setService( - String.format( - "%s.%s", batchingSetting.protoPakkage(), batchingSetting.serviceName())) - .setMethod(batchingSetting.methodName()) - .build(), - batchingSetting); - } + public void setLroRetrySettings(Optional> lroRetrySettingsOpt) { + if (!lroRetrySettingsOpt.isPresent()) { + return; + } + lroRetrySettingsTable.clear(); + for (GapicLroRetrySettings lroRetrySetting : lroRetrySettingsOpt.get()) { + lroRetrySettingsTable.put( + MethodConfig.Name.newBuilder() + .setService( + String.format( + "%s.%s", lroRetrySetting.protoPakkage(), lroRetrySetting.serviceName())) + .setMethod(lroRetrySetting.methodName()) + .build(), + lroRetrySetting); } + } - return new GapicServiceConfig( - methodConfigs, methodConfigTable, lroRetrySettingsTable, batchingSettingsTable); + public void setBatchingRestrySettings(Optional> batchingSettingsOpt) { + if (!batchingSettingsOpt.isPresent()) { + return; + } + batchingSettingsTable.clear(); + for (GapicBatchingSettings batchingSetting : batchingSettingsOpt.get()) { + batchingSettingsTable.put( + MethodConfig.Name.newBuilder() + .setService( + String.format( + "%s.%s", batchingSetting.protoPakkage(), batchingSetting.serviceName())) + .setMethod(batchingSetting.methodName()) + .build(), + batchingSetting); + } } public Map getAllGapicRetrySettings(Service service) {