본문 바로가기

아는 만큼 보인다/AWS

AWS SDK 사용해 다른 계정의 Lambda 함수를 일반화하고 호출하기

java용 SDK를 사용해 타 계정의 AWS Lambda function를 호출하고자 합니다. 


그런데,

호출하려는 AWS Lambda 함수를 일반화하고 싶습니다.

AWS Lambda 함수가 추가될 때마다 인터페이스를 추가하고 빌드하고 싶지 않은 것입니다. 하나

인터페이스로 이후에 추가되는 AWS Lambda 함수들을 모두 커버하고 싶은 것입니다.


이를 시도한 예제 코드입니다. 


1. 대상 Lambda 함수 정보 제공용 Interface 


public interface HelloMyLambdaService {
 
    @LambdaFunction
    //@LambdaFunction(functionName="arn:aws:lambda:ap-northeast-1:xxxxxx")
    Object invokeAwsLambda(Map<String, Object> input);
}
 호출하려는 함수를 일반화하기 위해서 다음과 같이 메소드를 정의합니다.
    • 파라미터 타입 Map<String, Object> : Json 포맷의 문자열을 AWS SDK가 처리 가능한 Map 타입으로 변환하여 호출함
    • 반환 타입은 Object 사용: 람다함수로 부터 String 또는 LinkedHashMap 형의 응답데이타가 반환됨


 그리고 @LambdaFunction 어노테이션에서는 함수명 속성을 제거합니다. 이제 위 interface에서는

 함수명을 제공하지 않습니다.



2. 다른 계정의 Lambda 함수 호출


public class LambdaInvoke {
    // access keys
    private static final String awsAccessKeyId = "XXX";
    private static final String awsSecretAccessKey = "YYYYYY";

    private static final String functionName = "runtime시 동적으로 지정됐다고 가정";

    public static void main(String [] args) {

        // credential 설정
        AWSCredentials credentials = new BasicAWSCredentials(awsAccessKeyId, awsSecretAccessKey);
        AWSLambdaClient lambda = new AWSLambdaClient(credentials);
        lambda.configureRegion(Regions.AP_NORTHEAST_1);

        // annotation 기반 AWS lambda 함수명 무시 --> 동적으로 지정된 함수명 사용
        LambdaInvokerFactoryConfig myConfig = new LambdaInvokerFactoryConfig();
        myConfig.withLambdaFunctionNameResolver(new LambdaFunctionNameResolver(){
            @Override
            public String getFunctionName( Method method,

                                                     LambdaFunction annotation,

                                                     LambdaInvokerFactoryConfig config) {
                return functionName;
            }
        });

       HelloMyLambdaService service = 

                LambdaInvokerFactory.build(HelloMyLambdaService.class,

                                                   lambda, myConfig);


        // invoke

        String inputPayload = "{test:input}";
        Map<String, Object> jsonParams = new Gson().fromJson(
                        inputPayload,
                        new TypeToken<HashMap<String, Object>>() {}.getType());
        Object ret = service.invoke(jsonParams );

        System.out.println("retrun value: " + ret);

    }
}


 LambdaInvokerFactory 가 LambdaInvoker를 만들 때 사용하는 설정 내용을 바꾸기 위해 LambdaInvokerFactoryConfig를 생성합니다.


 생성한 LambdaInvokerFactoryConfig에서 LambdaFunctionNameResolver를 교체합니다.

기본적으로 어노테이션으로부터 함수명을 추출하는 DefaultLambdaFunctionNameResolver를 빼고,

대신에 익명 LambdaFunctionNameResolver 클래스를 구현해 넣었습니다. 이렇게 바뀐 LambdaFunctionNameResolver는 동적으로 지정된 함수명을 반환합니다.


 함수명은 cross-account 의 함수를 지정하기 위해 cross-account-id가 포함된 ARN 포맷으로 지정

합니다.