Giter VIP home page Giter VIP logo

addon-java-sdk's Introduction

Addon SDK is a framework that is written in Java and offers abstractions to get up and running with the development of addons for the CAKE.com marketplace.

The SDK is intended to be easy to use and intuitive.

More features are planned and will be added to the SDK.

Installation

Maven must be configured as described here before the Addons SDK can be installed.

Once you have configured the required settings, you can import the Addons SDK into your project by adding the following dependency to your pom.xml file:

<dependency>
    <groupId>com.cake.clockify</groupId>
    <artifactId>addon-sdk</artifactId>
    <version>${addonssdk.version}</version>
</dependency>

Project

The project is organized in two modules:

  • the annotation processor
  • the addon SDK

Annotation processor

The annotation processor module is only used at build-time. It generates helper interfaces based on the manifest schema.

Clockify manifest makes use of the @ExtendClockifyManifest annotation in order to let the annotation processor know that it should generate interfaces for this class's builder according the specified definition.

For instance, suppose we have the following definition inside the json schema:

"definitions": {
    "lifecycle": {
      "properties": {
        "path": {...},
        "type": {
          "enum": [
            "INSTALLED",
            "DELETED",
            "SETTINGS_UPDATED"
          ]
        }
      },
      "required": [...]
    }
    ...
}

The annotation processor will generate the following interfaces:

public interface ClockifyLifecycleEventBuilderPathStep {
    ClockifyLifecycleEventBuilderTypeStep path(String value);
}

public interface ClockifyLifecycleEventBuilderTypeStep {
    ClockifyLifecycleEventBuilderBuildStep type(String value);

    default ClockifyLifecycleEventBuilderBuildStep onInstalled() {
        return type ("INSTALLED");
    }

    default ClockifyLifecycleEventBuilderBuildStep onDeleted() {
        return type ("DELETED");
    }

    default ClockifyLifecycleEventBuilderBuildStep onSettingsUpdated() {
        return type ("SETTINGS_UPDATED");
    }
}

public interface ClockifyLifecycleEventBuilderBuildStep {
    ClockifyLifecycleEvent build();
}

The above interfaces, combined with a Lombok builder result in a straightforward step-builder implementation.

public class ClockifyLifecycleEvent extends LifecycleEvent {

    @Builder
    protected ClockifyLifecycleEvent(@NonNull String type, @NonNull String path) {
        super(type, path);
    }

    public static ClockifyLifecycleEventBuilderPathStep builder() {
        return new ClockifyLifecycleEventBuilder();
    }

    private static class ClockifyLifecycleEventBuilder implements
            ClockifyLifecycleEventBuilderTypeStep,
            ClockifyLifecycleEventBuilderPathStep,
            ClockifyLifecycleEventBuilderBuildStep {
    }
}

Each required property will have its own step, and each step will only be able to set one property.

ClockifyLifecycleEvent lifecycle = ClockifyLifecycleEvent
                .builder()
                .path("/lifecycle")
                .onInstalled()
                .build();

Addon SDK

The SDK is structured into two parts, the shared codebase and the product-specific codebase:

  • shared
  • clockify, pumble, plaky

The product-specific layers will allow for more granular configuration and validation as well as provide specific helper classes.

Features

  • Predefined POJO models
  • Product specific validation & helpers
  • Centralized definition and handling of all the components of the addon
  • Easy to get started by either relying on the embedded webserver or serving the provided servlet class through a web framework

Getting started

First, create an addon instance:

ClockifyAddon clockifyAddon = new ClockifyAddon(
        ClockifyManifest.builder()
        .key(key)
        .name(name)
        .baseUrl(baseUrl)
        .requireBasicPlan()
        .scopes(Collections.emptyList())
        .build()
        );

The baseUrl must be a full URI, with the scheme, host and path.

Then, register any webhook / lifecycle / component / setting or custom endpoints on the addon.

Each object has its own builder class which by using the step builder pattern guides through the instantiation of the object and makes it easy to distinguish between required and optional properties.

 ClockifyComponent component = ClockifyComponent
        .builder()
        .activityTab()
        .allowAdmins()
        .path("/component")
        .options(Map.of("opt1", "val1"))
        .build();

ClockifySetting number = ClockifySetting.builder()
        .id("id")
        .name("name")
        .asNumber()
        .value(12)
        .build();

ClockifySetting multipleSetting = ClockifySetting.builder()
        .id("id")
        .name("name")
        .asDropdownMultiple()
        .value(List.of("1", "2"))
        .allowedValues(List.of("1", "2", "3"))
        .build();


RequestHandler<HttpRequest> handler = new RequestHandler() { ... }
clockifyAddon.registerComponent(component, handler);
...

Addon-specific filters can be registered for requests that will be handled through the addon's servlet.

Filter filter = ...; // servlet filter
clockifyAddon.addFilter(filter);

Serving the addon

Using the embedded jetty server

AddonServlet servlet = new AddonServlet(clockifyAddon);
EmbeddedServer server = new EmbeddedServer(servlet);
server.start(port);

Serving via spring boot (or any other framework)

import addonsdk.shared.Addon;
import addonsdk.shared.AddonServlet;

@WebServlet(...)
public class AppServlet extends AddonServlet {

    public AppServlet(Addon addon) {
        super(addon);
    }
}

Documentation

Manifest

The central part of an addon is its manifest. The manifest defines the basic information related to the addon, as well as the components and the routes that it supports.

A handler is automatically registered on the GET '/manifest' path when an addon object is instantiated.

When invoked, this handler will return a JSON containing the serialized manifest.

Handlers

The following arguments are required when registering a handler:

  • the HTTP method
  • the relative path
  • the handler itself

If the handler is being registered through either a component / lifecycle / webhook, the inferred HTTP method will depend on the type of the object itself.

  • component -> GET
  • lifecycle -> POST
  • webhook -> POST

Each addon implementation will only accept its own component / lifecycle / webhook subclasses.

addon-java-sdk's People

Contributors

gericlockify avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.