Skip to content

Commit ee214a4

Browse files
committed
Import of Cloud Functions JVM from Git-on-Borg.
- c1328f640791a360d414deccb47f873a76dee171 Merge "Improve coverage of packageless and nested functio... by Éamonn McManus <[email protected]> - 52bae0b45618d9f3bd19b8f97acbcbb5690293ad Clean up the invoker-runner pom.xml. by Éamonn McManus <[email protected]> - 8c9223dc6ddba8e639f23f85dfe9e607c703fc33 Explicitly set source level in example. by Éamonn McManus <[email protected]> - f573a69eb1588502330c8775f0dd9a11364e556b Update example to reflect the new API. by Éamonn McManus <[email protected]> PiperOrigin-RevId: 280075940
1 parent 84a2f6d commit ee214a4

File tree

4 files changed

+72
-15
lines changed

4 files changed

+72
-15
lines changed

invoker-core/src/main/java/com/google/cloud/functions/invoker/NewHttpFunctionExecutor.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,20 @@ private NewHttpFunctionExecutor(HttpFunction function) {
3333
*/
3434
public static Optional<NewHttpFunctionExecutor> forTarget(String target) {
3535
Class<?> c;
36-
try {
37-
c = Class.forName(target);
38-
} catch (ClassNotFoundException e) {
39-
return Optional.empty();
36+
while (true) {
37+
try {
38+
c = Class.forName(target);
39+
break;
40+
} catch (ClassNotFoundException e) {
41+
// This might be a nested class like com.example.Foo.Bar. That will actually appear as
42+
// com.example.Foo$Bar as far as Class.forName is concerned. So we try to replace every dot
43+
// from the last to the first with a $ in the hope of finding a class we can load.
44+
int lastDot = target.lastIndexOf('.');
45+
if (lastDot < 0) {
46+
return Optional.empty();
47+
}
48+
target = target.substring(0, lastDot) + '$' + target.substring(lastDot + 1);
49+
}
4050
}
4151
if (!HttpFunction.class.isAssignableFrom(c)) {
4252
throw new RuntimeException(
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// A function in the default package.
2+
3+
import com.google.cloud.functions.HttpFunction;
4+
import com.google.cloud.functions.HttpRequest;
5+
import com.google.cloud.functions.HttpResponse;
6+
7+
public class PackagelessHelloWorld implements HttpFunction {
8+
@Override
9+
public void service(HttpRequest request, HttpResponse response) throws Exception {
10+
response.setContentType("text/plain; charset=utf-8");
11+
response.getWriter().write("hello, world\n");
12+
}
13+
}

invoker-core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -87,29 +87,33 @@ abstract static class Builder {
8787
}
8888
}
8989

90+
private static String fullTarget(String nameWithoutPackage) {
91+
return "com.google.cloud.functions.invoker.testfunctions." + nameWithoutPackage;
92+
}
93+
9094
@Test
9195
public void helloWorld() throws Exception {
92-
testHttpFunction("HelloWorld.helloWorld",
96+
testHttpFunction(fullTarget("HelloWorld.helloWorld"),
9397
TestCase.builder().setExpectedResponseText("hello\n").build());
9498
}
9599

96100
@Test
97101
public void newHelloWorld() throws Exception {
98-
testHttpFunction("NewHelloWorld",
102+
testHttpFunction(fullTarget("NewHelloWorld"),
99103
TestCase.builder().setExpectedResponseText("hello\n").build());
100104
}
101105

102106
@Test
103107
public void echo() throws Exception {
104108
String testText = "hello\nworld\n";
105-
testHttpFunction("Echo.echo",
109+
testHttpFunction(fullTarget("Echo.echo"),
106110
TestCase.builder().setRequestText(testText).setExpectedResponseText(testText).build());
107111
}
108112

109113
@Test
110114
public void newEcho() throws Exception {
111115
String testText = "hello\nworld\n";
112-
testHttpFunction("NewEcho",
116+
testHttpFunction(fullTarget("NewEcho"),
113117
TestCase.builder().setRequestText(testText).setExpectedResponseText(testText).build());
114118
}
115119

@@ -119,7 +123,7 @@ public void echoUrl() throws Exception {
119123
TestCase[] testCases = Arrays.stream(testUrls)
120124
.map(url -> TestCase.builder().setUrl(url).setExpectedResponseText(url + "\n").build())
121125
.toArray(TestCase[]::new);
122-
testHttpFunction("EchoUrl.echoUrl", testCases);
126+
testHttpFunction(fullTarget("EchoUrl.echoUrl"), testCases);
123127
}
124128

125129
@Test
@@ -128,22 +132,35 @@ public void newEchoUrl() throws Exception {
128132
TestCase[] testCases = Arrays.stream(testUrls)
129133
.map(url -> TestCase.builder().setUrl(url).setExpectedResponseText(url + "\n").build())
130134
.toArray(TestCase[]::new);
131-
testHttpFunction("NewEchoUrl", testCases);
135+
testHttpFunction(fullTarget("NewEchoUrl"), testCases);
132136
}
133137

134138
@Test
135139
public void background() throws Exception {
136-
backgroundTest("BackgroundSnoop.snoop");
140+
backgroundTest(fullTarget("BackgroundSnoop.snoop"));
137141
}
138142

139143
@Test
140144
public void newBackground() throws Exception {
141-
backgroundTest("NewBackgroundSnoop");
145+
backgroundTest(fullTarget("NewBackgroundSnoop"));
142146
}
143147

144148
@Test
145149
public void newTypedBackground() throws Exception {
146-
backgroundTest("NewTypedBackgroundSnoop");
150+
backgroundTest(fullTarget("NewTypedBackgroundSnoop"));
151+
}
152+
153+
@Test
154+
public void nested() throws Exception {
155+
String testText = "sic transit gloria mundi";
156+
testHttpFunction(fullTarget("Nested.Echo"),
157+
TestCase.builder().setRequestText(testText).setExpectedResponseText(testText).build());
158+
}
159+
160+
@Test
161+
public void packageless() throws Exception {
162+
testHttpFunction("PackagelessHelloWorld",
163+
TestCase.builder().setExpectedResponseText("hello, world\n").build());
147164
}
148165

149166
// In these tests, we test a number of different functions that express the same functionality
@@ -218,7 +235,6 @@ public String toString() {
218235

219236
private Process startServer(SignatureType signatureType, String target)
220237
throws IOException, InterruptedException {
221-
String fullTarget = "com.google.cloud.functions.invoker.testfunctions." + target;
222238
File javaHome = new File(System.getProperty("java.home"));
223239
assertThat(javaHome.exists()).isTrue();
224240
File javaBin = new File(javaHome, "bin");
@@ -235,7 +251,7 @@ private Process startServer(SignatureType signatureType, String target)
235251
Map<String, String> environment = ImmutableMap.of("PORT", String.valueOf(serverPort),
236252
"K_SERVICE", "test-function",
237253
"FUNCTION_SIGNATURE_TYPE", signatureType.toString(),
238-
"FUNCTION_TARGET", fullTarget);
254+
"FUNCTION_TARGET", target);
239255
processBuilder.environment().putAll(environment);
240256
Process serverProcess = processBuilder.start();
241257
CountDownLatch ready = new CountDownLatch(1);
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.google.cloud.functions.invoker.testfunctions;
2+
3+
import com.google.cloud.functions.HttpFunction;
4+
import com.google.cloud.functions.HttpRequest;
5+
import com.google.cloud.functions.HttpResponse;
6+
import java.util.stream.Collectors;
7+
8+
public class Nested {
9+
public static class Echo implements HttpFunction {
10+
@Override
11+
public void service(HttpRequest request, HttpResponse response) throws Exception {
12+
String body = request.getReader().lines().collect(Collectors.joining("\n"));
13+
response.setContentType("text/plain");
14+
response.getWriter().write(body);
15+
response.getWriter().flush();
16+
}
17+
}
18+
}

0 commit comments

Comments
 (0)