I am reading existing cloudformation and want to read method integrations. The return type of CfnMethod.getIntegration() is "class software.amazon.jsii.JsiiObject". I understand there are 3 different types of Integrations, all extending Integration class. I tried to first cast it to Integration, thinking I would be later able to check if the type of it really is http,aws or lambda integration. But the first step failed:
class software.amazon.jsii.JsiiObject cannot be cast to class software.amazon.awscdk.services.apigateway.Integration
Where is my thinking flawed? How do I get the info about what kind of an integration it is? To make it weirder this is in the apigateway integration in the docs:
software.amazon.awscdk.services.apigateway
Class HttpIntegration
java.lang.Object
software.amazon.jsii.JsiiObject
software.amazon.awscdk.services.apigateway.Integration
software.amazon.awscdk.services.apigateway.HttpIntegration
I expected to be able to cast the JsiiObject into an Integration. Result: unable to cast (fails at "Integration" line).
public static void execute(HolderForAWSState holderForAWSState){
List<CfnMethod> work = new ArrayList<>();
for (IConstruct worker : holderForAWSState.getOrderedConstructs().get(CfnMethod.class)) {
work.add((CfnMethod) worker);
}
for(CfnMethod worker: work){
System.out.println("Integration class: ");
System.out.println(worker.getIntegration().getClass());
Integration integration = (Integration) worker.getIntegration();
System.out.println(integration.getClass());
}
}
2
Answers
One colleague of mine decided 2 hours with me on this problem is worth it.
We played using an existing CfnMethod worker:
JsiiObject jsiiObject = (JsiiObject) worker.getIntegration(); System.out.println(jsiiObject.$jsii$toJson());
outcome:
{"$jsii.byref":"Object@10049","$jsii.interfaces":["aws-cdk-lib.aws_apigateway.CfnMethod.IntegrationProperty"]}
How come? So why isn't this method called "getIntegrationProperty()"? Maybe if I cast to it?
IntegrationProperty intProp = (IntegrationProperty) worker.getIntegration();
outcome:
class software.amazon.jsii.JsiiObject cannot be cast to class software.amazon.awscdk.services.apigateway.CfnMethod$IntegrationProperty
????????
After 1 more hour of fumbling around we found out, that the cast is not a direct one, but for whatever reason considered "unsafe" and requires a special static method from a special class, that of course is nowhere documented:
IntegrationProperty integrationProp = UnsafeCast.unsafeCast(jsiiObject, IntegrationProperty.class);
Worked like a charm. All Integration Property methods are accessible. Example:
System.out.println(integrationProp.getClass());
System.out.println(integrationProp.getType());
outcome:
class software.amazon.awscdk.services.apigateway.CfnMethod$IntegrationProperty$Jsii$Proxy AWS_PROXY
Thanks Simun!
CDK is not implemented in Java and doesn’t follow any class hierarchies for that matter. CDK is implemented in Typescript and a Java Wrapper provides the interface for it. The core is still running typescript even when running from Java.
A JsiiObject is a proxy for the corresponding Typescript object and as far as I can see CDK doesn’t provide support for investigating the type hierarchy comfortably from Java.
I assume that the Integration is created by the CDK itself and not by user code.
Unfortunately I don’t see a valid, non-hacky way to achieve this and you might need a completely different solution.
For example use the AWS API to inspect the deployed CDK stack or extract the necessary information from the proxy yourself.