Can you generate Go code from a Java binary jar? This need arose from writing a prototype Ingress Controller for Kubernetes that uses a NetScaler to provide the Ingress function. Another need was a Terraform driver for NetScaler. (While the NetScaler Ingress controller didn’t need a Golang client, it is customary to write Kubernetes integrations using Go).
NITRO is the REST API to program the Citrix NetScaler load balancer. The API is easy to use with well-defined usage patterns. Most commonly, JSON is used to create/update/read/delete configuration on the NetScaler. There are Java and Python clients, (as well as PowerShell and Perl), but I needed a Golang client to NITRO.
There were a few roadblocks to producing the Go client. One problem is that the NITRO API is vast (over 1000 config objects with corresponding JSON definitions). Second, the JSON documentation is in HTML docs, or, one has to resort to tools like Postman to reverse engineer the JSON schema.
After studying the NITRO Java SDK source, it occurred to me that each config object in the REST API had a corresponding Java class. For example
com.citrix.netscaler.nitro.resource.config.lb.lbvserver had fields that represented the possible fields in the JSON config object to configure a
The task was to generate a JSON v4 schema from the NITRO Java SDK. This was relatively easy after finding JJSchema . This project generates a JSON schema from Java classes. There were a few changes required to make JJSchema work with the NITRO jar: JJSchema assumed that all fields had an accessor of the form
getFoo(): In the case of NITRO, it was
get_foo(). JJSchema also relies on field annotations (
@Attributes) to figure out metadata such as enums and read-only. For enums, the Java classes in the NITRO package had inner classes with static member constants, and figuring out the
readonly attribute was a matter of finding fields that didn’t have
set_foo() methods. The resulting changes are in a fork: https://github.com/chiradeep/JJSchema. The code to invoke JJSchema is in https://github.com/chiradeep/json-nitro. This involves determining all the subclasses of
com.citrix.netscaler.nitro.resource.config and invoking the forked JJSchema on those classes.
Getting from JSON schema to Go involves another open source project (Generate). As the blurb says, Generate generates Go Structs from JSON schema. The generated schema is used in a (somewhat incomplete) Go client to the NITRO API (https://github.com/chiradeep/go-nitro).