Send Docs Feedback

Note: Most user interface tasks can be performed in Edge Classic or the New Edge experience. For an overview, getting started topics, and release notes specific to the New Edge experience, see the docs.

How to create a Java callout

What is a Java callout?

Apigee Edge provides a range of policies that address common API management requirements such as security, data transformation, traffic management, and others.

However, there are some cases where your API requires custom behavior that is not implemented in a standard policy. In these cases, Apigee provides several options that enable you to script or code customized API behavior. One approach is to implement the desired behavior in Java.

For the supported versions of Java, see Supported software.

How do I use Java code in a proxy?

A Java callout policy lets you call Java code from within an executing proxy flow. Your Java code needs to implement certain Edge-specific Java interfaces that allow the code to interact with the executing proxy. For example, Java methods exist for getting and setting headers, query parameters, flow variables, and other entities within the current flow context of the proxy.

When should I use a Java callout?

Let's look at situations where Java callouts are useful, and situations where you should consider other approaches.

First, consider alternative approaches

Before using a Java callout, note that there may be alternative approaches that you can use instead. For example:

  • For lightweight operations, such as HTTP API calls to remote services, consider using the ServiceCallout policy. See Service Callout policy.
  • For relatively simple interactions with message content, such as modifying or extracting HTTP headers, parameters, or message content, you can use JavaScript or Python languages.

What you can do in Java code

A Java callout supports these basic operations:

  • Examining or manipulating request or response messages
  • Getting and setting flow variables
  • Calling external services
  • Raising faults
  • Manipulating error messages and status codes

What you cannot do in Java code

Most system calls are disallowed. You cannot:

  • Perform local network I/O
  • Make file system reads or writes
  • Get information about the current process, the process list, or CPU/memory utilization on the machine

Although some such calls may work, they are unsupported and liable to be actively disabled at any time. Avoid making such calls in your code.

Do not use or rely on Java libraries that are included with Apigee Edge. Those libraries are for Edge product functionality only, and there's no guarantee that a library will be available from release to release. If you use such libraries, use them in non-production demonstrations only.

Hello Java callout

Let's walk through a basic hello world Java callout example. In this example, we create a simple proxy with a Java callout that returns a "hello world" response. The proxy can return one of two possible responses:

  • If you pass in a "username" header with a "name" value, the proxy returns:

    Hello, <name>!
  • If you omit the header, the proxy just returns:

    "Hello, Guest!"

Download the starter project

To make things simple, we have a basic project prepared for you on GitHub in the Apigee api-platform-samples repository.

  1. Download or clone api-platform-samples to your system.
  2. In a terminal or code editor of your choice, go to the api-platform-samples/doc-samples/java-hello project.

Write the Java code

  1. Open the Java source file: java-hello/callout/src/main/java/HelloJava.java. This file is a skeleton version of the main Java class that we will implement. The imported packages are required for Edge Java Callout code. These classes provide methods that allow you to access the proxy execution context. We'll walk through the steps for compiling and deploying this code shortly.
    package com.apigeesample;
    
    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;
    
    
    public class HelloJava implements Execution {
    
    	public ExecutionResult execute(MessageContext messageContext, ExecutionContext executionContext) {
    		
    		try {
    
    			// Your code here.
                
                return ExecutionResult.SUCCESS;
    
    		} catch (Exception e) {
    			return ExecutionResult.ABORT;
    		}
    	}
    
    }
    
  2. Replace the commented line // Your code here with the following code:

    String name = messageContext.getMessage().getHeader("username");
    
    if (name != null && name.length()>0) {
    	messageContext.getMessage().setContent("Hello, " + name + "!");
    	messageContext.getMessage().removeHeader("username");
    } else {
    	messageContext.getMessage().setContent("Hello, Guest!");
    }
    Note: The MessageContext object lets you access entities inside the flow where the Java Callout policy executes. Let's say the Java Callout policy is attached to the Proxy Endpoint Response flow. The code listed above gets the HTTP Message object for that flow context. The Message object, in turn, gives you access to headers, query parameters, body content, and flow variables.
  3. Save the file.


Compile your code with Maven

The POM file and configuration for the Maven compile should work, but are offered in the Git repository as an example only. You may need to make adjustments for your environment. If you make changes to the sample code, you may also need to adjust the Maven configuration. 

