Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import com.google.api.pathtemplate.PathTemplate;
import com.google.common.base.Preconditions;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
Expand All @@ -31,50 +30,51 @@ public class ResourceNameTokenizer {
private static final String EQUALS_WILDCARD = "=*";
private static final String EQUALS_PATH_WILDCARD = "=**";

static List<List<String>> parseTokenHierarchy(List<String> patterns) {
List<String> nonSlashSepStrings = Arrays.asList("}_{", "}-{", "}.{", "}~{");
private static final String NON_SLASH_SEP_REGEX = "\\}(_|\\-|\\.|~)\\{";

static List<List<String>> parseTokenHierarchy(List<String> patterns) {
List<List<String>> tokenHierachies = new ArrayList<>();
for (String pattern : patterns) {
List<String> hierarchy = new ArrayList<>();
Set<String> vars = PathTemplate.create(pattern).vars();
String[] patternTokens = pattern.split(SLASH);
for (String patternToken : patternTokens) {
if (patternToken.startsWith(LEFT_BRACE) && patternToken.endsWith(RIGHT_BRACE)) {
String processedPatternToken =
// Replacement order matters - ensure the first is not a subcomponent of the second.
patternToken.replace(EQUALS_PATH_WILDCARD, EMPTY).replace(EQUALS_WILDCARD, EMPTY);
String[] rawPatternTokens = pattern.split(SLASH);
List<String> patternTokens = new ArrayList<>();

// Handle non-slash separators.
if (nonSlashSepStrings.stream().anyMatch(s -> patternToken.contains(s))) {
for (String str : nonSlashSepStrings) {
processedPatternToken = processedPatternToken.replace(str, "_");
}
} else {
final int processedPatternTokenLength = processedPatternToken.length();
// Handles wildcards.
List<String> candidateVars =
vars.stream()
// Check that the token size is within ~3 of the var, to avoid mismatching on
// variables with same-named subcomponents.
// Otherwise, "customer_client_link" will match with "customer".
.filter(
v ->
patternToken.contains(v)
// Accounting for braces.
&& processedPatternTokenLength - v.length() < 3)
.collect(Collectors.toList());
Preconditions.checkState(
!candidateVars.isEmpty(),
String.format(
"No variable candidates found for token %s in pattern %s",
processedPatternToken, pattern));
processedPatternToken = candidateVars.get(0);
// Process variables.
for (String rawPatternToken : rawPatternTokens) {
if (!rawPatternToken.startsWith(LEFT_BRACE) || !rawPatternToken.endsWith(RIGHT_BRACE)) {
continue;
}
// Add any non-slash separated tokens in the order that they're seen.
for (String subToken : rawPatternToken.split(NON_SLASH_SEP_REGEX)) {
String processedSubToken =
subToken.replace(LEFT_BRACE, EMPTY).replace(RIGHT_BRACE, EMPTY);
if (!patternTokens.contains(processedSubToken)) {
patternTokens.add(processedSubToken);
}
hierarchy.add(
processedPatternToken.replace(LEFT_BRACE, EMPTY).replace(RIGHT_BRACE, EMPTY));
}
}

for (String patternToken : patternTokens) {
// Handle wildcards.
final String processedPatternToken =
// Replacement order matters - ensure the first is not a subcomponent of the second.
patternToken.replace(EQUALS_PATH_WILDCARD, EMPTY).replace(EQUALS_WILDCARD, EMPTY);

List<String> candidateVars =
vars.stream()
// Check that the token matches the variable exactly, to avoid mismatching on
// variables with same-named subcomponents.
// Otherwise, "customer_client_link" will match with "customer".
.filter(v -> processedPatternToken.equals(v))
.collect(Collectors.toList());
Preconditions.checkState(
!candidateVars.isEmpty(),
String.format(
"No variable candidates found for token %s in pattern %s among variables %s",
processedPatternToken, pattern, vars));
hierarchy.add(processedPatternToken);
}
tokenHierachies.add(hierarchy);
}
return tokenHierachies;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,4 +187,33 @@ public void generateResourceNameClass_testingSessionOnePattern() {
Path goldenFilePath = Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "SessionName.golden");
Assert.assertCodeEquals(goldenFilePath, visitor.write());
}

@Test
public void generateResourceNameClass_testingBlueprintPatternWithNonSlashSeparator() {
FileDescriptor testingFileDescriptor = TestingOuterClass.getDescriptor();
ServiceDescriptor testingService = testingFileDescriptor.getServices().get(0);
assertEquals(testingService.getName(), "Testing");

Map<String, Message> messageTypes = Parser.parseMessages(testingFileDescriptor);
Map<String, ResourceName> resourceNames = Parser.parseResourceNames(testingFileDescriptor);
Set<ResourceName> outputResourceNames = new HashSet<>();
List<Service> services =
Parser.parseService(
testingFileDescriptor,
messageTypes,
resourceNames,
Optional.empty(),
outputResourceNames);

ResourceName testResname = resourceNames.get("showcase.googleapis.com/Test");
assertThat(outputResourceNames).contains(testResname);

GapicClass clazz = ResourceNameHelperClassComposer.instance().generate(testResname);

JavaWriterVisitor visitor = new JavaWriterVisitor();
clazz.classDefinition().accept(visitor);
Utils.saveCodegenToFile(this.getClass(), "TestName.golden", visitor.write());
Path goldenFilePath = Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "TestName.golden");
Assert.assertCodeEquals(goldenFilePath, visitor.write());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,12 @@ public void parseTokenHierarchy_singletonCollectionAndNonSlashSeparators() {

List<List<String>> tokenHierarchies = ResourceNameTokenizer.parseTokenHierarchy(patterns);
assertEquals(6, tokenHierarchies.size());
assertThat(tokenHierarchies.get(0)).containsExactly("user", "legacy_user_blurb");
assertThat(tokenHierarchies.get(0)).containsExactly("user", "legacy_user", "blurb");
assertThat(tokenHierarchies.get(1)).containsExactly("user", "blurb");
assertThat(tokenHierarchies.get(2)).containsExactly("room", "blurb");
assertThat(tokenHierarchies.get(3)).containsExactly("user", "legacy_document_blurb");
assertThat(tokenHierarchies.get(4)).containsExactly("user", "legacy_book_blurb");
assertThat(tokenHierarchies.get(5)).containsExactly("room", "legacy_room_blurb");
assertThat(tokenHierarchies.get(3)).containsExactly("user", "legacy_document", "blurb");
assertThat(tokenHierarchies.get(4)).containsExactly("user", "legacy_book", "blurb");
assertThat(tokenHierarchies.get(5)).containsExactly("room", "legacy_room", "blurb");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import com.google.protobuf.Descriptors.ServiceDescriptor;
import com.google.pubsub.v1.PubsubProto;
import com.google.showcase.v1beta1.EchoOuterClass;
import com.google.showcase.v1beta1.TestingOuterClass;
import google.cloud.CommonResources;
import java.nio.file.Path;
import java.nio.file.Paths;
Expand Down Expand Up @@ -71,6 +72,36 @@ public void generateClientTest_echoClient() {
assertCodeEquals(goldenFilePath, visitor.write());
}

@Test
public void generateClientTest_testingClientResnameWithOnePatternWithNonSlashSepNames() {
FileDescriptor testingFileDescriptor = TestingOuterClass.getDescriptor();
ServiceDescriptor testingService = testingFileDescriptor.getServices().get(0);
assertEquals(testingService.getName(), "Testing");

Map<String, Message> messageTypes = Parser.parseMessages(testingFileDescriptor);
Map<String, ResourceName> resourceNames = Parser.parseResourceNames(testingFileDescriptor);
Set<ResourceName> outputResourceNames = new HashSet<>();
List<Service> services =
Parser.parseService(
testingFileDescriptor,
messageTypes,
resourceNames,
Optional.empty(),
outputResourceNames);

Service testingProtoService = services.get(0);
GapicClass clazz =
ServiceClientTestClassComposer.instance()
.generate(testingProtoService, resourceNames, messageTypes);

JavaWriterVisitor visitor = new JavaWriterVisitor();
clazz.classDefinition().accept(visitor);
Utils.saveCodegenToFile(this.getClass(), "TestingClientTest.golden", visitor.write());
Path goldenFilePath =
Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "TestingClientTest.golden");
assertCodeEquals(goldenFilePath, visitor.write());
}

@Test
public void generateClientTest_pubSubPublisherClient() {
FileDescriptor serviceFileDescriptor = PubsubProto.getDescriptor();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ import com.google.showcase.v1beta1.CreateSessionRequest;
import com.google.showcase.v1beta1.DeleteSessionRequest;
import com.google.showcase.v1beta1.DeleteTestRequest;
import com.google.showcase.v1beta1.GetSessionRequest;
import com.google.showcase.v1beta1.GetTestRequest;
import com.google.showcase.v1beta1.ListSessionsRequest;
import com.google.showcase.v1beta1.ListSessionsResponse;
import com.google.showcase.v1beta1.ListTestsRequest;
import com.google.showcase.v1beta1.ListTestsResponse;
import com.google.showcase.v1beta1.ReportSessionRequest;
import com.google.showcase.v1beta1.ReportSessionResponse;
import com.google.showcase.v1beta1.Session;
import com.google.showcase.v1beta1.Test;
import com.google.showcase.v1beta1.VerifyTestRequest;
import com.google.showcase.v1beta1.VerifyTestResponse;
import io.grpc.MethodDescriptor;
Expand Down Expand Up @@ -88,6 +90,14 @@ public class GrpcTestingStub extends TestingStub {
ProtoUtils.marshaller(ReportSessionResponse.getDefaultInstance()))
.build();

private static final MethodDescriptor<GetTestRequest, Test> getTestMethodDescriptor =
MethodDescriptor.<GetTestRequest, Test>newBuilder()
.setType(MethodDescriptor.MethodType.UNARY)
.setFullMethodName("google.showcase.v1beta1.Testing/GetTest")
.setRequestMarshaller(ProtoUtils.marshaller(GetTestRequest.getDefaultInstance()))
.setResponseMarshaller(ProtoUtils.marshaller(Test.getDefaultInstance()))
.build();

private static final MethodDescriptor<ListTestsRequest, ListTestsResponse>
listTestsMethodDescriptor =
MethodDescriptor.<ListTestsRequest, ListTestsResponse>newBuilder()
Expand Down Expand Up @@ -121,6 +131,7 @@ public class GrpcTestingStub extends TestingStub {
listSessionsPagedCallable;
private final UnaryCallable<DeleteSessionRequest, Empty> deleteSessionCallable;
private final UnaryCallable<ReportSessionRequest, ReportSessionResponse> reportSessionCallable;
private final UnaryCallable<GetTestRequest, Test> getTestCallable;
private final UnaryCallable<ListTestsRequest, ListTestsResponse> listTestsCallable;
private final UnaryCallable<ListTestsRequest, ListTestsPagedResponse> listTestsPagedCallable;
private final UnaryCallable<DeleteTestRequest, Empty> deleteTestCallable;
Expand Down Expand Up @@ -204,6 +215,19 @@ public class GrpcTestingStub extends TestingStub {
}
})
.build();
GrpcCallSettings<GetTestRequest, Test> getTestTransportSettings =
GrpcCallSettings.<GetTestRequest, Test>newBuilder()
.setMethodDescriptor(getTestMethodDescriptor)
.setParamsExtractor(
new RequestParamsExtractor<GetTestRequest>() {
@Override
public Map<String, String> extract(GetTestRequest request) {
ImmutableMap.Builder<String, String> params = ImmutableMap.builder();
params.put("name", String.valueOf(request.getName()));
return params.build();
}
})
.build();
GrpcCallSettings<ListTestsRequest, ListTestsResponse> listTestsTransportSettings =
GrpcCallSettings.<ListTestsRequest, ListTestsResponse>newBuilder()
.setMethodDescriptor(listTestsMethodDescriptor)
Expand Down Expand Up @@ -262,6 +286,9 @@ public class GrpcTestingStub extends TestingStub {
this.reportSessionCallable =
callableFactory.createUnaryCallable(
reportSessionTransportSettings, settings.reportSessionSettings(), clientContext);
this.getTestCallable =
callableFactory.createUnaryCallable(
getTestTransportSettings, settings.getTestSettings(), clientContext);
this.listTestsCallable =
callableFactory.createUnaryCallable(
listTestsTransportSettings, settings.listTestsSettings(), clientContext);
Expand Down Expand Up @@ -307,6 +334,10 @@ public class GrpcTestingStub extends TestingStub {
return reportSessionCallable;
}

public UnaryCallable<GetTestRequest, Test> getTestCallable() {
return getTestCallable;
}

public UnaryCallable<ListTestsRequest, ListTestsResponse> listTestsCallable() {
return listTestsCallable;
}
Expand Down
Loading