Skip to content

Commit

Permalink
Last cleanup
Browse files Browse the repository at this point in the history
Signed-off-by: Mark Hoffmann <m.hoffmann@data-in-motion.biz>
  • Loading branch information
maho7791 committed Sep 3, 2023
1 parent 5f35bad commit 5ddb4ce
Show file tree
Hide file tree
Showing 57 changed files with 624 additions and 119 deletions.
41 changes: 26 additions & 15 deletions .github/workflows/build.yml
Expand Up @@ -9,18 +9,29 @@ env:
GRADLE_OPTS: -Dorg.gradle.parallel=false

jobs:
build:
name: build on OpenJDK Linux
runs-on: ubuntu-latest
steps:
- name: Git Checkout
uses: actions/checkout@v1
- name: Gradle Wrapper Validation
uses: gradle/wrapper-validation-action@v1
- name: Set up Java
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build
shell: bash
run: ./gradlew build
Build_Matrix:
strategy:
matrix:
os: [ ubuntu-latest ]
java: [ 17 ]
runner: [ 'xvfb-run --auto-servernum {0}' ]
name: JDK${{ matrix.java }} ${{ matrix.os }}
runs-on: ${{ matrix.os }}
steps:
- name: Git Checkout
uses: actions/checkout@v3
- name: Gradle Wrapper Validation
uses: gradle/wrapper-validation-action@v1
- name: Set up Java ${{ matrix.java }}
uses: actions/setup-java@v3
with:
distribution: "temurin"
cache: "gradle"
java-version: ${{ matrix.java }}
- name: Grant execute permission for gradlew
run: chmod +x ./gradlew
- name: Gradle version
run: ./gradlew --no-daemon --version
- name: Build with Gradle
run: ./gradlew clean build --info

2 changes: 1 addition & 1 deletion cnf/ext/rsa.mvn
Expand Up @@ -48,7 +48,6 @@ org.apache.felix:org.apache.felix.http.servlet-api:1.1.2
org.apache.felix:org.apache.felix.inventory:1.0.6
org.apache.felix:org.apache.felix.cm.json:1.0.6
org.apache.felix:org.apache.felix.log.extension:1.0.0
org.apache.felix:org.apache.felix.log:1.2.4
org.apache.felix:org.apache.felix.metatype:1.2.4
org.apache.felix:org.apache.felix.scr:2.1.30
org.apache.felix:org.apache.felix.shell.remote:1.2.0
Expand Down Expand Up @@ -139,3 +138,4 @@ org.bouncycastle:bcprov-jdk15on:1.70
org.bouncycastle:bctls-jdk15on:1.70
org.bouncycastle:bcutil-jdk15on:1.70
org.apache.felix:org.apache.felix.configurator:1.0.18
org.apache.felix:org.apache.felix.log:1.3.0
38 changes: 38 additions & 0 deletions org.gecko.playground.ds.config/README.md
@@ -0,0 +1,38 @@
# `org.gecko.playground.ds.config`

This is an example for configurable components.

This project is a multi jar project and produces:

* *org.gecko.playground.ds.config.configadmin* - components a programmatic way of configuration using the Configuration Admin
* *org.gecko.playground.ds.config.configurator* - declarative configured components using the Configurator

It shows how programmatically and declarative component instances can be created.

When running the application you will see this in the console:

```
Activate name-1 from 2001(album-10) from instance AlbumComponent@5398928f
Activate Funky from 1974(Funky, Funky) from instance AlbumComponent@165f68c5
Activate Happy from 2010(I wanna be happy) from instance AlbumComponent@1cea869f
Activate name-2 from 2002(album-20) from instance AlbumComponent@2e10d72b
Activate name-3 from 2003(album-30) from instance AlbumComponent@54da9176
Activate name-4 from 2004(album-40) from instance AlbumComponent@17d8d558
Activate name-5 from 2005(album-50) from instance AlbumComponent@5f5f0ed4
Modified name-1 from 2006(album-15) from instance AlbumComponent@5398928f
Modified name-2 from 2007(album-25) from instance AlbumComponent@2e10d72b
Modified name-3 from 2008(album-35) from instance AlbumComponent@54da9176
Modified name-4 from 2009(album-45) from instance AlbumComponent@17d8d558
Modified name-5 from 2010(album-55) from instance AlbumComponent@5f5f0ed4
De-Activate name-1 from 2006(album-15) from instance AlbumComponent@5398928f
De-Activate name-2 from 2007(album-25) from instance AlbumComponent@2e10d72b
De-Activate name-3 from 2008(album-35) from instance AlbumComponent@54da9176
De-Activate name-4 from 2009(album-45) from instance AlbumComponent@17d8d558
De-Activate name-5 from 2010(album-55) from instance AlbumComponent@5f5f0ed4
```

