Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#4750 Java invoke local support for handlers that implement RequestStreamHandler #5954

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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ node_modules
# IDE stuff # IDE stuff
**/.idea **/.idea
**/.vs **/.vs
**/*.iml


# OS stuff # OS stuff
.DS_Store .DS_Store
Expand Down
2 changes: 1 addition & 1 deletion lib/plugins/aws/invokeLocal/index.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ class AwsInvokeLocal {
`-DclassName=${className}`, `-DclassName=${className}`,
`-DhandlerName=${handlerName}`, `-DhandlerName=${handlerName}`,
'-jar', '-jar',
path.join(__dirname, 'java', 'target', 'invoke-bridge-1.0.jar'), path.join(__dirname, 'java', 'target', 'invoke-bridge-1.0.1.jar'),
], { shell: true }); ], { shell: true });


this.serverless.cli.log([ this.serverless.cli.log([
Expand Down
8 changes: 7 additions & 1 deletion lib/plugins/aws/invokeLocal/java/pom.xml
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@


<groupId>com.serverless</groupId> <groupId>com.serverless</groupId>
<artifactId>invoke-bridge</artifactId> <artifactId>invoke-bridge</artifactId>
<version>1.0</version> <version>1.0.1</version>


<properties> <properties>
<maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.source>1.8</maven.compiler.source>
Expand Down Expand Up @@ -39,6 +39,12 @@
<artifactId>jackson-annotations</artifactId> <artifactId>jackson-annotations</artifactId>
<version>2.8.5</version> <version>2.8.5</version>
</dependency> </dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>


<build> <build>
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@
import java.beans.Introspector; import java.beans.Introspector;
import java.beans.PropertyDescriptor; import java.beans.PropertyDescriptor;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.URL; import java.net.URL;
Expand All @@ -33,7 +36,16 @@ private InvokeBridge() {


this.instance = this.getInstance(); this.instance = this.getInstance();


System.out.println(this.invoke(eventMap, this.getContext(parsedInput)).toString()); Object output = this.invoke(eventMap, this.getContext(parsedInput));
String string = null;
if(output != null) {
if(output.getClass().isAssignableFrom(ByteArrayOutputStream.class)){
string = new String(((ByteArrayOutputStream)output).toByteArray());
}else {
string = output.toString();
}
}
System.out.println(string);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
Expand Down Expand Up @@ -64,7 +76,8 @@ private Object invoke(HashMap<String, Object> event, Context context) throws Exc
Class requestClass = method.getParameterTypes()[0]; Class requestClass = method.getParameterTypes()[0];


Object request = event; Object request = event;
if (!requestClass.isAssignableFrom(event.getClass())) { if (!requestClass.isAssignableFrom(event.getClass())
&& !requestClass.isAssignableFrom(InputStream.class)) {
request = requestClass.newInstance(); request = requestClass.newInstance();
PropertyDescriptor[] properties = Introspector.getBeanInfo(requestClass).getPropertyDescriptors(); PropertyDescriptor[] properties = Introspector.getBeanInfo(requestClass).getPropertyDescriptors();
for(int i=0; i < properties.length; i++) { for(int i=0; i < properties.length; i++) {
Expand All @@ -80,8 +93,13 @@ private Object invoke(HashMap<String, Object> event, Context context) throws Exc
return method.invoke(this.instance, request); return method.invoke(this.instance, request);
} else if (method.getParameterCount() == 2) { } else if (method.getParameterCount() == 2) {
return method.invoke(this.instance, request, context); return method.invoke(this.instance, request, context);
} else if (method.getParameterCount() == 3 && requestClass.isAssignableFrom(InputStream.class)) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ByteArrayInputStream inputStream = new ByteArrayInputStream(new ObjectMapper().writeValueAsBytes(event));
method.invoke(this.instance, inputStream, outputStream, context);
return outputStream;
} else { } else {
throw new NoSuchMethodException("Handler should take 1 or 2 arguments: " + method); throw new NoSuchMethodException("Handler should take 1, 2, or 3 (com.amazonaws.services.lambda.runtime.RequestStreamHandler compatible handlers) arguments: " + method);
} }
} }


Expand Down Expand Up @@ -110,7 +128,7 @@ private Method findHandlerMethod(Class clazz, String handlerName) throws Excepti


private HashMap<String, Object> parseInput(String input) throws IOException { private HashMap<String, Object> parseInput(String input) throws IOException {
TypeReference<HashMap<String,Object>> typeRef = new TypeReference<HashMap<String,Object>>() {}; TypeReference<HashMap<String,Object>> typeRef = new TypeReference<HashMap<String,Object>>() {};
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper().findAndRegisterModules();


JsonNode jsonNode = mapper.readTree(input); JsonNode jsonNode = mapper.readTree(input);


Expand All @@ -125,7 +143,6 @@ private String getInput() throws IOException {
while ((inputStr = streamReader.readLine()) != null) { while ((inputStr = streamReader.readLine()) != null) {
inputStringBuilder.append(inputStr); inputStringBuilder.append(inputStr);
} }

return inputStringBuilder.toString(); return inputStringBuilder.toString();
} }


Expand Down
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.serverless;

import static org.junit.Assert.assertNotNull;

import org.junit.Before;
import org.junit.Test;

public class InvokeBridgeTest {
@Before
public void before() {
System.setProperty("artifactPath", "target/test-classes/com/serverless/RequestStreamHandler.class");
System.setProperty("className", "com.serverless.RequestStreamHandler");
System.setProperty("handlerName", "handleRequest");
}

@Test
public void verifyInvoke() {
System.setIn(getClass().getResourceAsStream("/test.json"));
InvokeBridge.main(new String[] {});
assertNotNull(RequestStreamHandler.input);
}
}
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.serverless;

import java.util.Map;

import com.amazonaws.services.lambda.runtime.Context;

public class RequestHandler
implements com.amazonaws.services.lambda.runtime.RequestHandler<Map<String,Object>, Object> {

@Override
public Object handleRequest(Map<String, Object> stringObjectMap, Context context) {
return "Complete.";
}
}
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.serverless;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.Map;

import com.amazonaws.services.lambda.runtime.Context;
import com.fasterxml.jackson.databind.ObjectMapper;

public class RequestStreamHandler implements com.amazonaws.services.lambda.runtime.RequestStreamHandler {
static Map<String, Object> input;
@Override
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
ObjectMapper objectMapper = new ObjectMapper().findAndRegisterModules();
input = objectMapper.readValue(inputStream, Map.class);
System.out.println("Input received:" + input);
objectMapper.writeValue(outputStream, new TestPojo("RequestStreamHandler invoke complete."));
}

static private class TestPojo implements Serializable {
private final static Long serialVersionUID = 1L;
private final String message;

public TestPojo(String message) {
this.message = message;
}

public String getMessage() {
return message;
}
}
}
37 changes: 37 additions & 0 deletions lib/plugins/aws/invokeLocal/java/src/test/resources/test.json
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"context": {},
"event": {
"body": "{\"test\":\"data\"}",
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"cache-control": "no-cache",
"CloudFront-Forwarded-Proto": "https",
"CloudFront-Is-Desktop-Viewer": "true",
"CloudFront-Is-Mobile-Viewer": "false",
"CloudFront-Is-SmartTV-Viewer": "false",
"CloudFront-Is-Tablet-Viewer": "false",
"CloudFront-Viewer-Country": "KR",
"Host": "rr4lbbmtfb.execute-api.us-east-1.amazonaws.com",
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Old test dev APP id -- no longer valid.

"Postman-Token": "60d4d786-60bf-4ba5-bcde-5a00ac688041",
"User-Agent": "PostmanRuntime/7.3.0",
"Via": "1.1 17b1095550a8ffe13061114dbfceeb81.cloudfront.net (CloudFront)",
"X-Amz-Cf-Id": "QK3FgYHC89HWK03RsV7L8lJv34WzlFDyHmS0pbbCYtz9WyUCiw7JCQ==",
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Old test dev CF id -- no longer valid.

"X-Amzn-Trace-Id": "Root=1-5c93c7ca-1f19d2028476793a98d5e844",
"X-Forwarded-For": "211.229.207.20, 52.46.53.147",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https"
},
"httpMethod": "GET",
"base64Encoded": false,
"path": "/version/12345",
"pathParameters": {
"incomingClientVersion": "12345"
},
"queryStringParameters": {
"asdasd": "123123"
},
"stageVariables": null,
"resource": "/version/{incomingClientVersion}"
}
}