Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

APIGEE : Java Callout Issue

Hi @dchiesa1 ,

I am working on Java callout for invoking AWS lambda function from Apigee. I have written below java code and created Java project in Eclipse and exported project as runnable jar. That jar I am using in API proxies. But when I am testing API getting java error as below    

Java Code-

 

package com.example.lambda;

import java.nio.charset.Charset;
import com.apigee.flow.execution.ExecutionContext;
import com.apigee.flow.execution.ExecutionResult;
import com.apigee.flow.execution.spi.Execution;
import com.apigee.flow.message.MessageContext;

import com.amazonaws.auth.AWSSessionCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicSessionCredentials;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.lambda.AWSLambda;
import com.amazonaws.services.lambda.AWSLambdaClientBuilder;
import com.amazonaws.services.lambda.model.InvocationType;
import com.amazonaws.services.lambda.model.InvokeRequest;
import com.amazonaws.services.lambda.model.InvokeResult;

public class awsinvoke implements Execution  {
	
	public ExecutionResult execute(MessageContext messageContext,ExecutionContext executionContext) {
		try {

		// final String AWS_ACCESS_KEY_ID = "ASIA3UK7JR6MLQBMGIXW";
		  //  final String AWS_SECRET_ACCESS_KEY = "L/W8VHOqj2dN4JPAe8CnF/u2sqNJwu/+KPJrLi2Q";
		    //final String AWS_SESSION_TOKEN = "FwoGZXIvYXdzENj//////////wEaDN4TpncmRFI83olJ9iKpAvf8qiqfYd0F6ifT8xz/D69S/QaSFTHEHww5Rz/scvanT9gkMIssiSdqm+R3uGS93bptUHw1OjJnr+hStsn+ZZF2YQfRkEJ3WlQhOW1rDbgDBHiLtfSMQrKfye2LrUnviDUWRKwBVotw6bIU9NXSP5SRvwHC7Cz//s3UqqPojA3/0l+SpYtBnfjInpiMV7ppgUosYc3y2u21mWlmKvkl1ZF3ZUSWlp4uAEQevMdVQTdQP2JYKejzDhZ+IUZ7nNJbP2Jx4hsT72yPYir0JeqpdvklbzzouYN3DcJLSW7U8Kxs1GnJphJP3VKK+xxrW2KTBJV2R/BJc0fsgCRBxsy3NbYiA7C3n/Pdik3NU+Xa37RYoNwSPpBCmJXcv9JwsSAugj+r9K9sHZ3OLyj6k5uaBjIqEjOV4jdAsIJehb62jLrGKgQoRg0yHiSjUg/gTmXnNmaOWhKI6bJ6pFI5";

		    //AWSCredentials credentials = new BasicAWSCredentials(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY);
			 // ARN
		    //String functionName = "arn:aws:lambda:us-east-1:799600643992:function:helloworldlambda";
		    
		    String AWS_SESSION_TOKEN = messageContext.getVariable("AWS_SESSION_TOKEN");
		    String AWS_SECRET_ACCESS_KEY = messageContext.getVariable("AWS_ACCESS_KEY_ID");
		    String AWS_ACCESS_KEY_ID = messageContext.getVariable("AWS_SECRET_ACCESS_KEY");
		    String functionName = messageContext.getVariable("functionName");
		    String regionname= messageContext.getVariable("regionname");
		    AWSSessionCredentials credentials = new BasicSessionCredentials(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY,AWS_SESSION_TOKEN);
		    

		    //This will convert object to JSON String
		    //String inputJSON = new Json().toJson(userActivity);

		    InvokeRequest lmbRequest = new InvokeRequest()
		           .withFunctionName(functionName);

		    lmbRequest.setInvocationType(InvocationType.RequestResponse);
		    Regions functionregion = Regions.US_EAST_1;
		    if(regionname=="us-west-2")
		    {
		    functionregion= Regions.US_WEST_2;
		    }
		    if(regionname=="us-east-2")
		    {
		    functionregion= Regions.US_EAST_2;
		    }

		    AWSLambda lambda = AWSLambdaClientBuilder.standard()
		            .withRegion(functionregion)
		            .withCredentials(new AWSStaticCredentialsProvider(credentials)).build();

		    InvokeResult lmbResult = lambda.invoke(lmbRequest);

		    String resultJSON = new String(lmbResult.getPayload().array(), Charset.forName("UTF-8"));

		    //System.out.println(resultJSON);
		    String resultstr = "lambda_response";
		    messageContext.setVariable(resultstr, "Result: " + resultJSON );
		    
		    return ExecutionResult.SUCCESS;
		}

	    

		catch (Exception e) {
		//String exc =  e.toString();
		//messageContext.getErrorMessage().setContent(exc);
		String varName = "mycallout_error";
		messageContext.setVariable(varName, "Exception: " + e.toString());
		      return ExecutionResult.ABORT;

		    }
	}
}

 

.Error-

{
    "fault": {
        "faultstring""Failed to execute JavaCallout. Could not initialize class com.amazonaws.services.lambda.AWSLambdaClientBuilder",
        "detail": {
            "errorcode""steps.javacallout.ExecutionError"
        }
    }
}
 
This java file referring aws sdk , that jars is present in in exported jar, and when I am running this jar in my local system through cmd its working fine but in Apigee its throwing error. Can you please help me on this.
 
 
jar.PNG

 

 

Solved Solved
0 8 1,203
1 ACCEPTED SOLUTION


My requirement is to invoke lamda function from api proxy. Signature part I have done and it's working fine.


"signature part I have done" means what exactly? Do you have a Java callout that creates a signature? does it work within Apigee? I understood from your prior posts that you have a Java class that produces the signature but that class does not function within Apigee as a callout. I thought that was the problem we were solving. Is this wrong?


And I believe to call any aws services we need to use aws sdk.


That is not correct. To call AWS services you can just send an HTTP request to the appropriate endpoint. You can use a Lambda function as an HTTP Target. Or the target of a ServiceCallout. The only tricky part is the authentication, the signature. The Java callout I shared with you produces the signature you need. I think a Java callout that relies on the AWS SDK will not work in Apigee. The JAR for the AWS SDK is too large for Apigee. I cannot solve that.  It won't work. The Java class you already have cannot be used within Apigee. Other people have had this problem. That is why I produced the smaller Java callout that simply creates the signature for AWS.

View solution in original post

8 REPLIES 8