The albums *Funky* and *Happy* are created by configuration in *config/config.json*. This is published via the OSGi Configurator and the *org.gecko.playground.ds.config.configurator*.

The *name-<something>* Albums are created, then modified and after that removed using the Configuration Admin in the *AlbumCreator* component

The *AlbumComponent* is the configuration factory. It creates a new instance for each new configuration. This can be recognized by the differnet instance id in the log entries.
30 changes: 30 additions & 0 deletions org.gecko.playground.ds.dynamics/README.md
@@ -0,0 +1,30 @@
# `org.gecko.playground.ds.dynamics`

This is an example for shows the *dynamic Reference Policy* in components.

The *ExchangeComponent* has a dynamic reference to the exchange service. It will become active, even, if the exchange service is not available.

Also, if the *ExchangeComponent* is active and the exchange service goes away, it still stays active:

```
g! Dynamic set exchange org.gecko.playground.exchange.impl.ExchangeImpl@10aa41f2
Activate dynamic exchange component
There are 0 orders
g! stop 5
Dynamic unset exchange org.gecko.playground.exchange.impl.ExchangeImpl@10aa41f2
```

Now the exchange service is not there. And the component still exists.

If we now deactivate *ExchangeComponent* an re-activate it, we will see a different log-out, because the exchange service is not available:

```
g! disable org.gecko.playground.ds.dynamics.ExchangeComponent
De-Activate dynamic exchange component
true
g! enable org.gecko.playground.ds.dynamics.ExchangeComponent
true
g! Activate dynamic exchange component
Exchange not available!
```

46 changes: 31 additions & 15 deletions org.gecko.playground.ds.factory/README.md
@@ -1,28 +1,44 @@
# `org.gecko.playground.ds`
# `org.gecko.playground.ds.factory`

This tutorial shows how to work with OSGi *Declarative Service* and how many cool things you can do with them.
This tutorial shows how to work with OSGi *Declarative Service* as a factory.

## Configurable Services (`org.gecko.plaground.ds.config`)
For this we have two different factories:

First of all you can make your service *configurable*, meaning you can provide a set of properties that will customize the instance of your service, without having to repeat the common logic.
* *GardenDeviceFactory* - Creates smart device for your garden
* *HomeDeviceFactory* - Creates smart device for your home and rooms

As soon as the configuration is modified, or even removed, the service instance associated to it will be modified or removed accordingly.
Both are *Device* s

The configuration can be defined in a simple `.json` file, and can then be injected in the activate/modified/deactivate methods, so you have access to it.
The *DeviceHandlerService* injects these instance as *ComponentFactory*. These can create *ComponentInstance* s. Depending on the given type and properties now configured instance can be created using the right factory.

All instances can be disposed, when they are not needed any more

To test this you can use the *DeviceCommands*:

## Component Factory (`org.gecko.playground.ds.factory`)
* `device:createDevice <type> <name>` - creates a new device of type and name
* `device:deleteDevice <name>` - removes the device with the given name

This can be tested:

