diff --git a/java/build.gradle b/java/build.gradle index 3919534..cd50678 100644 --- a/java/build.gradle +++ b/java/build.gradle @@ -12,7 +12,8 @@ dependencies { 'javax.servlet.jsp:javax.servlet.jsp-api:2.3.1', 'javax.el:javax.el-api:3.0.0', 'com.amazonaws:aws-lambda-java-core:1.1.0', - 'com.amazonaws:aws-lambda-java-log4j:1.0.0' + 'com.amazonaws:aws-lambda-java-log4j:1.0.0', + 'com.amazonaws:aws-xray-recorder-sdk-core:2.2.1' ) compile fileTree(dir: 'jars', include: '*.jar') } diff --git a/java/src/main/java/com/foundeo/fuseless/CFMLLambdaContainerHandler.java b/java/src/main/java/com/foundeo/fuseless/CFMLLambdaContainerHandler.java index 9a4a04a..6c907f3 100644 --- a/java/src/main/java/com/foundeo/fuseless/CFMLLambdaContainerHandler.java +++ b/java/src/main/java/com/foundeo/fuseless/CFMLLambdaContainerHandler.java @@ -30,6 +30,13 @@ import java.util.EnumSet; import java.util.Enumeration; import java.util.concurrent.CountDownLatch; +import java.util.HashMap; +import java.util.Map; + + +import com.amazonaws.xray.AWSXRay; +import com.amazonaws.xray.entities.Segment; +import com.amazonaws.xray.entities.Subsegment; import java.io.*; @@ -38,7 +45,7 @@ public class CFMLLambdaContainerHandler extends AwsLambdaServletContainerHandler { private static final Logger LOG = Logger.getLogger(CFMLLambdaContainerHandler.class); - + /** * Returns a new instance of an CFMLLambdaContainerHandler initialized to work with AwsProxyRequest * and AwsProxyResponse objects. @@ -60,6 +67,8 @@ public static CFMLLambdaContainerHandler getA newHandler.setLogFormatter(new ApacheCombinedServletLogFormatter<>()); + + return newHandler; } @@ -95,17 +104,50 @@ protected void handleRequest(AwsProxyHttpServletRequest httpServletRequest, AwsH httpServletRequest.setServletContext(new ServletContextWrapper(getServletContext())); RequestWrapper req = new RequestWrapper((javax.servlet.http.HttpServletRequest)httpServletRequest); req.setAttribute("lambdaContext", lambdaContext); + Object seg = null; try { + if (StreamLambdaHandler.ENABLE_XRAY) { + seg = AWSXRay.beginSubsegment("FuseLess " + req.getRequestURI()); + + Map requestAttributes = new HashMap(); + requestAttributes.put("url", req.getRequestURL().toString()); + requestAttributes.put("method", req.getMethod()); + String header = req.getHeader("User-Agent"); + if (header != null) { + requestAttributes.put("user_agent", header); + } + header = req.getHeader("X-Forwarded-For"); + if (header != null) { + header = header.split(",")[0].trim(); + requestAttributes.put("client_ip", header); + requestAttributes.put("x_forwarded_for", true); + } else { + if (req.getRemoteAddr() != null) { + requestAttributes.put("client_ip", req.getRemoteAddr()); + } + } + ((Subsegment)seg).putHttp("request", requestAttributes); + + } LOG.debug("CFMLLambdaContainerHandler handleRequest: " + req.getRequestURI()); StreamLambdaHandler.getCFMLServlet().service(req, httpServletResponse); + } catch (Throwable t) { t.printStackTrace(); + LOG.error("CFMLLambdaContainerHandler Servlet Request Threw Exception: "); LOG.error(t); for (StackTraceElement st: t.getStackTrace()) { LOG.error("STE:" + st.toString()); } + if (seg != null) { + ((Subsegment)seg).addException(t); + } + } finally { + if (StreamLambdaHandler.ENABLE_XRAY) { + AWSXRay.endSubsegment(); + } } } @@ -114,8 +156,5 @@ protected void handleRequest(AwsProxyHttpServletRequest httpServletRequest, AwsH public void initialize() throws ContainerInitializationException { - - - } } \ No newline at end of file diff --git a/java/src/main/java/com/foundeo/fuseless/ServletContextWrapper.java b/java/src/main/java/com/foundeo/fuseless/ServletContextWrapper.java index a0803a6..fe7ae24 100644 --- a/java/src/main/java/com/foundeo/fuseless/ServletContextWrapper.java +++ b/java/src/main/java/com/foundeo/fuseless/ServletContextWrapper.java @@ -136,7 +136,7 @@ public String getRealPath(String path) { @Override public String getServerInfo() { - return this.servletContext.getServerInfo() + "; Foundeo FuseLess v0.0.7"; + return this.servletContext.getServerInfo() + "; Foundeo FuseLess v0.0.8"; } @Override diff --git a/java/src/main/java/com/foundeo/fuseless/StreamLambdaHandler.java b/java/src/main/java/com/foundeo/fuseless/StreamLambdaHandler.java index d8abdff..0f91d9a 100644 --- a/java/src/main/java/com/foundeo/fuseless/StreamLambdaHandler.java +++ b/java/src/main/java/com/foundeo/fuseless/StreamLambdaHandler.java @@ -27,6 +27,10 @@ import javax.servlet.*; import javax.servlet.http.HttpServlet; +import com.amazonaws.xray.AWSXRay; +import com.amazonaws.xray.entities.Subsegment; +import com.amazonaws.xray.entities.Segment; + import lucee.loader.servlet.CFMLServlet; @@ -37,9 +41,13 @@ public class StreamLambdaHandler implements RequestStreamHandler { private static HttpServlet cfmlServlet = null; + public static boolean ENABLE_XRAY = false; + static { try { - + if (System.getenv("FUSELESS_ENABLE_XRAY") != null && System.getenv("FUSELESS_ENABLE_XRAY").equals("true")) { + ENABLE_XRAY = true; + } LOG.info("StreamLambdaHandler initializing"); handler = CFMLLambdaContainerHandler.getAwsProxyHandler(); @@ -106,7 +114,10 @@ public void write(int b) { } catch (ContainerInitializationException e) { // if we fail here. We re-throw the exception to force another cold start e.printStackTrace(); + throw new RuntimeException("StreamLambdaHandler Could not initialize the container", e); + } finally { + } } @@ -121,7 +132,6 @@ public StreamLambdaHandler() { @Override public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException { - FuseLessContext ctx = new FuseLessContext(context); handler.proxyStream(inputStream, outputStream, ctx); } diff --git a/test.sh b/test.sh index 8b44412..c6c893e 100755 --- a/test.sh +++ b/test.sh @@ -10,6 +10,7 @@ else #download lucee jar echo "Downloading lucee-light-$LUCEE_VERSION.jar" curl --location -o java/jars/lucee-light-$LUCEE_VERSION.jar https://cdn.lucee.org/lucee-light-$LUCEE_VERSION.jar + cp java/jars/lucee-light-$LUCEE_VERSION.jar test/jars/ fi @@ -20,8 +21,6 @@ gradle build cd .. -cp java/jars/lucee-light-$LUCEE_VERSION.jar test/jars/ - cp java/build/libs/foundeo-fuseless.jar test/jars/ cd test @@ -38,8 +37,8 @@ echo -e "Sleeping for 5...\n" sleep 5 -echo "Running: http://127.0.0.1:3003/test.cfm" -http_code=$(curl --verbose -s --header "Content-Type: application/json" --request POST --data '{"x":1}' -o /tmp/result.txt -w '%{http_code}' http://127.0.0.1:3003/test.cfm;) +echo "Running: http://127.0.0.1:3003/assert.cfm" +http_code=$(curl --verbose -s --header "Content-Type: application/json" --request POST --data '{"x":1}' -o /tmp/result.txt -w '%{http_code}' 'http://127.0.0.1:3003/assert.cfm?requestMethod=POST&requestContentType=application/json&requestBody=%7B%22x%22%3A1%7D';) echo "Finished with Status: $http_code " echo -e "\n-----\n" #output the result @@ -49,20 +48,28 @@ echo -e "\n-----\n" kill $SAM_PID -#echo "Testing Events" +if [ "$http_code" -ne 222 ]; then + #fail if status code is not 200 + exit 1 +fi + + + + +echo "Testing Events" +echo -e "\n-----\n" sam local generate-event s3 put > /tmp/test-event.json sam local invoke FuselessTestEvent --event /tmp/test-event.json +echo -e "\n-----\n" + + -if [ "$http_code" -eq 200 ]; then - exit 0 -fi -#fail if status code is not 200 -exit 1 +exit 0 diff --git a/test/cfml/app/Application.cfc b/test/cfml/app/Application.cfc index cce0bc8..c3120ca 100644 --- a/test/cfml/app/Application.cfc +++ b/test/cfml/app/Application.cfc @@ -6,10 +6,7 @@ component { this.setClientCookies=false; public function onRequest(string path) { - - writeOutput("AWS Request ID: #getLambdaContext().getAwsRequestId()# #cgi.request_method# Lucee #server.lucee.version#"); - - //logger("Testing Logger"); + include path; } public function getLambdaContext() { @@ -21,4 +18,9 @@ component { getLambdaContext().getLogger().log(arguments.msg); } + public function onError(err) { + writeOutput("ERROR: #err.message# - #err.detail# #err.stacktrace#"); + logger(err.message & " - " & err.detail); + } + } \ No newline at end of file diff --git a/test/cfml/app/assert.cfm b/test/cfml/app/assert.cfm new file mode 100644 index 0000000..dc210ab --- /dev/null +++ b/test/cfml/app/assert.cfm @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + +
+	#assert("cgi.request_method", url.requestMethod, cgi.request_method)#
+	#assert("requestBody", url.requestBody, reqData.content)#
+	#assert("Content-Type", url.requestContentType, contentType)#
+	
+
+
+ + + + + + + + + + function assert(name, expected, actual) { + var msg = "#name# Expected: #expected#, Actual: #actual#"; + if (expected != actual) { + cfheader(statuscode="520", statustext="Test Failed"); + msg = "[FAIL] " & msg; + } else { + msg = "[PASS] " & msg; + } + return msg; + } + \ No newline at end of file diff --git a/test/cfml/app/test.cfc b/test/cfml/app/test.cfc new file mode 100644 index 0000000..1fd06f0 --- /dev/null +++ b/test/cfml/app/test.cfc @@ -0,0 +1,15 @@ +component { + + remote numeric function add(numeric x, numeric y) { + return x+y; + } + + remote string function assertHTTPRequestMethod(string expectedMethod="") { + var msg = "Expected #expectedMethod#, cgi.request_method=#cgi.request_method#"; + if (cgi.request_method != arguments.expectedMethod) { + cfheader(statuscode="405", statustext=msg); + } + return msg; + } + +} \ No newline at end of file diff --git a/test/cfml/app/test.cfm b/test/cfml/app/test.cfm new file mode 100644 index 0000000..149983d --- /dev/null +++ b/test/cfml/app/test.cfm @@ -0,0 +1 @@ +Hello #server.lucee.version# \ No newline at end of file