Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Integrating Google Guice in AWS Lambda

I'm trying to integrate Google Guice in AWS Lambda but for some reasons, injection is not working well. It give me null whenever i try to call

Handler Code:

public class FirstLamdba implements RequestHandler<Request, Object>{   

        private UserService userService;

        @Inject
        public void seUserService(UserService userService) {
            this.userService = userService;
        }

        public Object handleRequest(Request request, Context context){

            userService.persistData();
}

UserService

public interface UserService {
    List<String> persistData();
}

UserServiceImpl

public class UserServiceImpl implements UserService{


    @Override
    public List<String> persistData() {

        System.out.println("***Working*********");
}

Binding Class:

public class MessageGuiceModule extends AbstractModule
{
  protected void configure() {

    bind(UserService.class).to(UserServiceImpl.class);
  }
}

Test Class:

 @Test
        public void testLambdaFunctionHandler() {
Request request = new Request();
            request.setName("Name");
            FirstLamdba handler = new FirstLamdba();
            Context ctx = createContext();

            Object output = handler.handleRequest(request, ctx);

            // TODO: validate output here if needed.
            if (output != null) {
                System.out.println(output.toString());
            }
        }

For some reasons, UserService userService is sets as null in FirstLamdba.

Any idea?

like image 938
user1030128 Avatar asked Oct 29 '16 17:10

user1030128


2 Answers

The first time a lambda function is invoked, the environment will be created.

public class FirstLamdba implements RequestHandler<Request, Object>{   

        Injector injector = Guice.createInjector(new MessageGuiceModule());
        private UserService userService = injector.getInstance(UserService.class);


        //setter for testing purpose
        public void setUserService(UserService userService) {
            this.userService = userService;
        }

        public Object handleRequest(Request request, Context context){

            userService.persistData();
}


@Test
public void testLambdaFunctionHandler() {
        Request request = new Request();
        request.setName("Name");
        FirstLamdba handler = new FirstLamdba();
        handler.setUserService(mockUserService);

        Context ctx = createContext();

        Object output = handler.handleRequest(request, ctx);

        // TODO: validate output here if needed.
        if (output != null) {
            System.out.println(output.toString());
        }
}
like image 89
frhack Avatar answered Oct 12 '22 14:10

frhack


The Lambda RequestHandler instance is not instrumented with Guice, so using @Inject directly inside the RequestHandler class is not going to work. This is why you your userService property is always null.

I haven't tried using Guice with Lambda, but I believe you will have to explicitly call Guice.createInjector() at some point in order to bootstrap Guice dependency injection.

In general when developing AWS Lambda functions I recommend starting with a POJO that does things like bootstrapping your libraries, and exposes a single high-level method like persistUser() that you can easily run and test independently from any Lambda specific code. Once you get that working your Lambda function would simply be a few lines of code that instantiates an instance of this POJO and calls the persistUser() method.

like image 20
Mark B Avatar answered Oct 12 '22 13:10

Mark B