```
g! createDevice GARDEN Pool-Pump
Activate Instance GARDEN-DEVICE - Pool-Pump
Device created: GARDEN-DEVICE- Pool-Pump (org.gecko.playground.ds.factory.garden.GardenDeviceFactory@254b5fd4)
g! createDevice HOME Smart-TV
Activate Instance HOME-DEVICE - Smart-TV
Device created: HOME-DEVICE- Smart-TV (org.gecko.playground.ds.factory.home.HomeDeviceFactory@6147eaea)
## Greedy Policy (`org.gecko.playground.ds.greedy`)
g! deleteDevice HOME Smart-TV
Dispose device HOME - Smart-TV
Deactivate Instance HOME-DEVICE - Smart-TV
STOP HOME-DEVICE - Smart-TV
Device deleted: HOME- Smart-TV
g! deleteDevice GARDEN Pool-Pump
Dispose device GARDEN - Pool-Pump
Deactivate Instance GARDEN-DEVICE - Pool-Pump
STOP GARDEN-DEVICE - Pool-Pump
Device deleted: GARDEN- Pool-Pump
```



## Prototype Services (`org.gecko.playground.ds.prototype`)

By default, when you define a service, this will be a singleton, meaning, every time you want to reference to that service within the lifetime of an application, you will get the same instance.

If instead you want to get a new instance every time, you can define your service as a *prototype*.
Now the instance are release using the corresponding factory.

16 changes: 0 additions & 16 deletions org.gecko.playground.ds.factory/config/config.json

This file was deleted.

Expand Up @@ -16,12 +16,12 @@
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