The project is set up so that you can compile with Maven. If you want to use javac, we'll include an example following the Maven example.

  1. Be sure that you have Maven installed:

    mvn -version
  2. Execute the script java-hello/buildsetup.sh. This script installs the required JAR dependencies in your local Maven repo.
  3. cd to the java-hello/callout directory.
  4. Execute Maven:

    mvn clean package
    If you get a Maven error, be sure that you are in the java-hello/callout directory.
  5. If you wish, verify that the JAR file edge-custom-policy-java-hello.jar was copied to java-hello/apiproxy/resources/java. This is the required location for JAR files that you wish to deploy with a proxy.

Compile with javac

If you want to use javac to compile the code, you can do something similar to the following (from the java-hello directory). The required JAR files are provided for you in the java-hello/lib directory.

  1. cd to api-platform-samples/doc-samples/java-hello.
  2. Be sure you have javac in your path.

    javac -version
  3. Execute the following javac command:

    javac -d . -classpath ./lib/expressions-1.0.0.jar:./lib/message-flow-1.0.0.jar:. callout/src/main/java/HelloJava.java
  4. Copy the JAR file to the apiproxy/resources/java directory. This is the required location for JAR files that you wish to deploy with a proxy.

    cp com/apigeesample/HelloJava.class apiproxy/resources/java

Deploy and call the proxy

A deploy script is provided in the ./java-hello directory. But before you run it, you need to do a quick setup.

  1. cd to api-platform-samples/doc-samples/java-hello
  2. If you haven't already done so, open the file ../../setup/setenv.sh and edit it as indicated with your Apigee account information: your username (the email address associated with your account), your organization name, and the domain you use to make API management calls. For example, for Edge cloud, the domain is https://api.enterprise.apigee.com; however, your domain may be different if you're using Edge Private Cloud.
  3. Save the setenv.sh file.
  4. Execute the deploy script:

    ./deploy.sh
  5. If the deploy succeeds, execute the invoke script:

    ./invoke.sh

    The invoke script calls a cURL command that looks like this:

    curl  http://$org-$env.$api_domain/java-hello -H "username:Will"

    Which returns "Hello, Will!

    You can edit the invoke.sh script to change the name, or if you change the cURL call to remove the header, then the command returns "Hello, Guest!"

About the proxy

Let's quickly examine the policies used in this proxy. Pay attention to where the policies are positioned in the proxy flow and why.

The Assign message policy

An Assign message policy is attached to the ProxyEndpoint request flow. It copies the username header from the request and assigns it to the response. This operation allows the Java Callout policy, which is attached to the response flow, to access the username header and build a custom response body using the value of that header.

<AssignMessage async="false" continueOnError="false" enabled="true" name="CopyHeader">     
    <DisplayName>CopyHeader</DisplayName>     
    <Copy source="request">         
        <Headers>             
          <Header name="username"/>         
        </Headers>     
    </Copy>     
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>     
    <AssignTo createNew="false" transport="http" type="response"/> 
</AssignMessage>

The Java callout policy

The Java callout policy is attached to the response flow. This is because the custom Java code makes changes to the response headers and message. The policy's ClassName element specifies the main class that is executed by the policy. The ResourceURL element is the name of the JAR file that you built and added to the resources/java directory of the proxy.

<JavaCallout name="hello-java">         
    <ClassName>com.apigeesample.HelloJava</ClassName>         
    <ResourceURL>java://edge-custom-policy-java-hello.jar</ResourceURL> 
</JavaCallout>

What you need to know about Java callout

Important things to note about implementing a Java callout are:

  • Imports classes from the com.apigee.flow.execution and com.apigee.flow.message packages. These packages must be included in the JAR file that is packaged and deployed. You can upload your Java JAR through the Management UI proxy editor, or you can include it in the /resources/java directory in API proxies that you develop locally.
  • Implements the Execution interface. Any Java code that is executed within an API proxy must implement Execution. 
  • A Java Callout policy contains no actual code. Instead, a Java Callout policy references a Java 'resource', which you must package in a JAR.
  • Package names to avoid: Do not use io.apigee or com.apigee as package names in Java Callouts. Those are reserved and used by other Apigee modules.
  • If your Java Callout relies on additional third-party libraries packaged as independent JAR files, then place those JAR files in the /resources/java directory as well to ensure that they are loaded correctly at runtime.
  • If there are multiple JARs, simply add them as additional resources. You do not need to modify the policy configuration to refer to additional JAR files. Putting them in /resources/java is sufficient.
  • For additional information on uploading Java JARs, see Resource files.

Help or comments?