https://github.com/pf4j/pf4j-update
Update mechanism for PF4J
https://github.com/pf4j/pf4j-update
java modularity pf4j plugins update
Last synced: 9 months ago
JSON representation
Update mechanism for PF4J
- Host: GitHub
- URL: https://github.com/pf4j/pf4j-update
- Owner: pf4j
- License: apache-2.0
- Created: 2014-06-26T13:29:34.000Z (over 11 years ago)
- Default Branch: master
- Last Pushed: 2024-10-12T16:33:58.000Z (about 1 year ago)
- Last Synced: 2025-04-12T06:08:14.158Z (9 months ago)
- Topics: java, modularity, pf4j, plugins, update
- Language: Java
- Homepage:
- Size: 412 KB
- Stars: 68
- Watchers: 12
- Forks: 41
- Open Issues: 9
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
PF4J - Update
=====================
[](https://travis-ci.org/pf4j/pf4j-update)
[](http://search.maven.org/#search|ga|1|pf4j-update)
The goal of this project is to supply an update mechanism for [PF4J](https://github.com/pf4j/pf4j).
It's an open source (Apache license) lightweight (around 15KB) extension for PF4J, with minimal dependencies (only pf4j and gson).
Components
-------------------
- **UpdateManager** allows you to inspect the repositories (local, remote) for updates, available (new) plugins. Also this class allows you to install available plugins, update or uninstall existing plugins.
- **UpdateRepository** defines a local/remote repository (pluggable)
- **PluginInfo** defines the plugin information for each repository's plugin
- **PluginRelease** defines a plugin release
- **FileDownloader** defines a pluggable way of downloading from a repository
- **FileVerifier** defines a pluggable way of verifying downloaded files, e.g. checksum verification
Using Maven
-------------------
In your pom.xml you must define the dependencies to PF4J artifacts with:
```xml
org.pf4j
pf4j-update
${pf4j-update.version}
```
where ${pf4j-update.version} is the last pf4j-update version.
You may want to check for the latest released version using [Maven Search](http://search.maven.org/#search%7Cga%7C1%7Cpf4j-update)
How to use
-------------------
It's very simple to add pf4j-update in your application.
The whole code of below snippet is available on [Github](https://github.com/pf4j/pf4j-update/blob/master/src/test/java/org/pf4j/update/util/TestApplication.java).
```java
public static void main(String[] args) {
...
// create plugin manager
PluginManager pluginManager = new DefaultPluginManager();
pluginManager.loadPlugins();
// create update manager
UpdateManager updateManager = new UpdateManager(pluginManager);
// >> keep system up-to-date <<
boolean systemUpToDate = true;
// check for updates
if (updateManager.hasUpdates()) {
List updates = updateManager.getUpdates();
log.debug("Found {} updates", updates.size());
for (PluginInfo plugin : updates) {
log.debug("Found update for plugin '{}'", plugin.id);
PluginInfo.PluginRelease lastRelease = updateManager.getLastPluginRelease(plugin.id);
String lastVersion = lastRelease.version;
String installedVersion = pluginManager.getPlugin(plugin.id).getDescriptor().getVersion();
log.debug("Update plugin '{}' from version {} to version {}", plugin.id, installedVersion, lastVersion);
boolean updated = updateManager.updatePlugin(plugin.id, lastVersion);
if (updated) {
log.debug("Updated plugin '{}'", plugin.id);
} else {
log.error("Cannot update plugin '{}'", plugin.id);
systemUpToDate = false;
}
}
} else {
log.debug("No updates found");
}
// check for available (new) plugins
if (updateManager.hasAvailablePlugins()) {
List availablePlugins = updateManager.getAvailablePlugins();
log.debug("Found {} available plugins", availablePlugins.size());
for (PluginInfo plugin : availablePlugins) {
log.debug("Found available plugin '{}'", plugin.id);
PluginInfo.PluginRelease lastRelease = updateManager.getLastPluginRelease(plugin.id);
String lastVersion = lastRelease.version;
log.debug("Install plugin '{}' with version {}", plugin.id, lastVersion);
boolean installed = updateManager.installPlugin(plugin.id, lastVersion);
if (installed) {
log.debug("Installed plugin '{}'", plugin.id);
} else {
log.error("Cannot install plugin '{}'", plugin.id);
systemUpToDate = false;
}
}
} else {
log.debug("No available plugins found");
}
if (systemUpToDate) {
log.debug("System up-to-date");
}
...
}
```
The library has very few components. The main component is the **UpdateManager**.
This class contains methods for repositories inspection
```java
public List getAvailablePlugins();
public boolean hasAvailablePlugins();
public List getUpdates();
public boolean hasUpdates();
public List getPlugins();
public List getRepositories();
```
and methods for plugin handling
```java
public boolean installPlugin(String url);
public boolean updatePlugin(String id, String url);
public boolean uninstallPlugin(String id);
```
UpdateManager can work with multiple repositories (local and remote).
All repositories are either defined in a `repositories.json` file or
provided in UpdateManager's constructor.
Below I defined two repository: localhost and folder.
```json
[
{
"id": "localhost",
"url": "http://localhost:8081/"
},
{
"id": "folder",
"url": "file:/home/decebal/work/pf4j-update/downloads/"
}
]
```
Each repository has a unique id and a URL.
In the root of this project you have a `repositories.json` file used by
the test applications.
For more information please see the test sources (UpdateTest, ...).
It's a good idea to run these tests and to see the results.
Customization
-------------
The project is made for customization and extension to your own needs. Here are some
examples:
### Tailor repository loading
First you can supply to `UpdateManager` your custom location and name
of `repositories.json` if you want it to live somewhere else.
If you need even more control, `UpdateManager` accepts repositories in
constructor and through setters.
Implement your own `UpdateRepository`, `FileDownloader` and `FileVerifier`s
to handle your own custom repsitory structures, authentication, checksum
verifications etc.
### Subclass UpdateManager
For full control, subclass `UpdateManager` and override relevant methods.
Repository structure
-------------------
Each repository exposes multiple plugins using a `plugins.json` file.
Below I registered two plugins: _welcome-plugin_ and _hello-plugin_.
```json
[
{
"id": "welcome-plugin",
"description": "Welcome plugin",
"releases": [
{
"version": "0.8.0",
"date": "Jun 5, 2014 9:00:35 PM",
"url": "pf4j-demo-plugin1/0.8.0/pf4j-demo-plugin1-0.8.0.zip"
},
{
"version": "0.9.0",
"date": "Jun 25, 2014 9:58:35 PM",
"url": "pf4j-demo-plugin1/0.9.0/pf4j-demo-plugin1-0.9.0.zip"
}
]
},
{
"id": "hello-plugin",
"description": "Hello plugin",
"releases": [
{
"version": "0.8.0",
"date": "Jun 5, 2014 9:12:35 PM",
"url": "pf4j-demo-plugin2/0.8.0/pf4j-demo-plugin2-0.8.0.zip"
},
{
"version": "0.9.0",
"date": "Jun 25, 2014 9:58:35 PM",
"url": "pf4j-demo-plugin2/0.9.0/pf4j-demo-plugin2-0.9.0.zip"
}
]
}
]
```
### plugins.json
**Fields per plugin**
|Property |Format |Description |
|------------|-------------|-----------------------------------|
|id |string |Unique id, mandatory |
|name |string |Display name (short) |
|description |string |Describe your plugin |
|provider |string |Name of plugin provider |
|releases |List |List of releases (minimum one) |
**Fields per release**
|Property |Format |Description |
|------------|-------------|-----------------------------------|
|version |X.Y.Z |Version of release ([SemVer](http://semver.org/) format) |
|date |date |Release date, ISO8601 or `yyyy-MM-dd` format |
|requires |Expression |[SemVer expression](https://github.com/zafarkhaja/jsemver#semver-expressions-api-ranges), e.g. ">=2.0.0" |
|url |URL-string |Link to zip, either absolute or relative URL |
|sha512sum |<sha512-digest>
*or* <hash-file URL>
*or* ".sha512" |String with SHA-512 HEX digest of file content
URL to file with SHA-512 string
Fetch SHA-512 file next to plugin, with `.sha512` file suffix |
*New properties may appear in the future.*
The last (current) release of the plugin is calculated taking into account
by the _version_ property. In our example, the last release for each
plugin is the release with version _0.9.0_.
We encourage using `yyyy-MM-dd` format for release date. Localized US format
as in the examples above will also work. If the date is not parsable, it
will be set to epoch (1970-01-01) and print a warning in logs.
**NOTE**: The `requires` property was a simple X.Y.Z string in versions
up to 0.3.0, interpreted as `>=X.Y.Z`. You may want to update your old
`plugins.json` files to the new syntax.
### Example for 'hello-plugin' (plugin2):
URL from `repositories.json`: `http://localhost:8081/`
Relative URL in `plugins.json`: `pf4j-demo-plugin2/0.8.0/pf4j-demo-plugin2-0.8.0.zip`
Resulting `UpdateRepository.PluginRelease.url`: `http://localhost:8081/pf4j-demo-plugin2/0.8.0/pf4j-demo-plugin2-0.8.0.zip`
In the _downloads_ folder of the project you have a repository (plugins.json and artifacts - plugins archives) used by the test applications.
The structure of the repository is:
- plugin1
- 0.8.0
- plugin1.zip
- 0.9.0
- plugin1.zip
- plugin2
- 0.8.0
- plugin2.zip
- 0.9.0
- plugin2.zip
- plugins.json
For each plugin you have a folder (plugin1, plugin2) that contains subfolder for each version (0.8.0, 0.9.0).
In each version folder you have the plugin archive (.zip) according to PF4J specification.
Mailing list
--------------
Much of the conversation between developers and users is managed through [mailing list](http://groups.google.com/group/pf4j).
Versioning
------------
This project will be maintained under the Semantic Versioning guidelines as much as possible.
Releases will be numbered with the follow format:
`..`
And constructed with the following guidelines:
* Breaking backward compatibility bumps the major
* New additions without breaking backward compatibility bumps the minor
* Bug fixes and misc changes bump the patch
For more information on SemVer, please visit http://semver.org/.