@Component(service = WorkmodeCommands.class, property = {
@Component(service = DeviceCommands.class, property = {
"osgi.command.scope=device", //
"osgi.command.function=createDevice",
"osgi.command.function=deleteDevice"
})
public class WorkmodeCommands {
public class DeviceCommands {

@Reference
private DeviceHandler deviceHandler;
Expand Down
29 changes: 29 additions & 0 deletions org.gecko.playground.ds.filter/README.md
@@ -0,0 +1,29 @@
# `org.gecko.playground.ds.filter`

This tutorial shows how to work with OSGi *Declarative Service* references using filtering and selecting the right service.

The *GreeterComponent* referenced to a *GreeterService*. But we have two implementations of it and only want tol select that one with the service propert< *lang=DE*

The *ConfigurableGreeterComponent* uses the configuration in *config/config.json*. The reference for the *GreeterService* got a name *gs*.

The configuration contains the filter, by extending the key with `.target`:

```json
{
":configurator:resource-version": 1,
"CGS":
{
"gs.target": "(lang=EN)"
}
}
```

With this, it is possible to define filters in a declarative / configurable way. This can also be used when directly using the *ConfigurationAdmin*.

When launching the application, you will see the result in the console:

```
Say greeting depending on the configuration: Greetz, Emil
Say greeting in german: Grüße dich, Emil
```

5 changes: 5 additions & 0 deletions org.gecko.playground.ds.filter/bnd.bnd
@@ -0,0 +1,5 @@
-includeresource: \
OSGI-INF/configurator/=config/

Require-Capability: osgi.extender;filter:='(osgi.extender=osgi.configurator)'
-privatepackage: org.gecko.playground.ds.filter
8 changes: 8 additions & 0 deletions org.gecko.playground.ds.filter/config/config.json
@@ -0,0 +1,8 @@
{
":configurator:resource-version": 1,

"CGS":
{
"gs.target": "(lang=EN)"
}
}
12 changes: 9 additions & 3 deletions org.gecko.playground.ds.filter/launch-filter.bndrun
Expand Up @@ -3,13 +3,19 @@
-runrequires: \
bnd.identity;id='org.apache.felix.gogo.command',\
bnd.identity;id='org.apache.felix.gogo.shell',\
bnd.identity;id='org.gecko.playground.ds.filter'
bnd.identity;id='org.gecko.playground.ds.filter',\
bnd.identity;id='org.apache.felix.configadmin'
-runbundles: \
org.apache.felix.gogo.command;version='[1.1.2,1.1.3)',\
org.apache.felix.gogo.runtime;version='[1.1.6,1.1.7)',\
org.apache.felix.gogo.shell;version='[1.1.4,1.1.5)',\
org.apache.felix.scr;version='[2.2.6,2.2.7)',\
org.apache.felix.cm.json;version='[2.0.0,2.0.1)',\
org.apache.felix.configurator;version='[1.0.18,1.0.19)',\
org.apache.felix.configadmin;version='[1.9.26,1.9.27)',\
org.eclipse.parsson.jakarta.json;version='[1.1.2,1.1.3)',\
org.osgi.util.function;version='[1.2.0,1.2.1)',\
org.osgi.util.converter;version='[1.0.9,1.0.10)',\
org.gecko.playground.ds.filter;version=snapshot,\
org.apache.felix.scr;version='[2.2.6,2.2.7)',\
org.osgi.service.component;version='[1.5.1,1.5.2)',\
org.osgi.util.function;version='[1.2.0,1.2.1)',\
org.osgi.util.promise;version='[1.3.0,1.3.1)'
@@ -0,0 +1,28 @@
package org.gecko.playground.ds.filter;

import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.ConfigurationPolicy;
import org.osgi.service.component.annotations.Reference;

@Component(name="CGS", configurationPolicy = ConfigurationPolicy.REQUIRE)
public class ConfigurableGreeterComponent {

private GreeterService greeter;

@Activate
public void activate() {
System.out.println("Say greeting depending on the configuration: " + greeter.greet("Emil"));
}

@Reference(name = "gs")
public void setGreeter(GreeterService greeter) {
this.greeter = greeter;
}

public void unsetGreeter(GreeterService greeter) {
this.greeter = null;
}


}
27 changes: 27 additions & 0 deletions org.gecko.playground.ds.greedy/README.md
@@ -0,0 +1,27 @@
# `org.gecko.playground.ds.greedy`

This tutorial shows how to work with OSGi *Declarative Service* references using greediness.

The *GreedyConsumer* references to an *Important*-Service. We have the less important *ImportantService* implementation and the *VeryImportantService* implementation, that is disabled.

So on start you see that the *ImportantService* was referenced:

```
Welcome to Apache Felix Gogo
g! Activate Greedy Consumer
Set less important service: true, very: false from org.gecko.playground.ds.greedy.impl.ImportantService@d35dea7
```



If you activate the *VeryImportantService* you see, that because of the defined service rank, this instance is more important. The greediness configuration should now take the better version:

```
g! enable VIS
true
g! Set VERY important service: true, very: true from org.gecko.playground.ds.greedy.very.VeryImportantService@4396e1f0
Unset less important service: true, very: false from org.gecko.playground.ds.greedy.impl.ImportantService@d35dea7
```

At first the new instance was set. Afterwards, the old instance has been unsetted.
Expand Up @@ -15,7 +15,7 @@
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Component;

@Component(name="VIS", property = Constants.SERVICE_RANKING + ":Integer=10")
@Component(name="VIS", enabled = false, property = Constants.SERVICE_RANKING + ":Integer=10")
public class VeryImportantService implements Important{

/*
Expand Down
26 changes: 26 additions & 0 deletions org.gecko.playground.ds.scope/README.md
@@ -0,0 +1,26 @@
# `org.gecko.playground.ds.proto`

This tutorial shows how to work with OSGi *Declarative Service* using scoped services.

As example there are two counter components for singleton services and two counter components for protoytpe services.

Running the application prints something like this:

```
Counter 1: 1 with instance org.gecko.playground.ds.scope.CounterService@3be8df3
Counter 1: 2 with instance org.gecko.playground.ds.scope.CounterService@3be8df3
Counter 1: 3 with instance org.gecko.playground.ds.scope.CounterService@3be8df3
Counter 2: 4 with instance org.gecko.playground.ds.scope.CounterService@3be8df3
Counter 2: 5 with instance org.gecko.playground.ds.scope.CounterService@3be8df3
Counter 2: 6 with instance org.gecko.playground.ds.scope.CounterService@3be8df3
Proto Counter 1: 1 with instance CounterImpl@12933a4
Proto Counter 1: 2 with instance CounterImpl@12933a4
Proto Counter 1: 3 with instance CounterImpl@12933a4
Proto Counter 2: 1 with instance CounterImpl@50bd50fd
Proto Counter 2: 2 with instance CounterImpl@50bd50fd
Proto Counter 2: 3 with instance CounterImpl@50bd50fd
```

The two singleton counter components 1 and 2 share the same counter service instance.

The proto counter 1 and 2 getting an own instance of the *CounterImpl*, that is registered as prototype servicec factory in the *CounterPrototypeCreator*.

0 comments on commit 5ddb4ce

Please sign in to comment.