/* * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ using Amazon.Lambda.Core; using System; using System.IO; using System.Threading.Tasks; namespace Amazon.Lambda.RuntimeSupport { /// /// This class provides methods that help you wrap existing C# Lambda implementations with LambdaBootstrapHandler delegates. /// This makes serialization and deserialization simpler and allows you to use existing functions them with an instance of LambdaBootstrap. /// public class HandlerWrapper : IDisposable { private static readonly InvocationResponse EmptyInvocationResponse = new InvocationResponse(new MemoryStream(0), false); private MemoryStream OutputStream = new MemoryStream(); public LambdaBootstrapHandler Handler { get; private set; } private HandlerWrapper(LambdaBootstrapHandler handler) { Handler = handler; } private HandlerWrapper() { } /// /// Get a HandlerWrapper that will call the given delegate on function invocation. /// /// Action called for each invocation of the Lambda function /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Action invokeDelegate) { var handlerWrapper = new HandlerWrapper(); handlerWrapper.Handler = invocation => { handlerWrapper.OutputStream.SetLength(0); invokeDelegate(invocation.InputStream, invocation.LambdaContext, handlerWrapper.OutputStream); handlerWrapper.OutputStream.Position = 0; var response = new InvocationResponse(handlerWrapper.OutputStream, false); return Task.FromResult(response); }; return handlerWrapper; } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: Task Handler(); /// /// Func called for each invocation of the Lambda function. /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func handler) { return new HandlerWrapper(async (invocation) => { await handler(); return EmptyInvocationResponse; }); } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: Task Handler(Stream) /// /// Func called for each invocation of the Lambda function. /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func handler) { return new HandlerWrapper(async (invocation) => { await handler(invocation.InputStream); return EmptyInvocationResponse; }); } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: Task Handler(PocoIn) /// /// Func called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func handler, ILambdaSerializer serializer) { return new HandlerWrapper(async (invocation) => { TInput input = serializer.Deserialize(invocation.InputStream); await handler(input); return EmptyInvocationResponse; }); } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: Task Handler(ILambdaContext) /// /// Func called for each invocation of the Lambda function. /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func handler) { return new HandlerWrapper(async (invocation) => { await handler(invocation.LambdaContext); return EmptyInvocationResponse; }); } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: Task Handler(Stream, ILambdaContext) /// /// Func called for each invocation of the Lambda function. /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func handler) { return new HandlerWrapper(async (invocation) => { await handler(invocation.InputStream, invocation.LambdaContext); return EmptyInvocationResponse; }); } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: Task Handler(PocoIn, ILambdaContext) /// /// Func called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func handler, ILambdaSerializer serializer) { return new HandlerWrapper(async (invocation) => { TInput input = serializer.Deserialize(invocation.InputStream); await handler(input, invocation.LambdaContext); return EmptyInvocationResponse; }); } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: Task<Stream> Handler() /// /// Func called for each invocation of the Lambda function. /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func> handler) { return new HandlerWrapper(async (invocation) => { return new InvocationResponse(await handler()); }); } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: Task<Stream> Handler(Stream) /// /// Func called for each invocation of the Lambda function. /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func> handler) { return new HandlerWrapper(async (invocation) => { return new InvocationResponse(await handler(invocation.InputStream)); }); } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: Task<Stream> Handler(PocoIn) /// /// Func called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func> handler, ILambdaSerializer serializer) { return new HandlerWrapper(async (invocation) => { TInput input = serializer.Deserialize(invocation.InputStream); return new InvocationResponse(await handler(input)); }); } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: Task<Stream> Handler(ILambdaContext) /// /// Func called for each invocation of the Lambda function. /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func> handler) { return new HandlerWrapper(async (invocation) => { return new InvocationResponse(await handler(invocation.LambdaContext)); }); } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: Task<Stream> Handler(Stream, ILambdaContext) /// /// Func called for each invocation of the Lambda function. /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func> handler) { return new HandlerWrapper(async (invocation) => { return new InvocationResponse(await handler(invocation.InputStream, invocation.LambdaContext)); }); } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: Task<Stream> Handler(PocoIn, ILambdaContext) /// /// Func called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func> handler, ILambdaSerializer serializer) { return new HandlerWrapper(async (invocation) => { TInput input = serializer.Deserialize(invocation.InputStream); return new InvocationResponse(await handler(input, invocation.LambdaContext)); }); } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: Task<PocoOut> Handler() /// /// Func called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func> handler, ILambdaSerializer serializer) { var handlerWrapper = new HandlerWrapper(); handlerWrapper.Handler = async (invocation) => { TOutput output = await handler(); handlerWrapper.OutputStream.SetLength(0); serializer.Serialize(output, handlerWrapper.OutputStream); handlerWrapper.OutputStream.Position = 0; return new InvocationResponse(handlerWrapper.OutputStream, false); }; return handlerWrapper; } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: Task<PocoOut> Handler(Stream) /// /// Func called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func> handler, ILambdaSerializer serializer) { var handlerWrapper = new HandlerWrapper(); handlerWrapper.Handler = async (invocation) => { TOutput output = await handler(invocation.InputStream); handlerWrapper.OutputStream.SetLength(0); serializer.Serialize(output, handlerWrapper.OutputStream); handlerWrapper.OutputStream.Position = 0; return new InvocationResponse(handlerWrapper.OutputStream, false); }; return handlerWrapper; } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: Task<PocoOut> Handler(PocoIn) /// /// Func called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func> handler, ILambdaSerializer serializer) { var handlerWrapper = new HandlerWrapper(); handlerWrapper.Handler = async (invocation) => { TInput input = serializer.Deserialize(invocation.InputStream); TOutput output = await handler(input); handlerWrapper.OutputStream.SetLength(0); serializer.Serialize(output, handlerWrapper.OutputStream); handlerWrapper.OutputStream.Position = 0; return new InvocationResponse(handlerWrapper.OutputStream, false); }; return handlerWrapper; } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: Task<PocoOut> Handler(ILambdaContext) /// /// Func called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func> handler, ILambdaSerializer serializer) { var handlerWrapper = new HandlerWrapper(); handlerWrapper.Handler = async (invocation) => { TOutput output = await handler(invocation.LambdaContext); handlerWrapper.OutputStream.SetLength(0); serializer.Serialize(output, handlerWrapper.OutputStream); handlerWrapper.OutputStream.Position = 0; ; return new InvocationResponse(handlerWrapper.OutputStream, false); }; return handlerWrapper; } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: Task<PocoOut> Handler(Stream, ILambdaContext) /// /// Func called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func> handler, ILambdaSerializer serializer) { var handlerWrapper = new HandlerWrapper(); handlerWrapper.Handler = async (invocation) => { TOutput output = await handler(invocation.InputStream, invocation.LambdaContext); handlerWrapper.OutputStream.SetLength(0); serializer.Serialize(output, handlerWrapper.OutputStream); handlerWrapper.OutputStream.Position = 0; return new InvocationResponse(handlerWrapper.OutputStream, false); }; return handlerWrapper; } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: Task<PocoOut> Handler(PocoIn, ILambdaContext) /// /// Func called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func> handler, ILambdaSerializer serializer) { var handlerWrapper = new HandlerWrapper(); handlerWrapper.Handler = async (invocation) => { TInput input = serializer.Deserialize(invocation.InputStream); TOutput output = await handler(input, invocation.LambdaContext); handlerWrapper.OutputStream.SetLength(0); serializer.Serialize(output, handlerWrapper.OutputStream); handlerWrapper.OutputStream.Position = 0; return new InvocationResponse(handlerWrapper.OutputStream, false); }; return handlerWrapper; } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: void Handler() /// /// Action called for each invocation of the Lambda function. /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Action handler) { return new HandlerWrapper((invocation) => { handler(); return Task.FromResult(EmptyInvocationResponse); }); } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: void Handler(Stream) /// /// Action called for each invocation of the Lambda function. /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Action handler) { return new HandlerWrapper((invocation) => { handler(invocation.InputStream); return Task.FromResult(EmptyInvocationResponse); }); } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: void Handler(PocoIn) /// /// Action called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Action handler, ILambdaSerializer serializer) { return new HandlerWrapper((invocation) => { TInput input = serializer.Deserialize(invocation.InputStream); handler(input); return Task.FromResult(EmptyInvocationResponse); }); } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: void Handler(ILambdaContext) /// /// Action called for each invocation of the Lambda function. /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Action handler) { return new HandlerWrapper((invocation) => { handler(invocation.LambdaContext); return Task.FromResult(EmptyInvocationResponse); }); } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: void Handler(Stream, ILambdaContext) /// /// Action called for each invocation of the Lambda function. /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Action handler) { return new HandlerWrapper((invocation) => { handler(invocation.InputStream, invocation.LambdaContext); return Task.FromResult(EmptyInvocationResponse); }); } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: void Handler(PocoIn, ILambdaContext) /// /// Action called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Action handler, ILambdaSerializer serializer) { return new HandlerWrapper((invocation) => { TInput input = serializer.Deserialize(invocation.InputStream); handler(input, invocation.LambdaContext); return Task.FromResult(EmptyInvocationResponse); }); } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: Stream Handler() /// /// Func called for each invocation of the Lambda function. /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func handler) { return new HandlerWrapper((invocation) => { return Task.FromResult(new InvocationResponse(handler())); }); } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: Stream Handler(Stream) /// /// Func called for each invocation of the Lambda function. /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func handler) { return new HandlerWrapper((invocation) => { return Task.FromResult(new InvocationResponse(handler(invocation.InputStream))); }); } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: Stream Handler(PocoIn) /// /// Func called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func handler, ILambdaSerializer serializer) { return new HandlerWrapper((invocation) => { TInput input = serializer.Deserialize(invocation.InputStream); return Task.FromResult(new InvocationResponse(handler(input))); }); } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: Stream Handler(ILambdaContext) /// /// Func called for each invocation of the Lambda function. /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func handler) { return new HandlerWrapper((invocation) => { return Task.FromResult(new InvocationResponse(handler(invocation.LambdaContext))); }); } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: Stream Handler(PocoIn, ILambdaContext) /// /// Func called for each invocation of the Lambda function. /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func handler) { return new HandlerWrapper((invocation) => { return Task.FromResult(new InvocationResponse(handler(invocation.InputStream, invocation.LambdaContext))); }); } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: Stream Handler(PocoIn, ILambdaContext) /// /// Func called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func handler, ILambdaSerializer serializer) { return new HandlerWrapper((invocation) => { TInput input = serializer.Deserialize(invocation.InputStream); return Task.FromResult(new InvocationResponse(handler(input, invocation.LambdaContext))); }); } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: PocoOut Handler() /// /// Func called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func handler, ILambdaSerializer serializer) { var handlerWrapper = new HandlerWrapper(); handlerWrapper.Handler = (invocation) => { TOutput output = handler(); handlerWrapper.OutputStream.SetLength(0); serializer.Serialize(output, handlerWrapper.OutputStream); handlerWrapper.OutputStream.Position = 0; return Task.FromResult(new InvocationResponse(handlerWrapper.OutputStream, false)); }; return handlerWrapper; } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: PocoOut Handler(Stream) /// /// Func called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func handler, ILambdaSerializer serializer) { var handlerWrapper = new HandlerWrapper(); handlerWrapper.Handler = (invocation) => { TOutput output = handler(invocation.InputStream); handlerWrapper.OutputStream.SetLength(0); serializer.Serialize(output, handlerWrapper.OutputStream); handlerWrapper.OutputStream.Position = 0; return Task.FromResult(new InvocationResponse(handlerWrapper.OutputStream, false)); }; return handlerWrapper; } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: PocoOut Handler(PocoIn) /// /// Func called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func handler, ILambdaSerializer serializer) { var handlerWrapper = new HandlerWrapper(); handlerWrapper.Handler = (invocation) => { TInput input = serializer.Deserialize(invocation.InputStream); TOutput output = handler(input); handlerWrapper.OutputStream.SetLength(0); serializer.Serialize(output, handlerWrapper.OutputStream); handlerWrapper.OutputStream.Position = 0; return Task.FromResult(new InvocationResponse(handlerWrapper.OutputStream, false)); }; return handlerWrapper; } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: PocoOut Handler(ILambdaContext) /// /// Func called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func handler, ILambdaSerializer serializer) { var handlerWrapper = new HandlerWrapper(); handlerWrapper.Handler = (invocation) => { TOutput output = handler(invocation.LambdaContext); handlerWrapper.OutputStream.SetLength(0); serializer.Serialize(output, handlerWrapper.OutputStream); handlerWrapper.OutputStream.Position = 0; ; return Task.FromResult(new InvocationResponse(handlerWrapper.OutputStream, false)); }; return handlerWrapper; } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: PocoOut Handler(Stream, ILambdaContext) /// /// Func called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func handler, ILambdaSerializer serializer) { var handlerWrapper = new HandlerWrapper(); handlerWrapper.Handler = (invocation) => { TOutput output = handler(invocation.InputStream, invocation.LambdaContext); handlerWrapper.OutputStream.SetLength(0); serializer.Serialize(output, handlerWrapper.OutputStream); handlerWrapper.OutputStream.Position = 0; return Task.FromResult(new InvocationResponse(handlerWrapper.OutputStream, false)); }; return handlerWrapper; } /// /// Get a HandlerWrapper that will call the given method on function invocation. /// Note that you may have to cast your handler to its specific type to help the compiler. /// Example handler signature: PocoOut Handler(PocoIn, ILambdaContext) /// /// Func called for each invocation of the Lambda function. /// ILambdaSerializer to use when calling the handler /// A HandlerWrapper public static HandlerWrapper GetHandlerWrapper(Func handler, ILambdaSerializer serializer) { var handlerWrapper = new HandlerWrapper(); handlerWrapper.Handler = (invocation) => { TInput input = serializer.Deserialize(invocation.InputStream); TOutput output = handler(input, invocation.LambdaContext); handlerWrapper.OutputStream.SetLength(0); serializer.Serialize(output, handlerWrapper.OutputStream); handlerWrapper.OutputStream.Position = 0; return Task.FromResult(new InvocationResponse(handlerWrapper.OutputStream, false)); }; return handlerWrapper; } #region IDisposable Support private bool disposedValue = false; // To detect redundant calls protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { OutputStream.Dispose(); } disposedValue = true; } } public void Dispose() { Dispose(true); } #endregion } }