Submit a plugin for review

Lodging the review request

Review requests are currently limited to internal Squiz developers. The review process is required for any plugin to be made available in the Squiz DXP.

Plugins must be submitted for review before they will be added as an available extension.

This ensures the quality of the plugin, and that appropriate tests are in place so that Squiz DXP upgrades do not break plugins deployed within the system.

You submit a request to have your plugin reviewed by creating a ticket via the Squiz service desk (Squiz Jira login required). Under requests for customers choose the Funnelback extension plugin review option. In the ticket you will need to provide details in relation to your plugin as well as a link to the source repository in GitLab for your plugin.

The source repository will also need to include a readme file for your plugin.

Average turn around time for a review is 2 business days. This is subject to all the required information being provided at the time your request was submitted.

For internal Squiz developers, if you require assistance, please ask on Slack in #product-funnelback-plugin-help.

Plugin development checklist

The following list covers some of the practices/factors the review team will be looking for when deciding whether to approve or reject a plugin.

We recommend you run through the list yourself before you submit a plugin for review.

Validity

A plugin must satisfy the following, otherwise it will not appear on the extensions page in Funnelback:

  • the plugin version must be a valid semantic version. See semver.org for details.

  • the plugin must indicate where it can run, by having at least one of the following properties set to true in the docs/plugin-details.properties file:

    • runs-on-datasource

    • runs-on-result-page

Tests

Write unit tests which cover the core functionality of your plugin.

  • Use JUnit as the runner for your tests

  • Use small separate unit tests that test one thing rather than large ones that test many at once.

  • Cover both successful and error cases, which should be separate tests.

  • For the error cases, consider especially what might be null in the data model for public-ui hook scripts.

  • Don’t have unit tests connect to external systems - instead mock data from the outside world to ensure tests are self-contained and won’t break when the outside world changes.

    e.g. You should not have a unit test that connects to Instagram, but you would make the connection code as small as possible, and test all your other code with a mock example of what Instagram returns.

  • Provide a Gitlab-CI pipeline which builds your plugin and runs the unit tests.

Logging

Logging is a balancing act, more than likely your log messages will be ignored. But sometimes people might look to find something out.

  • Include logging in your plugin

  • Logging should be done with log4j2.

  • Call your logger log, do this as it is inline with project lombok.

  • Use log.trace("msg") and log.debug("msg") as much as you want, anything to help with development.

  • log.info() should probably never be used. No one is interested.

  • Use log.warn() for someone set something wrong, and they should fix it.

Dependencies

  • Don’t use special version markers RELEASE and LATEST within the <version> element. In particular, update the <version.funnelback-shared>LATEST</version.funnelback-shared> to the version of Funnelback that you are hoping to release to.

  • Try to use the same version of any third-party libraries as Funnelback itself does. An easy way to find this is to look in $SEARCH_HOME/lib/java/all on your development vm. If the product is on an older version than you need, please request that the product to switch to the latest version of that third party dependency.

  • Use the same libraries Funnelback does for a given capability where possible (e.g. use Jackson for JSON parsing, not something else). When adding a library that Funnelback uses, you can add the dependency with a provided scope. For example:

    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>${version.log4j2}</version>
        <scope>provided</scope>
    </dependency>
  • If using a different third party library, please be mindful of the license associated with them. We’re typically okay with Permissive licenses such as MIT or Apache.

  • Ask first if you’re unsure which library to use.

Best practice

  • Indent your code using 4 spaces per level, not tabs.

  • Include inline comments and JavaDoc documentation to explain what methods do and what fields are intended to hold.

  • Use comments to explain the code purpose, not to re-state what the code does

    e.g.

    page++; // go to the next API page
    NOT page++; // increase the value of page by 1
  • Break long methods (more than one screen-full) into separate, helpfully named methods.

  • Ensure any network request your plugin makes specifies timeouts (for connecting, reading and writing).

  • Remove any unused code before submitting your plugin.

  • Include documentation based on the default readme template

  • Consider the memory / how you will ensure that your plugin will have an upper-limit on memory usage to ensure it can’t affect Funnelback’s overall operation.

  • Can you avoid holding an entire response or file in memory at once and instead process it as a stream?

  • Consider the CPU usage of your plugin

  • In particular, be aware that regular expressions on arbitrary input can take exponential time - see: https://en.wikipedia.org/wiki/ReDoS

  • Ensure that your plugin doesn’t hard-code any credentials (e.g. passwords, tokens). These should be read from config.

  • Avoid static methods - such methods make it hard to mock out implementations in tests

  • It is cheap to construct objects when needed? - e.g. new MyUtil().someMethod(a,b,c);

  • Ensure any static fields are marked as final and are immutable

  • Avoid state where you can - It’s usually better to pass arguments to a function than to have that function read and write fields within an object.

  • Plugins must not provide any config settings which might be unsafe in a multi-tenanted environment.

    Things that are unsafe include:

    • Allowing for reading arbitrary paths on the filesystem

    • Allowing for running arbitrary code

    • Allowing for resources (memory, CPU, network) to be consumed without upper limits

  • Don’t rely on internal details of Funnelback, in particular

    • Don’t assume where things exist on disk will be stable

    • Don’t assume that functions in Funnelback classes outside the funnelback-shared project will remain the same over time