Skip to content

Commit

Permalink
Config gen fixes - hewing closer to desired manual config
Browse files Browse the repository at this point in the history
  • Loading branch information
garrettjonesgoogle committed Aug 3, 2016
1 parent 653b6f2 commit bc6be6b
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 97 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.google.api.tools.framework.aspects.http.HttpConfigAspect;
import com.google.api.tools.framework.model.Interface;
import com.google.api.tools.framework.model.Method;
import com.google.api.tools.framework.model.ProtoFile;
import com.google.api.tools.framework.model.stages.Merged;
import com.google.api.tools.framework.processors.merger.Merger;
import com.google.api.tools.framework.processors.resolver.Resolver;
Expand All @@ -30,9 +31,6 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.io.Files;

import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;

import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
Expand All @@ -45,6 +43,9 @@
import java.util.Set;
import java.util.TreeMap;

import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;

/** Main class for the config generator. */
public class ConfigGeneratorApi extends ToolDriverBase {

Expand All @@ -68,7 +69,7 @@ public class ConfigGeneratorApi extends ToolDriverBase {
private static final String CONFIG_PROTO_TYPE = ConfigProto.getDescriptor().getFullName();

private static final String CONFIG_KEY_TIMEOUT = "timeout_millis";
private static final int CONFIG_VALUE_DEFAULT_TIMEOUT = 30000;
private static final int CONFIG_VALUE_DEFAULT_TIMEOUT = 60000;

/** Constructs a config generator api based on given options. */
public ConfigGeneratorApi(ToolOptions options) {
Expand Down Expand Up @@ -156,9 +157,13 @@ private List<Object> generateInterfacesConfig() {
}

private Map<String, Object> generateLanguageSettings() {
int index =
Preconditions.checkPositionIndex(model.getFiles().size() - 1, model.getFiles().size());
String packageName = model.getFiles().get(index).getFullName();
String packageName = null;
for (Interface interfaze : model.getSymbolTable().getInterfaces()) {
// use the package name of the first interface
packageName = interfaze.getFile().getFullName();
break;
}
Preconditions.checkNotNull(packageName, "No interface found.");
return LanguageGenerator.generate(packageName);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,10 @@ public Map<String, Object> generate(Method method) {
}
result.put(CONFIG_KEY_REQUIRED_FIELDS, new LinkedList<String>(parameterList));
}
if (parameterList.size() > REQUEST_OBJECT_METHOD_THRESHOLD) {
// use all fields for the following check; if there are ignored fields for flattening
// purposes, the caller still needs a way to set them (by using the request object method).
if (message.getFields().size() > REQUEST_OBJECT_METHOD_THRESHOLD
|| message.getFields().size() != parameterList.size()) {
result.put(CONFIG_KEY_REQUEST_OBJECT_METHOD, true);
} else {
result.put(CONFIG_KEY_REQUEST_OBJECT_METHOD, false);
Expand Down
82 changes: 56 additions & 26 deletions src/main/java/com/google/api/codegen/config/LanguageGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableMap;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.LinkedList;
Expand All @@ -33,24 +34,31 @@ public class LanguageGenerator {

private static final String CONFIG_KEY_PACKAGE_NAME = "package_name";

private static final Map<String, LanguageFormatter> LANGUAGE_FORMATTERS =
ImmutableMap.<String, LanguageFormatter>builder()
.put("java", new SimpleLanguageFormatter(".", "com", false))
.put("python", new SimpleLanguageFormatter(".", null, false))
.put("go", new GoLanguageFormatter())
.put("csharp", new SimpleLanguageFormatter(".", null, true))
.put("ruby", new SimpleLanguageFormatter("::", null, true))
.put("php", new SimpleLanguageFormatter("\\", null, true))
.build();
private static final Map<String, LanguageFormatter> LANGUAGE_FORMATTERS;

static {
List<RewriteRule> javaRewriteRules =
Arrays.asList(
new RewriteRule("^google", "com.google.cloud"),
new RewriteRule("(.v[^.]+)$", ".spi$1"));
List<RewriteRule> phpRewriteRules = Arrays.asList(new RewriteRule("^google", "google.cloud"));
LANGUAGE_FORMATTERS =
ImmutableMap.<String, LanguageFormatter>builder()
.put("java", new SimpleLanguageFormatter(".", javaRewriteRules, false))
.put("python", new SimpleLanguageFormatter(".", null, false))
.put("go", new GoLanguageFormatter())
.put("csharp", new SimpleLanguageFormatter(".", null, true))
.put("ruby", new SimpleLanguageFormatter("::", null, true))
.put("php", new SimpleLanguageFormatter("\\", phpRewriteRules, true))
.build();
}

public static Map<String, Object> generate(String packageName) {
List<String> packageNameComponents =
Arrays.asList(packageName.split(DEFAULT_PACKAGE_SEPARATOR));

Map<String, Object> languages = new LinkedHashMap<>();
for (String language : LANGUAGE_FORMATTERS.keySet()) {
LanguageFormatter formatter = LANGUAGE_FORMATTERS.get(language);
String formattedPackageName = formatter.getFormattedPackageName(packageNameComponents);
String formattedPackageName = formatter.getFormattedPackageName(packageName);

Map<String, Object> packageNameMap = new LinkedHashMap<>();
packageNameMap.put(CONFIG_KEY_PACKAGE_NAME, formattedPackageName);
Expand All @@ -64,27 +72,32 @@ private static String firstCharToUpperCase(String string) {
}

private interface LanguageFormatter {
String getFormattedPackageName(List<String> nameComponents);
String getFormattedPackageName(String packageName);
}

private static class SimpleLanguageFormatter implements LanguageFormatter {

private final String separator;
private final String prefix;
private final List<RewriteRule> rewriteRules;
private final boolean capitalize;

public SimpleLanguageFormatter(String separator, String prefix, boolean capitalize) {
public SimpleLanguageFormatter(
String separator, List<RewriteRule> rewriteRules, boolean capitalize) {
this.separator = separator;
this.prefix = prefix;
if (rewriteRules != null) {
this.rewriteRules = rewriteRules;
} else {
this.rewriteRules = new ArrayList<>();
}
this.capitalize = capitalize;
}

public String getFormattedPackageName(List<String> nameComponents) {
List<String> elements = new LinkedList<>();
if (prefix != null) {
elements.add(prefix);
public String getFormattedPackageName(String packageName) {
for (RewriteRule rewriteRule : rewriteRules) {
packageName = rewriteRule.rewrite(packageName);
}
for (String component : nameComponents) {
List<String> elements = new LinkedList<>();
for (String component : packageName.split(DEFAULT_PACKAGE_SEPARATOR)) {
if (capitalize) {
elements.add(firstCharToUpperCase(component));
} else {
Expand All @@ -96,11 +109,10 @@ public String getFormattedPackageName(List<String> nameComponents) {
}

private static class GoLanguageFormatter implements LanguageFormatter {
public String getFormattedPackageName(String packageName) {
List<String> nameComponents = new ArrayList<>();
nameComponents.addAll(Arrays.asList(packageName.split(DEFAULT_PACKAGE_SEPARATOR)));

private static LanguageFormatter backup =
new SimpleLanguageFormatter("/", "google.golang.org", false);

public String getFormattedPackageName(List<String> nameComponents) {
// If the name follows the pattern google.foo.bar.v1234,
// we reformat it into cloud.google.com.
// google.logging.v2 => cloud.google.com/go/logging/apiv2
Expand All @@ -109,12 +121,30 @@ public String getFormattedPackageName(List<String> nameComponents) {
if (size < 3
|| !nameComponents.get(0).equals("google")
|| !nameComponents.get(size - 1).startsWith("v")) {
return backup.getFormattedPackageName(nameComponents);
nameComponents.add(0, "google.golang.org");
return Joiner.on("/").join(nameComponents);
}
return "cloud.google.com/go/"
+ Joiner.on("/").join(nameComponents.subList(1, size - 1))
+ "/api"
+ nameComponents.get(size - 1);
}
}

private static class RewriteRule {
private final String pattern;
private final String replacement;

public RewriteRule(String pattern, String replacement) {
this.pattern = pattern;
this.replacement = replacement;
}

public String rewrite(String input) {
if (pattern == null) {
return input;
}
return input.replaceAll(pattern, replacement);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ private static List<Object> generateRetryParams() {
retryParamsDefault.put("initial_retry_delay_millis", 100);
retryParamsDefault.put("retry_delay_multiplier", 1.3);
retryParamsDefault.put("max_retry_delay_millis", 60000);
retryParamsDefault.put("initial_rpc_timeout_millis", 60000);
retryParamsDefault.put("initial_rpc_timeout_millis", 20000);
retryParamsDefault.put("rpc_timeout_multiplier", 1);
retryParamsDefault.put("max_rpc_timeout_millis", 60000);
retryParamsDefault.put("max_rpc_timeout_millis", 20000);
retryParamsDefault.put("total_timeout_millis", 600000);

List<Object> output = new LinkedList<Object>();
Expand Down
60 changes: 21 additions & 39 deletions src/test/java/com/google/api/codegen/ConfigGenerationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,63 +15,45 @@
package com.google.api.codegen;

import com.google.api.codegen.config.ConfigGeneratorApi;
import com.google.api.tools.framework.model.Model;
import com.google.api.tools.framework.model.testing.TestConfig;
import com.google.api.tools.framework.model.testing.TestDataLocator;
import com.google.api.tools.framework.model.testing.ConfigBaselineTestCase;
import com.google.api.tools.framework.tools.ToolOptions;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import java.io.File;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Collections;

public class ConfigGenerationTest {
@Rule public TemporaryFolder tempDir = new TemporaryFolder();
import org.junit.Test;

@Test
public void config() throws Exception {
String testTarget = "library";
String baselineName = testTarget + "_config.baseline";
public class ConfigGenerationTest extends ConfigBaselineTestCase {
@Override
protected String baselineFileName() {
return "library_config.baseline";
}

TestDataLocator locator = TestDataLocator.create(this.getClass());
TestConfig testConfig =
new TestConfig(
locator, tempDir.getRoot().getPath(), Collections.singletonList(testTarget + ".proto"));
Model model = Model.create(testConfig.getDescriptor());
@Override
protected boolean suppressDiagnosis() {
// Suppress linter warnings
return true;
}

String outFile = tempDir.getRoot().getPath() + File.separator + baselineName;
@Override
public Object run() throws Exception {
String outFile = tempDir.getRoot().getPath() + File.separator + baselineFileName();

ToolOptions options = ToolOptions.create();
options.set(ConfigGeneratorApi.OUTPUT_FILE, outFile);
options.set(ToolOptions.DESCRIPTOR_SET, testConfig.getDescriptorFile().toString());
new ConfigGeneratorApi(options).run();

URL baselineUrl = locator.findTestData(baselineName);
if (baselineUrl == null) {
throw new IllegalStateException(String.format("baseline not found: %s", baselineName));
}
String baselineContent = locator.readTestData(baselineUrl);
String outputContent =
new String(Files.readAllBytes(Paths.get(outFile)), StandardCharsets.UTF_8);

if (!outputContent.equals(baselineContent)) {
Path saveFile =
Paths.get(
System.getProperty("java.io.tmpdir"),
String.format("%s_testdata", this.getClass().getPackage().getName()),
baselineName);
Files.createDirectories(saveFile.getParent());
Files.copy(Paths.get(outFile), saveFile, StandardCopyOption.REPLACE_EXISTING);
throw new IllegalStateException(
String.format("baseline failed, output saved at %s", saveFile));
}
return outputContent;
}

@Test
public void library() throws Exception {
test("library");
}
}
Loading

0 comments on commit bc6be6b

Please sign in to comment.