Sonar Apigee Plugin
This SonarQube Plugin is designed to test Apigee apiproxies and sharedflows. The goals is to help API developers in doing a static analysis and providing issues to the Sonar engine.
The rules are based on the apigeecs/bundle-linter and on this document about best-practices. It deals also with some recommendations of these pages : Introduction to antipatterns All rules are not yet implemented (see below).
This plugin has been successfully tested with several SonarQube releases. Here are the compatibilities :
- sonar-apigee-plugin 2.1.1: SQ from 7.9 (former LTS) to 8.7.1 included
- sonar-apigee-plugin 3.0.0: SQ from 8.8 and later, including of course 8.9 LTS
- If you run older releases of Sonar, please consider upgrading Sonar, or stay with the release 1.3.1 of this plugin and with sonar-xml plugin 1.4.3.
- If you upgrade sonar-xml from 1.4.3 to 2.0.1-*, you MUST upgrade this sonar-apigee-plugin at the same time.
- If you upgrade SonarQube from 8.7.1 or ealier to 8.8 and later, you MUST uninstall this sonar-apigee-plugin before upgrading (and reinstall it after)
To work, the plugin sonar-xml-plugin MUST be installed.
- Set the "Sonar way Apigee" quality profile as default. You can also create a new profile and add it the rules coming from ApigeeXML and CommonXML repositories.
.xsltas suffixes to be analyzed in the XML Language administration.
- Configure your Quality Gates as needed
If you want to try the very latest version :
mvn clean install
You'll get a jar file in the target directory.
Copy this jar in the directory $SONARQUBE_HOME/extensions/plugins and restart the server.
Why this plugin ?
- because companies prefer using a centralized platform like Sonar, instead of an standalone tool
- because SonarQube provides a lot of tools, measures, issue management, ... out-of-the-box
- because SonarQube is well integrated with CI platform like Jenkins. It's part of continuous delivery.
The rule IDs come from the apigeecs/bundle-linter. Other rules start from "500" to not interfer with the first rules. Example : PD500.
✖️: not yet implemented
⭕: won't be implemented. See details in Description column
|BN001||Bundle folder structure correctness.||Bundles have a clear structure.|
|BN002||Extraneous files.||Ensure each folder contains approrpriate resources in the bundle.|
|BN003||Major||Cache Coherence||A bundle that includes cache reads should include cache writes with the same keys.|
|BN004||Unused variables.||Within a bundle variables created should be used in conditions, resource callouts, or policies.|
|BN005||Minor||Unattached policies.||Unattached policies are dead code and should be removed from production bundles.|
|BN006||Major||Bundle size - policies.||Large bundles are a symptom of poor design. A high number of policies is predictive of an oversized bundle. The threshold is defined in the Quality Profile. Default value is 20.|
|BN007||Major||Bundle size - resource callouts.||Large bundles are a symptom of poor design. A high number of resource callouts is indicative of underutilizing out of the box Apigee policies. The threshold is defined in the Quality Profile. Default value is 20.|
|BN008||Major||IgnoreUnresolvedVariables and FaultRules||Use of IgnoreUnresolvedVariables without the use of FaultRules may lead to unexpected errors.|
|BN009||Major||Statistics Collector - duplicate policies||Warn on duplicate policies when no conditions are present or conditions are duplicates.|
|BN500||Info||Description length||A Description tag should have more than N chars to be useful. "N" can be modified in the Quality Profile. The default value is 5.|
|BN501||Blocker||Description pattern||The Description of the APIProxy must be compliant with a pattern defined in the Quality Profile. For example :
|BN502||Minor||Unattached resources.||Unattached resources are dead code and should be removed from production bundles. This rule only checks XSL, XSD and WSDL resources. Don't forget to add
Proxy Definition level
|PD001||Blocker||RouteRules to Targets||RouteRules should map to defined Targets|
|PD002||Blocker||Unreachable Route Rules - defaults||Only one RouteRule should be present without a condition|
|PD003||Blocker||Unreachable Route Rules||RouteRule without a condition should be last.|
|PD501||Major||Too much proxy endpoints||Discourage the declaration of multiple proxy endpoints in a same proxy. The threshold is defined in the Quality Profile. Default value is 2.|
Target Definition level
|TD001||Major||Mgmt Server as Target||Discourage calls to the Management Server from a Proxy via target.|
|TD002||Major||Use Target Servers||Encourage the use of target servers|
|TD501||Major||Too much Target Endpoints||Discourage the use of numerous target endpoints. The threshold is defined in the Quality Profile. Default value is 5.|
|FL001||Blocker||Unconditional Flows||Only one unconditional flow will get executed. Error if more than one was detected.|
|FL500||Critical||Default flow||A default flow must be defined to catch all requests on undefined resources.|
|FL501||Blocker||Unreachable flow||Flow without a condition must be last.|
|ST001||Minor||Empty Step||Empty steps clutter the bundle. (Should never happen, Apigee already blocks this error form occuring.)|
|PO001||Major||JSON Threat Protection||A check for a body element should be performed before policy execution.|
|PO002||Major||XML Threat Protection||A check for a body element should be performed before policy execution.|
|PO003||Major||Extract Variables with JSONPayload||A check for a body element should be performed before policy execution.|
|PO004||Major||Extract Variables with XMLPayload||A check for a body element should be performed before policy execution.|
|PO005||Major||Extract Variables with FormParam||A check for a body element should be performed before policy execution.|
|PO006||Policy Naming Conventions - default name||Policy names should not be default.|
|PO007||Minor||Policy Naming Conventions - type indication||It is recommended that the policy name include an indicator of the policy type.|
|PO008||Minor||Policy Name Attribute Conventions||It is recommended that the policy name attribute match the display name of the policy.|
|PO009||Major||Service Callout Target - Mgmt Server||Targeting management server may result in higher than expected latency use with caution.|
|PO010||Service Callout Target - Target Server||Encourage use of target servers.|
|PO011||Service Callout Target - Dynamic URLs||Error on dynamic URLs in target server URL tag.|
|PO012||Service Callout Target - Script Target Node||JSHint, ESLint. This SonarQube plugin is not a linter.|
|PO014||Resource Call Out - Java||Analyzed by sonar-java-plugin.|
|PO015||Resource Call Out - Python||Analyzed by sonar-python-plugin.|
|PO016||Statistics Collector - duplicate variables||Warn on duplicate variables.|
|PO017||Misconfigured - FaultRules/Fault Rule in Policy||FaultRules are configured in ProxyEndpoints and TargetEndpoints.|
|PO018||Major||Regex Lookahead/Lookbehind are Expensive - Threat Protection Policy||Regular expressions that include lookahead or lookbehind perform slowly on large payloads and are typically not required.|
|PO019||Major||Reserved words as variables - ServiceCallout Request||Using "request" as the name of a Request may cause unexpected side effects.|
|PO020||Major||Reserved words as variables - ServiceCallout Response||Using "response" as the name of a Response may cause unexpected side effects.|
|PO021||Statistics Collector - reserved variables||Warn on insertion of duplicate variables.|
|PO022||Major||Nondistributed Quota||When using nondistributed quota the number of allowed calls is influenced by the number of Message Processors (MPs) deployed. This may lead to higher than expected transactions for a given quota as MPs now autoscale.|
|PO023||Major||Quota Policy Reuse||When the same Quota policy is used more than once you must ensure that the conditions of execution are mutually exclusive or that you intend for a call to count more than once per message processed.|
|PO024||Major||Cache Error Responses||By default the ResponseCache policy will cache non 200 responses. Either create a condition or use policy configuration options to exclude non 200 responses.|
|PO500||Major||Avoid Python language||Python scripts can introduce performance bottlenecks for simple executions, as it is interpreted at runtime.|
|FR001||Major||No Condition on FaultRule||It's not a best practice to have a FaultRule without an outer condition, which automatically makes the FaultRule true.|
|FR501||Major||FaultRules or DefaultFaultRule must be used||It's needed to prevent default error messages from the backend or from Apigee to be forwarded outside.|
|FR502||Critical||DefaultFaultRule defined and FaultRule without condition||A DefaultFaultRule is defined whereas a FaultRule without condition exists. Consider removing the FaultRule without condition.|
|CC001||Literals in Conditionals||Warn on literals in any conditional statement.|
|CC002||Null Blank Checks||Blank checks should also check for null conditions. (to be reviewed)|
|CC003||Minor||Long condition statement||Conditions should not be longer than "N" characters. "N" can be modified in the Quality Profile. The default value is 255.|
|CC004||Overly complex condition||Condition complexity should be limited to fix number of variables and conjunctions.|
|CC006||Detect logical absurdities||Conditions should not have internal logic conflicts - warn when these are detected.|