[Developers] Improve prerequisites section (#407)
Some of the articles are extended. Coding tasks slightly changed. Added troubleshooting section for Declarative Services. Signed-off-by: Svilen Valkanov <svilen.valkanov@musala.com>pull/307/merge
parent
58294b579b
commit
712825dbdd
|
@ -16,7 +16,7 @@ import org.osgi.framework.ServiceRegistration;
|
|||
/**
|
||||
* The class {@link TVActivator} is responsible for the activation of this
|
||||
* bundle.
|
||||
*
|
||||
*
|
||||
* @author Kiril Atanasov - Initial contribution
|
||||
*/
|
||||
public class TVActivator implements BundleActivator {
|
||||
|
@ -49,7 +49,7 @@ public class TVActivator implements BundleActivator {
|
|||
tracker.open();
|
||||
|
||||
// The TV is starting to consume power from the providers
|
||||
tracker.getTV().start();
|
||||
tracker.getTV().startConsuming();
|
||||
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ public class TVActivator implements BundleActivator {
|
|||
*/
|
||||
@Override
|
||||
public void stop(BundleContext context) throws Exception {
|
||||
tracker.getTV().stop();
|
||||
tracker.getTV().stopConsuming();
|
||||
tvServiceRegistration.unregister();
|
||||
tracker.close();
|
||||
}
|
||||
|
|
|
@ -99,6 +99,21 @@ A bundle can therefore register a service, it can get a service and it can track
|
|||
![OSGi Services][fig3]
|
||||
Fig.3 OSGi Services (Source: <https://www.osgi.org/wp-content/uploads/services.png>)
|
||||
|
||||
Popular OSGi Containers
|
||||
-----------------------
|
||||
|
||||
We have talked so far about the OSGi specification. Here is the place to emphasize that the different containers might implement different parts of the OSGi specifications and might provide slightly different API (which could make the bundle not fully portable between different containers).
|
||||
|
||||
We will list the most popular OSGi containers with a short description of their goals. We can divide them into:
|
||||
|
||||
- open source:
|
||||
- [Equinox](https://www.eclipse.org/equinox/) - this is the reference implementation of the OSGi R4.x Core Specification and one of the mostly used. As it is used in the openHAB project, we have prepared a [wiki page](equinox.html);
|
||||
- [Apache Felix](http://felix.apache.org/) - implements OSGi R5 Core Specification, developed by the Apache Software Foundation. [Apache Karaf](http://karaf.apache.org/) is distribution based on Apache Felix that provides some additional features on top of it (e.g. folder based hot deployment, improved default console with remote SSH, maven plugins and others);
|
||||
- [Concierge](https://www.eclipse.org/concierge/) - implements OSGi R5 Core Specification and is aimed at mobile and embedded devices. With a size of around 250 kb it has the smallest footprint of the presented containers;
|
||||
|
||||
- commercial:
|
||||
- [ProSyst OSGi Framework](http://dz.prosyst.com/pdoc/mBS_SDK_8.1/modules/framework/overview/framework.html) - implements OSGi R5 Core and Compendium Specification. This implementation is low-footprint, optimized for embedded products, provides custom remote management agent and many more additional components.
|
||||
|
||||
Important Definitions
|
||||
---------------------
|
||||
|
||||
|
|
|
@ -72,7 +72,12 @@ In this example our component needs a [LogService](https://osgi.org/javadoc/r4v4
|
|||
|
||||
### 1. Service Component Description
|
||||
|
||||
This is the XML component description. This file is located in the *OSGI-INF* folder and is named *consumer.xml*:
|
||||
This is the XML component description. This file is located in the *OSGI-INF* folder and is named *consumer.xml*.
|
||||
|
||||
Note! Please keep in mind that the Service Component Description might be
|
||||
automatically generated using SCR Annotations like @Component, @Reference,
|
||||
@Activate, @Deacticate and etc that are supported e.g. in Apache Felix. Currently
|
||||
these annotations are not used in the openHAB project, so please ignore examples where they are used.
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
@ -101,8 +106,8 @@ This is the XML component description. This file is located in the *OSGI-INF* f
|
|||
Let's take a look at some settings, that we can apply:
|
||||
|
||||
- **immediate**:
|
||||
- *true* - the component is activated as soon as all dependencies are satisfied;
|
||||
- *false* - the component has lazy activation. The activation of the component is delayed until the service is requested. This is the default value;
|
||||
- *true* - the component is activated as soon as all dependencies are satisfied. Adding this option will ensure that the component will be activated right after the bundle is activated and the component is satisfied;
|
||||
- *false* - the component has lazy activation. The activation of the component is delayed(lazy activation) until the service is requested. This is the default value;
|
||||
- **cardinality**:
|
||||
- *1..1* - single service reference, that is mandatory. If your referenced service gets inactive, DS deactivates your service component as well (default value);
|
||||
- *0..1* - single service reference(not mandatory). You have to be aware that you might not have your reference resolved, your component can live with the absence;
|
||||
|
@ -262,7 +267,6 @@ The component **configuration is satisfied** when:
|
|||
|
||||
- component is **enabled**;
|
||||
- all the **component references are satisfied**. A reference is satisfied when the reference specifies optional cardinality or there is at least one target service for the reference.
|
||||
|
||||
If the component has lazy initialization (the component is *delayed*), it is moved to the REGISTERED state and it is waiting to be activated, when the service is requested (see Fig.2).
|
||||
Otherwise (the component is *immediate*) as soon as its dependencies are satisfied, the component is activated (see Fig.1).
|
||||
|
||||
|
@ -290,7 +294,22 @@ For more information - [OSGi 4.2 Compendium Specifiaction, Chapter 112.5 Compone
|
|||
|
||||
If you want to practice, what you have learned so far, you can try out our [OSGi Coding tasks](osgitasks.html). In chapter IV. there are tasks, that are using OSGi DS. It is recommended to start from the beginning (chapter I.), as the tasks are related between each other.
|
||||
|
||||
## VIII. Further Reading
|
||||
## VIII. Troubleshooting
|
||||
|
||||
If you are new to Declarative Services and you don't know how to troubleshoot, maybe we can help you. We will give you a few tips what might have gone wrong. Some of the steps below depend on your development IDE and the OSGi Container that you use. Mind that most of the tips below are specific to Eclipse IDE and Equinox as the OSGi Runtime. You might review again the [Equinox commands](equinox.html#iv-commands) before you continue:
|
||||
|
||||
- make sure that your Component Description (the XML file) contains the necessary information to provide or reference service (see the examples above);
|
||||
- make sure that your Component Description is placed in the OSGI-INF folder;
|
||||
- [Eclipse IDE only] make sure that no warnings are displayed in the Component Description file (a warning might indicate that some of the class names that you have used are not correct !);
|
||||
- open the bundle manifest file (located in META-INF/MANIFEST.MF) and check if your Component Description is added in the "Service-Component" header (it can be added as "OSGI-INF/*.xml or "OSGI-INF/component.xml");
|
||||
- [Eclipse IDE only] open the build.properties file and make sure that the Component Description is added in the bin.includes entry (it can be added as "OSGI-INF/" or "OSGI-INF/component.xml"). If it is not included in the build.properties file, it will not end in the .jar file that will be deployed in the Equinox runtime and SCR will be not able to find it;
|
||||
- Start the runtime and check the log. Do you see any Errors like "MESSAGE [SCR] Error while trying to bind reference"? Read the error message and proceed accordingly.
|
||||
- Make sure that the bundle that is providing the service is in "ACTIVE" state, if it is not, start it manually with the "start id" command, where id is the id of the bundle;
|
||||
- [Equinox only] While the runtime is running type the "services" command and search if your service is registered. In case it is not registered, most probably you have missed some of the steps above :);
|
||||
- [Equinox only] While the runtime is running type "ls -c id", where id is the id of the bundle that is providing the service. This will give detailed information about the services that are registered by this bundle, read the information if the component is satisfied carefully;
|
||||
- Is your service in use? In case it is not and you are not seeing it registered, the component might have lazy activation policy(this is the default policy). Add "immediate=true" in your Component Definition if you like to change the activation policy.
|
||||
|
||||
## XIX. Further Reading
|
||||
|
||||
- [*OSGi Service Platform Service Compendium, Release 4, Version 4.2,
|
||||
August 2009*](https://osgi.org/download/r4v42/r4.cmpn.pdf)
|
||||
|
|
|
@ -28,7 +28,7 @@ The tasks are divided in several sections:
|
|||
* TOC
|
||||
{:toc}
|
||||
|
||||
Sample implementations of the tasks will be added in the [openHAB docs repo](https://github.com/openhab/openhab-docs/tree/gh-pages/_sample_code/osgi_codings_tasks/bundles).
|
||||
Sample implementations are present in the [openHAB docs repo](https://github.com/openhab/openhab-docs/tree/gh-pages/_sample_code/osgi_codings_tasks/bundles).
|
||||
|
||||
### I. Writing basic OSGi bundle
|
||||
|
||||
|
@ -57,8 +57,8 @@ Sample implementations of the tasks will be added in the [openHAB docs repo](htt
|
|||
|
||||
3. Create an `org.openhab.training.electricity.consumer` bundle, which contains an
|
||||
interface `ElectricityConsumer` with methods:
|
||||
- `void start()` - starts the device and displays a message on the console. If the device requires a provider (it is not energy independent), this method can set the current provider. After the device is started it should try to consume electricity equal to the device consumption from the current provider at fixed interval from 5 seconds and display a message on the console, which provider is in use at the moment;
|
||||
- `void stop()` - stops the device and displays message on the console. The device should not consume electricity anymore. The device should stop, if the current provider is discharged;
|
||||
- `void startConsuming()` - starts the device and displays a message on the console. If the device requires a provider (it is not energy independent), this method can set the current provider. After the device is started it should try to consume electricity equal to the device consumption from the current provider at fixed interval from 5 seconds and display a message on the console, which provider is in use at the moment;
|
||||
- `void stopConsuming()` - stops the device and displays message on the console. The device should not consume electricity anymore. The device should stop, if the current provider is discharged;
|
||||
- `void setCurrentProvider(ElectricityProvider)` - sets a current provider from a list with available providers;
|
||||
- `List<ElectricityProvider> getAllAvailableProviders()` - returns a list with available providers (a provider is available, when it is registered in the *Service Registry* and has more charge, than the device consumption).
|
||||
4. Create an `org.openhab.training.electricity.radio` bundle, which:
|
||||
|
@ -119,13 +119,17 @@ interface `ElectricityConsumer` with methods:
|
|||
|
||||
1. Implement the [*ManagedService*][ManagedService] interface in the `org.openhab.training.electricity.tv.events` bundle and:
|
||||
- add a configuration to the `TV` class with property "autoSleep" and value a timestamp (hh:mm);
|
||||
- modify the method that listens for events with topic "time" to stop the bundle, when the "autoSleep" property is equal to the "time" topic.
|
||||
2. Create another implementation of the `ElectricityProvider` interface (`RechargableBattery`) in an `org.openhab.training.electricity.rechargablebattery` bundle that:
|
||||
- modify the method that listens for events with topic "time" to stop the bundle, when the "autoSleep" property is equal to the "time" topic.
|
||||
|
||||
2. Create another implementation of the `ElectricityProvider` interface (`RechargableBattery`) in an `org.openhab.training.electricity.rechargeablebattery` bundle that:
|
||||
- has a finite charge (e.g `int capacity = 30`);
|
||||
- implements the *ManagedService* interface. After this modification, it should be possible to change the charge of a battery with a `setCharge(int capacity)` method;
|
||||
- when the battery is recharged (the configuration of the battery is changed), the consumers must be notified about the change.
|
||||
|
||||
Hint! Read about the [ConfigurationAdmin](https://osgi.org/javadoc/r4v42/org/osgi/service/cm/ConfigurationAdmin.html) service and how you can use it to change the configuration of a ManagedService. You might want to implement additional bundle that is using the ConfigurationAdmin service to change the configuration of the battery to perform a quick test.
|
||||
Hint! Read about the [ConfigurationAdmin](https://osgi.org/javadoc/r4v42/org/osgi/service/cm/ConfigurationAdmin.html) service and how you can use it to change the configuration of a ManagedService. You might want to implement additional bundle that is using the ConfigurationAdmin service to change the configuration of the battery to perform a quick test.
|
||||
|
||||
Hint! Install `org.eclipse.equinox.cm` bundle in order to use *ConfigurationAdmin* service.
|
||||
|
||||
3. Create a `org.openhab.training.electricity.recharger` bundle that will wait 10 seconds after it is activated and will recharge a rechargeable battery if it is registered as a service.
|
||||
|
||||
### VII. Console Commands
|
||||
|
||||
|
|
Loading…
Reference in New Issue