blob: 000d7e7dd2adba3ef0bba7f5e14c49c9a107d8ca [file] [log] [blame]
Pierre De Rop6b4a6c42010-04-25 22:57:56 +00001This sample illustrates the usage of the new DependencyManager annotations.
2
3Sample description:
Pierre De Rop40b34552011-05-07 10:21:55 +00004==================
Pierre De Rop6b4a6c42010-04-25 22:57:56 +00005
Pierre De Rop40b34552011-05-07 10:21:55 +00006This sample shows a basic "SpellChecker" application which provides a Felix "spellcheck" GOGO shell
7command. The GOGO "spellcheck" command accepts a string as parameter, which is checked for proper
8existence. The SpellChecker class has a required/multiple (1..N) dependency over every available
9"DictionaryService" services, which are internally used by the SpellChecker command, when checking
10word existence.
11
12A DictionaryService is defined using a FactoryConfigurationAdapterService annotation, allowing to
13instantiate many "DictionaryService" instances from webconsole. This annotation actually registers a
14ManagedServiceFactory into the Registry, and you can specify some meta type informations in the
15annotation, allowing to configure the DictionaryService words and language from WebConsole. Each
16time you instantiate a factory configuration whose factory pid equals "DictionaryImplFactoryPid",
17in the webconsole "Dictionary Services" configuration section, then a corresponding "DictionaryImpl"
18component is instantiated and is then injected into the SpellChecker service. So, before testing,
19you first have to go to webconsole Configuration panel, and specify some dictionaries (see the
20"Dictionary Services" section). Then, go to the felix GOGO shell, and you will then see the
21"spellcheck" command (when typing "help").
22
23Notice that in the sample, you will also find a DictionaryAspect Service (DictionaryAspect.java),
24which decorates the EnglishDictionary service, by adding some additional words to it.
25
Pierre De Rop6b4a6c42010-04-25 22:57:56 +000026How to test:
Pierre De Rop40b34552011-05-07 10:21:55 +000027===========
Pierre De Rop6b4a6c42010-04-25 22:57:56 +000028
Pierre De Rop40b34552011-05-07 10:21:55 +0000291) Install the following bundles (with same or higher version):
Pierre De Rop6b4a6c42010-04-25 22:57:56 +000030
Pierre De Rop40b34552011-05-07 10:21:55 +000031 org.apache.felix.configadmin-1.2.8.jar
32 org.apache.felix.metatype-1.0.4.jar
33 org.apache.felix.http.jetty-2.2.0.jar
34 org.apache.felix.webconsole-3.1.8.jar
35 org.apache.felix.shell-1.4.2.jar
36 org.apache.felix.dependencymanager-3.0.0.jar
37 org.apache.felix.dependencymanager.shell-3.0.0.jar
38 org.apache.felix.dependencymanager.runtime-3.0.0.jar
39 org.apache.felix.log-1.0.1.jar (optional)
Pierre De Rop6b4a6c42010-04-25 22:57:56 +000040
Pierre De Rop40b34552011-05-07 10:21:55 +0000412) compile dependency manager sample.annotation from trunk:
Pierre De Rop6b4a6c42010-04-25 22:57:56 +000042
Pierre De Rop40b34552011-05-07 10:21:55 +000043 svn checkout http://svn.apache.org/repos/asf/felix/trunk/dependencymanager dependencymanager
44 cd dependencymanager/sample.annotation
45 mvn clean install
46
47Then install ./target/org.apache.felix.dependencymanager.samples.annotation-3.0.0-SNAPSHOT.jar into
48felix.
49
503) Start felix
51
52At this point, you should have the following running bundles:
53
54g! lb
55START LEVEL 1
56 ID|State |Level|Name
57 0|Active | 0|System Bundle (3.2.1)
58 1|Active | 1|Apache Felix Bundle Repository (1.6.2)
59 2|Active | 1|Apache Felix Configuration Admin Service (1.2.8)
60 3|Active | 1|Apache Felix Dependency Manager (3.0.0)
61 4|Active | 1|Apache Felix Dependency Manager Runtime (3.0.0)
62 5|Active | 1|Apache Felix Dependency Manager Annotation Sample (3.0.0.SNAPSHOT)
63 6|Active | 1|Apache Felix Dependency Manager Shell (3.0.0)
64 7|Active | 1|Apache Felix Gogo Command (0.8.0)
65 8|Active | 1|Apache Felix Gogo Runtime (0.8.0)
66 9|Active | 1|Apache Felix Gogo Shell (0.8.0)
67 10|Active | 1|Apache Felix Http Jetty (2.2.0)
68 11|Active | 1|Apache Felix Log Service (1.0.1)
69 12|Active | 1|Apache Felix Metatype Service (1.0.4)
70 13|Active | 1|Apache Felix Shell Service (1.4.2)
71 14|Active | 1|Apache Felix Web Management Console (3.1.8)
72
734) Inspect Dependency Manager components from gogo shell:
74
75type "dm 5" for browsing the components for the bundle id 5
76
77[5] org.apache.felix.dependencymanager.samples.annotation
78 org.osgi.service.cm.ManagedServiceFactory(service.pid=DictionaryImplFactoryPid) registered
79 org.osgi.service.log.LogService service optional available
80 org.apache.felix.dm.samples.annotation.SpellChecker(osgi.command.function={spellcheck},osgi.command.scope=dmsample.annotation) unregistered
81 org.apache.felix.dm.samples.annotation.DictionaryService service required unavailable
82 org.osgi.service.log.LogService service optional unavailable
83 org.apache.felix.dm.impl.AspectServiceImpl$AspectImpl@4d76b4 unregistered
84 org.apache.felix.dm.samples.annotation.DictionaryService (&(!(org.apache.felix.dependencymanager.aspect=*))(lang=en)) service optional unavailable
85 DictionaryAspectPID configuration required unavailable
86 org.osgi.service.log.LogService service optional unavailable
87
88Here, the bundle [5] corresponds to our annotation.sample bundle. In this bundle, we have three
89components:
90
91* org.osgi.service.cm.ManagedServiceFactory: this is the service DM has internally registered in
92 order to be able to instantiate some of our "DictionaryImpl" component instances from config
93 admin (using the factory pid "DictionaryImplFactoryPid"). See DictionaryImpl.java and especially
94 the @FactoryConfigurationAdapterService annotation. The component depends on the log service
95 because our "DictionaryImpl" component also depends on the log service. The ManagedServiceFactory
96 is actually depending on all dependencies defined in our "DictionaryImpl" component, and those
97 dependencies will be applied on each instantiated DictionaryImpl component instances.
98
99* org.apache.felix.dm.samples.annotation.SpellChecker: This is our "SpellChecker" component exposing
100 two services properties: "osgi.command.function" (the gogo shell method name), and
101 "osgi.command.scope" (the gogo command scope).
102 It also has two dependencies: "org.apache.felix.dm.samples.annotation.DictionaryService", and
103 "org.osgi.service.log.LogService".
104
105* org.apache.felix.dm.impl.AspectServiceImpl$AspectImpl: this is also an internal service registered
106 by dependency manager, in order to instantiate our "DictionaryAspect" interceptor service. See
107 DictionaryAspect.java. The aspect impl depends on the three dependencies (which are initially
108 defined in DictionaryAspect.java):
109
110 - org.apache.felix.dm.samples.annotation.DictionaryService: this is the service our DictionaryAspect
111 is intercepting. The AspectServiceImpl$AspectImpl will create a DictionaryAspect instance for
112 every DictionaryService found from the OSGi registry (that is, for every DictionaryService you
113 create from web console "Dictionary Services" configuraton section).
114
115 - DictionaryAspectPID configuration: this is the config pid our DictionaryAspect is depending on (see
116 @ConfigurationDependency in DictionaryAspect.java).
117
118 - org.osgi.service.log.LogService: the DictionaryAspect is optionally depending on the log service
119 (a null object is used if there is no one).
120
121So, when a DictionaryService will come up, the AspectServiceImpl component will instantiate a
122corresponding "DictionaryAspect" instance, with all the dependencies defined in DictionaryAspect.
123
1245) Create a DictionaryService from web console:
125
126Go to web console: in the Configuration panel, edit the "Dictionary Services" Configuration, and add
127some dictionaries. By default, an English dictionary is displayed. Just click on "save", *then click
128on your refresh web browser*: you will see a new dictionary service instance. At this point, a
129"DictionaryImpl" component instance will be create (with the service property "lang=en"), and the
130SpellCheck component will be injected with it (the DictionaryImpl implements
131DictionaryService). Then you should see the "spellcheck" command, when typing "help" on the gogo
132shell.
133
1346) test the spellchecker under gogo shell:
135
136Just type "spellcheck hello", and the command should reply a fantastic message, like "word hello is
137correct".
138
1397) Inspect again DependencyManager components from the shell:
140
141Type again "dm 5", for browsing the components coming from our bundle id 5:
142
143[5] org.apache.felix.dependencymanager.samples.annotation
144 org.osgi.service.cm.ManagedServiceFactory(service.pid=DictionaryImplFactoryPid) registered
145 org.osgi.service.log.LogService service optional available
146 org.apache.felix.dm.samples.annotation.SpellChecker(osgi.command.function={spellcheck},osgi.command.scope=dmsample.annotation) registered
147 org.apache.felix.dm.samples.annotation.DictionaryService service required available
148 org.osgi.service.log.LogService service optional available
149 org.apache.felix.dm.impl.AspectServiceImpl$AspectImpl@128edf2 unregistered
150 org.apache.felix.dm.samples.annotation.DictionaryService (&(!(org.apache.felix.dependencymanager.aspect=*))(lang=en)) service optional unavailable
151 DictionaryAspectPID configuration required unavailable
152 org.osgi.service.log.LogService service optional unavailable
153 org.apache.felix.dm.samples.annotation.DictionaryService(service.pid=DictionaryImplFactoryPid.e01b70ff-d2b5-4305-9e86-84c68a2fddbb,service.factoryPid=DictionaryImplFactoryPid,lang=en) registered
154 org.osgi.service.log.LogService service optional available
155
156Here, you can see the following:
157
158* the org.osgi.service.cm.ManagedServiceFactory with factory pid "DictionaryImplFactoryPid" is now
159 registered, because we have created a dictionary from config admin (in the Dictionary Services"
160 webconsole configuration section).
161
162* the SpellChecker is now "registered" because it has been injected with the DictionaryImpl we have
163 created from webconsole.
164
165* the AspectServiceImpl$AspectImpl is not yet registered because we still have to instantiate a
166 configuration from webconsole for the "DictionaryAspectPID" PID: this configuration is required to
167 instance our DictionaryAspect component (see the @ConfigurationDependency annotation in
168 DictionaryAspect.java).
169
170* One instance of the DictionaryService component is now registered (this instance corresponds to
171 what we just configured from webconsole, in the "Dictionary Services" section).
172
1738) Finally, activate the "Aspect Dictionary" component:
174
175To do so, you can click on the "Aspect Dictionary" button, from web console Configuration section,
176in order to decorate the english dictionary with some custom words. By default, the "aspect" word is
177pre configured, but you can click on the "+" button in order to add more words. Then click on
178Save. At this point, the English DictionaryService will be decorated with the aspect service. So,
179now, if you type "spellcheck aspect", then the message: "word aspect is correct" should be
180displayed. What is going on is that the original DictionaryService will be replaced by the
181DictionaryAspect, using a higher service.ranking (ranking 10, see DictionaryAspect.java). So the
182spell checker will be transparently re-injected with the DictionayAspect, which is from his side
183depending on the originial DictionaryService.
184
185So, if you type "dm 5", you will know see two DictionaryService instances:
186
187 org.apache.felix.dm.samples.annotation.DictionaryService(service.pid=DictionaryImplFactoryPid.8390ad56-b2de-4414-9123-29c65c42e5b9,service.factoryPid=DictionaryImplFactoryPid,lang=en) registered
188 org.osgi.service.log.LogService service optional available
189
190 org.apache.felix.dm.samples.annotation.DictionaryService(service.pid=DictionaryImplFactoryPid.8390ad56-b2de-4414-9123-29c65c42e5b9,service.ranking=10,service.factoryPid=DictionaryImplFactoryPid,org.apache.felix.dependencymanager.aspect=57,lang=en) registered
191 org.apache.felix.dm.samples.annotation.DictionaryService (&(|(!(service.ranking=*))(service.ranking<=9))(|(service.id=57)(org.apache.felix.dependencymanager.aspect=57))) service required available
192 DictionaryAspectPID configuration required available
193 org.osgi.service.log.LogService service optional available
194
195The first one is the original DictionaryService we have created using the factory pid
196"DictionaryImplFactoryPid" from web console. By default, the ranking of this service is 0.
197
198Next, you see the new DictionaryService which corresponds to our DictionaryAspect service. It has
199the following properties:
200
201* it has inherited from all service properties found from the original intercepted DictionarService.
202* it has a higher service ranking than the original one (see service.ranking=10). This ranking is
203 actually defined in DictionaryAspect.java, in the @Aspect annotation.
204* it has a dependency over the original DictionaryService (using an appropriate filter).
205* it also inherits from all dependencies originally defined in the DictionaryImpl component
206
207
208
209