Skip to content
This repository has been archived by the owner on Sep 19, 2024. It is now read-only.

Commit

Permalink
chore(docs): split contributor doc into multiple files (#191)
Browse files Browse the repository at this point in the history
  • Loading branch information
paullatzelsperger authored Aug 13, 2024
1 parent 9addba0 commit b32e10e
Show file tree
Hide file tree
Showing 7 changed files with 2,804 additions and 2,649 deletions.
2,670 changes: 21 additions & 2,649 deletions developer/wip/for-contributors/contributor-handbook.md

Large diffs are not rendered by default.

412 changes: 412 additions & 0 deletions developer/wip/for-contributors/control-plane/dependency-injection.md

Large diffs are not rendered by default.

1,000 changes: 1,000 additions & 0 deletions developer/wip/for-contributors/control-plane/entities.md

Large diffs are not rendered by default.

129 changes: 129 additions & 0 deletions developer/wip/for-contributors/control-plane/extension-model.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# The EDC Extension Model

<!-- TOC -->

* [The EDC Extension Model](#the-edc-extension-model)
* [1. Extension basics](#1-extension-basics)
* [2. Autodoc and Metamodel Annotations](#2-autodoc-and-metamodel-annotations)
* [3. Configuration and best practices](#3-configuration-and-best-practices)

<!-- TOC -->

## 1. Extension basics

Three things are needed to register an extension module with the EDC runtime:

1. a class that implements `ServiceExtension`
2. a [provider-configuration file](https://docs.oracle.com/javase/7/docs/api/java/util/ServiceLoader.html)
3. adding the module to your runtime's build file. EDC uses Gradle, so your runtime build file should contain

```groovy
runtimeOnly(project(":module:path:of:your:extension"))
```

Extensions should **not** contain business logic or application code. Their main job is to

- read and handle [configuration](./extension-model.md#3-configuration-and-best-practices)
- instantiate and register services with the service context (read more [here](./dependency-injection.md))
- allocate and free resources, for example scheduled tasks

## 2. Autodoc and Metamodel Annotations

EDC can automatically generate documentation about its extensions, about the settings used therein and about its
extension points. This feature is available as Gradle task:

```bash
./gardlew autodoc
```

Upon execution, this task generates a JSON file located at `build/edc.json`, which contains structural information about
the extension, for example:

<details>
<summary>Autodoc output in edc.json</summary>

```json
[
{
"categories": [],
"extensions": [
{
"categories": [],
"provides": [
{
"service": "org.eclipse.edc.web.spi.WebService"
},
{
"service": "org.eclipse.edc.web.spi.validation.InterceptorFunctionRegistry"
}
],
"references": [
{
"service": "org.eclipse.edc.web.spi.WebServer",
"required": true
},
{
"service": "org.eclipse.edc.spi.types.TypeManager",
"required": true
}
],
"configuration": [
{
"key": "edc.web.rest.cors.methods",
"required": false,
"type": "string",
"description": "",
"defaultValue": "",
"deprecated": false
}
// other settings
],
"name": "JerseyExtension",
"type": "extension",
"overview": null,
"className": "org.eclipse.edc.web.jersey.JerseyExtension"
}
],
"extensionPoints": [],
"modulePath": "org.eclipse.edc:jersey-core",
"version": "0.8.2-SNAPSHOT",
"name": null
}
]
```

</details>

To achieve this, the [EDC Runtime Metamodel](https://github.com/eclipse-edc/Runtime-Metamodel) defines several
annotations. These are not required for compilation, but they should be added to the appropriate classes and fields with
proper attributes to enable good documentation.

Note that `@Provider`, `@Inject`, `@Provides` and `@Requires` are used by Autodoc to resolve the dependency graph for
documentation, but they are also used by the runtime to resolve service dependencies. Read more about that
[here](./dependency-injection.md).

## 3. Configuration and best practices

One important task of extensions is to read and handle configuration. For this, the `ServiceExtensionContext` interface
provides the `getConfig()` group of methods.

Configuration values can be _optional_, i.e. they have a default value, or they can be _mandatory_, i.e. no default
value. Attempting to resolve a mandatory configuration value that was not specified will raise an `EdcException`.

EDC's configuration API can resolve configuration from three places, in this order:

1. from a `ConfigurationExtension`: this is a special extension class that provides a `Config` object. EDC ships with a
file-system based config extension.
2. from environment variables: `edc.someconfig.someval` would map to `EDC_SOMECONFIG_SOMEVAL`
3. from Java `Properties`: can be passed in through CLI arguments, e.g. `-Dedc.someconfig.someval=...`

Best practices when handling configuration:

- resolve early, fail fast: configuration values should be resolved and validated as early as possible in the
extension's `initialize()` method.
- don't pass the context: it is a code smell if the `ServiceExtensionContext` is passed into a service to resolve config
- annotate: every setting should have a `@Setting` annotation
- no magic defaults: default values should be declard as constants in the extension class and documented in the
`@Setting` annotation.
- no secrets: configuration is the wrong place to store secrets
- naming convention: every config value should start with `edc.`
Loading

0 comments on commit b32e10e

Please sign in to comment.