Overview
This document covers coding style common in Cloudstack development. It covers coding in Java, shell script, Python and database naming conventions. It does not always cover coding best practices (although there will be some overlap).
Although the document talks mostly about conventions, certain items are ‘must’ while others are ‘should’ and ‘can’.
In all cases, correctness of the code is paramount, followed by readability, followed by these conventions.
It is also important to not introduce formatting changes in existing code in the attempt to conform to these conventions: this makes it hard to track logic changes vs. formatting changes in the code. If an existing code block is being rewritten extensively then it makes sense to adopt these conventions.
Copyright and License
All source code should bear the ASF license header as detailed here:
http://www.apache.org/legal/src-headers.html#headers
Java Coding Conventions
These are mostly taken from http://geosoft.no/development/javastyle.html with modifications to reflect current style in Cloudstack. That document is itself derived from Sun’s original Java Code Conventions document.
Naming Conventions
- Names representing types must be nouns and written in mixed case starting with upper case. E.g., StoragePool
- Variable names must be in mixed case starting with lower case, E.g., virtualRouter
- Names representing constants (final variables) must be all uppercase using underscore to separate words. E.g., MAX_TEMPLATE_SIZE_MB
- Names representing methods must be verbs and written in mixed case starting with lower case. E.g., copyTemplateToZone
- Abbreviations and acronyms should not be uppercase when used as name. E.g., startElbVm
- Private class variables should have underscore prefix. E.g., _downloadTimer. Exception: Transfer Objects (TOs), Database objects (VOs), Command objects:- private class variables in these classes have no underscores. The exception is justified since these are usually logged and are more readable without underscores.
- Static variables are prefixed with s_. E.g., s_logger
- is prefix should be used for boolean variables and methods. E.g., isFinished
- Exception classes should be suffixed with Exception.
- Default interface implementations can be prefixed by Default or if intended to be subclassed, suffixed by Base. E.g., DefaultExternalNetworkElement or NetworkElementBase
- There are various naming conventions used to convey the design patterns common in Cloudstack, listed in the Appendix.
Files, Layout and whitespace
- File content must be kept within 180 columns
Continuation of lines should be obvious:
totalSum = a + b + c +
d + e;
- Must indent with space not tabs. Indentation = 4 spaces
- Line endings should be LR (Mac / Linux format)
- White space:
- - Operators should be surrounded by a space character.
- - Java reserved words should be followed by a white space.
- - Commas should be followed by a white space.
- - Colons should be surrounded by white space.
- - Semicolons in for statements should be followed by a space character.
Block layout should be as illustrated below . Class, Interface and method blocks should also use this layout.
while (!done) {
doSomething();
done = moreToDo();
}
If-else clauses must use the following layout:
if (condition) {
statements;
} else {
statements;
}
- The try-catch block follows the if-else example above
Statements
- Imported classes should always be listed explicitly. No wildcards. The list of imports should be kept minimal and organized using your IDE
- Class and Interface declarations should be organized in the following manner:
- Class/Interface documentation.
- class or interface statement.
- Class (static) variables in the order public, protected, package (no access modifier), private.
- Instance variables in the order public, protected, package (no access modifier), private.
- Constructors.
- Methods (no specific order).
- Type conversions must always be done explicitly. Never rely on implicit type conversion.
- Variables should be initialized where they are declared and they should be declared in the smallest scope possible
- Class variables should never be declared public
- Loop variables should be initialized immediately before the loop.
- The conditional should be put on a separate line. This improves debuggability when there is a failure.
- The use of magic numbers in the code should be avoided. Numbers other than 0 and 1can be considered declared as named constants instead.
- Tricky code should not be commented but rewritten. Code should be self documenting
- Code that parses special input strings (e.g, comma delimited) should provide examples of valid strings in comments
- Use // for all non-JavaDoc comments, including multi-line comments
- Comments should be in English
- Comments should be indented relative to their position in the code
- All public classes and public and protected functions within public classes should be documented using the Java documentation (javadoc) conventions
Libraries
- For string operations, org.apache.commons.lang3.StringUtils must be used. For operations not covered by org.apache.commons.lang3.StringUtils, the facade com.cloud.utils.StringUtils must be used.
Database Conventions
- All SQL keywords are all-caps
- Naming:
- Table and column names are lower case with underscore separating words
- Indices (including UNIQUE) are lower case of the form i_<table name>_<column name>
- Foreign key constraints are of the form fk_<table name>_<foreign table name><foreign column_name>
- All CREATE TABLE’s should have the corresponding DROP TABLE IF EXISTS at the top of the file.
- Database engine must always be InnoDB. Charset should always be UTf8
- Primary keys are always bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT
- Tables intended for operational purposes, usually transient data should be prefixed with op_ (e.g., op_lock)
- Columns should always be commented unless obvious
- Examine each column to choose your indexes. More indexes can mean more tablespace usage (but this is usually trivial) but better performance. More indexes also increase the possibility of deadlocks.
Shell Script
The current state of shell scripts inside Cloudstack is fairly inconsistent. Will update later
Python
- All Python code must be PEP-8 compliant
- All existing code fails this test.
- TODO
IDE settings file
Eclipse
- The eclipse settings file is checked-in in git with the code. You can find it at tools/eclipse/eclipse.epf
- The formatter xml exported from the above epf is ApacheCloudStack.xml
- It is available in git repo @ https://git-wip-us.apache.org/repos/asf?p=cloudstack.git;a=blob_plain;f=tools/eclipse/ApacheCloudStack.xml;hb=HEAD
Intellij Idea
Appendix
Naming Conventions for Design patterns used in Cloudstack Java code
- If an interface has only a single implementation, the implementing class has a suffix Impl
- A class that maps to a database table is known as a Value Object and is suffixed with VO. E.g., NetworkVO. This actually maps to the EJB DTO pattern rather than the EJB VO pattern
- A class that transfers data from one tier to another (e.g., from the business logic tier to the resource layer) is a Transfer Object and is suffixed with TO. E.g., LoadBalancerTO.
- A utility class that encapsulates common utilities (e.g., conversion between ip address formats) is suffixed with Utils. Eg., NetUtils. These classes do not hold state. Generally all methods are static.
- Services offered by the business tier to the API tier are declared as interfaces and are suffixed by Service. E.g., LoadBalancerService
- Singleton classes that implement lifecycle functions are called Managers. E.g., AgentManager
- Data Access Objects (DAOs) implement the J2EE DAO pattern. They are generally declared as interfaces suffixed with DAO and then implemented as classes with the DaoImpl suffix. E.g., AccountDao _and AccountDaoImpl_
- The Cloudstack API layer implements the Command pattern. All API commands are suffixed with Cmd. E.g., DeployVmCmd.
- The internal API layer between the business tier and the resource layer also uses the Command pattern. These classes are suffixed with Command. Responses to these commands are suffixed with Answer. E.g. ModifyStoragePoolCommand and ModifyStoragePoolAnswer.
- Resources are managers that respond to the internal API commands. E.g. XenServer56Resource
References
[1] Java Programming Style Guidelines http://geosoft.no/development/javastyle.html
[2] Java Code Conventions http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html
Attachments