API framework for Ligoj plugins
Requirements: Java 25, Maven 3.9.16+. Built on Ligoj Bootstrap (org.ligoj.bootstrap:bootstrap-business-parent).
- parent: parent POM of the modules of this repository, built on the bootstrap business parent.
- plugin-api: the extension points, following semver: plugin definitions and IAM interfaces.
- plugin-core: the shared model, repositories and REST resources (nodes, subscriptions, parameters, projects, delegations, tasks, events) and the base classes of the plugins.
- plugin-api-test: the test support of the plugins: Spring test context, CSV fixtures and base test classes.
- plugin-iam-empty: an empty, read-only IAM provider, for tests.
- plugin-parent: the parent POM of every plugin.
org.ligoj.bootstrap.core.plugin.FeaturePlugin(bootstrap): the base of all plugins: key (feature:iam:empty,service:id:ldap, ...),install,updateand the entities to install fromcsv/files.- org.ligoj.app.api.ServicePlugin: a service (first level node, such as
service:id) or a tool (second level, such asservice:id:ldap) handling subscriptions. - org.ligoj.app.api.ToolPlugin: a tool with versions and status checks of its node instances and subscriptions.
- org.ligoj.app.api.ConfigurablePlugin: a plugin exposing a configuration per subscription.
- org.ligoj.app.resource.ActivitiesProvider: the activities of users on a subscription, such as their last activity on the tool.
The base classes plugins usually extend, in plugin-core:
- AbstractServicePlugin and AbstractToolPluginResource. The latter rejects the
CREATEsubscription mode by default. - AbstractConfiguredServicePlugin: configuration entities attached to a subscription. Use
findConfiguredto read them andfindConfiguredManagedbefore any change: the latter also requires the subscriptions of the project to be managed by the user. - LongTaskRunnerNode and LongTaskRunnerSubscription: long running tasks, one at a time per node or subscription.
- ServicePluginLocator: the plugin resource of a node.
- LigojPluginsClassLoader:
toPath(node)/toPath(subscription, ...), the file storage of a node or subscription.
- org.ligoj.app.iam.IamProvider: Identity and Access Management (IAM) provider of the application.
- org.ligoj.app.iam.IamConfigurationProvider
- org.ligoj.app.iam.IAuthenticationContributor
- org.ligoj.app.iam.ICompanyRepository
- org.ligoj.app.iam.IContainerRepository
- org.ligoj.app.iam.IGroupRepository
- org.ligoj.app.iam.IUserRepository
- org.ligoj.app.iam.IPasswordGenerator
The keys read by plugin-core, as ${...} placeholders of the application properties (see the configuration reference of the Ligoj application for the other keys):
| Key | Default | Description |
|---|---|---|
health.node |
none | Mandatory. CRON expression of the health check of the nodes. Without it, the application does not start. |
health.subscription |
none | Mandatory. CRON expression of the health check of the subscriptions. Without it, the application does not start. |
event.retention |
365 |
Retention in days of the status events. The last event of each node and subscription, holding its current status, is kept. |
event.purge |
0 0 4 * * ? |
CRON expression of the purge of the expired events. |
user-log.retention |
30 |
Retention in days of the user logs (browser side errors posted to /user-log). |
user-log.purge |
0 0 3 * * ? |
CRON expression of the purge of the expired user logs. |
Caches declared by plugin-core with a lifetime, adjustable with the bootstrap cache.<name>.ttl key:
node-parametersandsubscription-parameters: 1 hour. The parameter values of the nodes and the subscriptions, cleared on any node parameter change.node-health-lock: 1 hour. The cluster-wide lock of the scheduled health checks: a member skips its run while another member holds it. A run longer than this lifetime loses the lock, and may then overlap with the run of another member.
Minimal Maven structure for a plugin:
- Version, following the semver convention
- Plugin artifact id, derived from the plugin key without its first part: the key
service:id:ldapgivesplugin-id-ldap, the keyfeature:iam:emptygivesplugin-iam-empty- A tool plugin's artifact id starts with the artifact id of its service plugin. For sample, plugin
plugin-id-ldapis a tool plugin for the serviceplugin-id. - Otherwise, it is
plugin-followed by a single name, without additional hyphen.
- A tool plugin's artifact id starts with the artifact id of its service plugin. For sample, plugin
- Parent service plugin artifact as
provideddependency.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.ligoj.api</groupId>
<artifactId>plugin-parent</artifactId>
<version>5.0.6</version> <!-- Version of plugin API -->
<relativePath />
</parent>
<groupId>org.ligoj.plugin</groupId>
<artifactId>plugin-id-ldap</artifactId> <!-- Tool plugin artifact-id, must start with "plugin-" -->
<version>1.1.3-SNAPSHOT</version> <!-- Tool plugin version -->
<packaging>jar</packaging>
<!-- Feature dependency -->
<dependencies>
<dependency>
<groupId>org.ligoj.plugin</groupId>
<artifactId>plugin-id</artifactId> <!-- Service plugin artifact-id -->
<version>[2.2.0-SNAPSHOT,2.3.0)</version> <!-- Service plugin version range -->
<scope>provided</scope> <!-- Always provided -->
</dependency>
</dependencies>
</project>Produced artifacts for a plugin named plugin-id-ldap are:
- Main jar file:
plugin-id-ldap-1.0.0.jar - Javadoc jar file:
plugin-id-ldap-1.0.0-javadoc.jar. Optional, but when deployed, contributes to generated OpenAPI JSON file. - Sources jar file:
plugin-id-ldap-1.0.0-sources.jar. Optional. - Test sources jar file:
plugin-id-ldap-1.0.0-test-sources.jar. Optional. - Jacoco coverage result
The following command generates all artifacts and runs the unit and integration tests (integration tests are skipped without the it profile):
mvn verify -Pjavadoc,jacoco,sources,itplugin-parent also provides these auto-activated profiles:
code-sign: signs the plugin jar withjarsigner, when~/.ligoj/code-signing.p12exists. The keystore password comes from theLIGOJ_SIGN_STOREPASSenvironment variable or theligoj.sign.storepassproperty;-Djarsigner.skip=trueskips the signature. The signature is verified at startup by the application against the truststore set by theligoj.plugin.signature.truststoresystem property, by defaultplugin-vendors.p12in the Ligoj home directory, opened with theligoj.plugin.signature.truststore.passwordsystem property (defaultchangeit). A truststore created with another password is not loaded. See the comments of plugin-parent/pom.xml to create the keystore and the truststore.ui-build: builds the Vue.js front-end of the plugin whenui/package.jsonexists, with a Node version downloaded undertarget/(ui.node.version);-Dskip.ui.build=trueskips it.
# Build and run the unit tests, install the modules locally
mvn clean install
# With the integration tests and the coverage
mvn clean verify -Pit,jacocoTest failures do not fail the build (testFailureIgnore from the parent POMs): check the Tests run: … Failures: … Errors: … lines.
The common steps:
- Login to application
- Go to the
Administrationpage - Choose the
Pluginsection
The specific steps:
- Click on
Install > Install from file - In the modal, fill the inputs accordingly to your plugin
- Upload it
- Restart the application
The specific steps:
- Click on
Install > Install from repository - In the modal, type the artifact name
- Choose one or many plugins
- Confirm
- Restart the application
The Ligoj CLI is an administration tool for all Ligoj API operations.
See all command options with ligoj plugin
The command is:
ligoj plugin upload --id "plugin-id-ldap" --version "1.1.4" --from "/path/to/plugin-id-ldap-1.1.4.jar"The command is:
ligoj plugin install --id "plugin-id-ldap" --version "1.1.4" --repository "central" --javadoc