Access private IP from Java Callout on Apigee (X)

Hi,

Our Java Callout policy runs properly on Apigee Hybird - Given we used a Custom Java Security Policy to allow certain permissions that were not allowed by default.

On Apigee (X), we can't Add a custom security policy - We get an error that aligns with the documentation. (which says it's only available on Hybrid)

Without going into the reasoning of why custom security policies are not allowed on Apigee, is there a way to allow the Java Callout to access local IP in the same VPC? (For example a VM)

Without this option, we would have to use a public IP address which would probably lead to internal routing but with external routing billing.

One more method we are looking into is have another API Proxy to perform the connection to the local IP.  But we would still need to figure out how to access this API Proxy from the java callout code.

Thanks in advance!
Razor.

1 4 219
4 REPLIES 4

is there a way to allow the Java Callout to access local IP in the same VPC? (For example a VM)

No.

Without this option, we would have to use a public IP address which would probably lead to internal routing but with external routing billing.

I don't think it's true that you must use a public IP address. I think you can reach a local IP from a ServiceCallout, or an ExternalCallout, or a regular target.

we would still need to figure out how to access this API Proxy from the java callout code.

But WHY is the Java Callout the way you must reach an external encpoint? that's not what Java Callouts are intended for.

We collect a substantial amount of data from each transaction (headers, payload, metadata) and send it for processing.

If we used ExternalCallout, the process is inline, slowing down the original transaction, introducing extra Latency.

If we use ServiceCallout, we are bound to only trigger the ServiceCallout in the context of a transaction.

Since we want to aggregate the collected data into batches, we used Java to implement the aggregation mechanism, timers to flush the aggregated data, reduce overhead of calling the external service too often.

 

With regards to adding another API Proxy, the downsides are:

  1. Extra hit per call. (more expensive)
  2. Extra configuration on customer resources.

We tried using 127.0.0.1:443 as destination in the Java code but got permission error, same as private IP address 10.0.X.X.  Only public IP works.

 

I suggest using ExternalCallout instead of Java Callout.  EC is GRPC, the connection is persistent, and it will be fast.  Migrate the aggregation and timer logic to an external process written in Java or whatever.  Then you can do whatever you. like in that external process.  No restrictions on the Java permissions.  That Java logic  can run in a CloudRun container or GKE or whatever you like.  

The Java callout isn't a general-purpose logic host, and is restricted in what it can do, as you can see.  But if you use an external process, you avoid that restriction, at the cost of some extra architectural complexity.

Thanks for the feedback.  Will consider it.

In favor of the Java Callout solution is that assuming all Apigee product types (Edge, Hybrid, X, On-Prem) Supported the same Java Callout (and they mostly do), we would only have to maintain a single sharedflow with a single Jar file to support all deployment types.

With ExternalCallout we have to accommodate running another component in different scenarios.

Also, It would really help if ExternalCallout had an "Async" mode where it would send all the data to the GRPC endpoint AFTER the transaction was finished.  Yes, I understand this means all the data needs to be buffered somewhere, I would allow configurable maximum payload size and an option to determine what happens if the payload > maximum size.  For example, drop the payload completely, or truncate.

This way you could enjoy all worlds, use ExternalCallout, not worry about the CloudRun process being inline with regards to latency and even causing outages to the original API proxy, while also reducing the memory footprint of having all the data buffered to implement async operation of ExternalCallout.