Last post of the year
This will be my last last of the year.
So first off I'd like to wish everyone a safe and merry and Christmas and a happy new year.
In my last post I covered adding support for gateway script that are embedded in an APIC YAML file.
All our original rules around DataPower transforms were for DataPower logic written with XSLT. Those transforms can still be deployed using APIC.
For the the newer APIC YAML files, the trick for us is to be able to handle the XSLT embedded in another file. In the same we can extract the gateway script from the YAML file we can extract the XSLT.
There is now a specific XML plugin for SonarQube, but we have specifically included the XSLT checks for DataPower in our SonarQube plugin for a few reasons:
When it came to trying to embed the XSLT checks, it was a lot easier then what we needed to do with the rhino library.
In this case, we just needed to split out the YAML file. I used a combination of the snakeyaml and Jackson databind library to handle the parsing the YAML files.
In some places we used the object binding. So in this case we can use the JacksonDataBind ObjectMapper class.
We can define each field that will be marshalled into the Object. So in this case it is APIConnectPolicy(AsYaml)
public class APIConnectPolicyAsYaml
{
@JsonProperty("global-policy")
String globalPolicy;
APIConnectInfoAsYaml info;
@JsonIgnore
Map<String, Object> gateways;
@JsonIgnore
Map<String, Object> assembly;
YAML is a bit of a beast. It's never really (in my opinion) had the maturity and consistency of XML with schema's (XSD and DTD).
There are a lot more mature options to un-marshal and marshal XML then there are for YAML. So working with it this way, with binding objects, we had a few quirks in the logic as we don't have a full taxonomy for the entire structure of what APIC YAML files can look like.
The structure / taxonomy of the YAML is mostly likely hidden away somewhere in the proprietary code of the APIC code project.
So to pull some of the nested details needed to write some of our more complicated rules, like when we extract the gateway script or XSL, we need to start getting into more complicated YAML files. So to work with the more complicated, we started to look at YAML parsing as lists of lists using :
public Map<String, Object> getAssembly()
{
return assembly;
}
Then using "SnakeYaml", which allows us to get the list of lists (well maps of maps in the code).
Recommended by LinkedIn
Yaml yaml = new Yaml();
Map<String, Object> obj = yaml.load(sourceFile.getOriginalSourceLines());
For example, when we parse these we end up having to keep recursing through the map for another map with the right key. For handling gateway script we need to look for the key "execute" and then under that "gatewayscript" or "xslt".
Once we have the contents, we can parse it as we did with the other XSL files.
Then we can use the existing rules with our DP code:
These include:
R146 The XPATH contains //. // selects nodes from anywhere in the document and can affect performance of the XSL (XSL)
R147 The XSL contains an xsl:message element. These are usually only used in non-production code (XSL)
R148 The XSL contains an xsl:message element with terminate set to ‘yes’. That will stop the XSLT processor (XSL)
R151 An xsl:choose is missing a fall through xsl:otherwise (XSL)
More information on our products and on pricing can be found on our website:
You can also reach me via email at:
Richard@bettercodingtools.com
Or contact me via the contact page on our website:
Regards
Richard