blob: 827180833b71eb8cfe05fb84bdfc37743165904c [file] [log] [blame]
Pierre De Ropfaca2892016-01-31 23:27:05 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19package org.apache.felix.dm.lambda.itest;
20import static org.apache.felix.dm.lambda.DependencyManagerActivator.aspect;
21import static org.apache.felix.dm.lambda.DependencyManagerActivator.component;
22
23import java.util.ArrayList;
24import java.util.List;
25
26import org.apache.felix.dm.Component;
27import org.apache.felix.dm.DependencyManager;
28import org.junit.Assert;
29import org.osgi.framework.Constants;
30import org.osgi.framework.ServiceReference;
31
32/**
33 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
34 */
35@SuppressWarnings({"rawtypes", "unchecked", "unused"})
36public class AspectWhiteboardTest extends TestBase {
37
38 public void testWhiteboardConsumer() {
39 DependencyManager m = getDM();
40 // helper class that ensures certain steps get executed in sequence
41 Ensure e = new Ensure();
42 // create service providers and consumer
43 Component sp1 = component(m).impl(new ServiceProvider(e)).provides(ServiceInterface.class.getName()).build();
44 Component sp2 = component(m).impl(new ServiceProvider(e)).provides(ServiceInterface.class.getName()).build();
45 ServiceConsumer sci = new ServiceConsumer(e);
Pierre De Rop11527502016-02-18 21:07:16 +000046 Component sc = component(m).impl(sci).withSvc(ServiceInterface.class, srv->srv.required(false).add("add").remove("remove")).build();
Pierre De Ropfaca2892016-01-31 23:27:05 +000047 Component sa2 = aspect(m, ServiceInterface.class).rank(20).autoAdd(false).impl(new ServiceAspect(e, 3)).build();
48 Component sa1 = aspect(m, ServiceInterface.class).rank(10).autoAdd(false).impl(new ServiceAspect(e, 4)).build();
49
50 // start with a service consumer
51 System.out.println("Adding consumer");
52 m.add(sc);
53
54 // then add two providers, so the consumer will see two services
55 System.out.println("Adding 2 providers");
56 m.add(sp1);
57 m.add(sp2);
58
59 // make sure consumer sees both services
60 Assert.assertEquals(2, sci.services());
61
62 // add an aspect with ranking 20
63 System.out.println("Adding aspect with rank 20");
64 m.add(sa2);
65
66 // make sure the consumer sees the two new aspects and no longer sees the two original services
67 Assert.assertEquals(2, sci.services());
68 Assert.assertEquals(20, sci.highestRanking());
69 Assert.assertEquals(20, sci.lowestRanking());
70
71 // add an aspect with ranking 10
72 System.out.println("Adding aspect with rank 10");
73 m.add(sa1);
74
75 // make sure the consumer still sees the two aspects with ranking 20
76 Assert.assertEquals(2, sci.services());
77 Assert.assertEquals(20, sci.highestRanking());
78 Assert.assertEquals(20, sci.lowestRanking());
79
80 // remove the aspect with ranking 20
81 System.out.println("Removing aspect with rank 20");
82 m.remove(sa2);
83
84 // make sure the consumer now sees the aspects with ranking 10
85 Assert.assertEquals(2, sci.services());
86 Assert.assertEquals(10, sci.highestRanking());
87 Assert.assertEquals(10, sci.lowestRanking());
88
89 // remove one of the original services
90 System.out.println("Removing 1 service");
91 m.remove(sp1);
92
93 // make sure the aspect of that service goes away
94 Assert.assertEquals(1, sci.services());
95 Assert.assertEquals(10, sci.highestRanking());
96 Assert.assertEquals(10, sci.lowestRanking());
97
98 // remove the aspect with ranking 10
99 System.out.println("Removing aspect with rank 10");
100 m.remove(sa1);
101
102 // make sure only the original service remains
103 Assert.assertEquals(1, sci.services());
104 Assert.assertEquals(0, sci.highestRanking());
105 Assert.assertEquals(0, sci.lowestRanking());
106
107 System.out.println("Done with test");
108
109 // end of test
110 m.remove(sa2);
111 m.remove(sp2);
112 m.remove(sc);
113 }
114
115 public void testWhiteboardConsumerRef() {
116 DependencyManager m = getDM();
117 // helper class that ensures certain steps get executed in sequence
118 Ensure e = new Ensure();
119 // create service providers and consumer
120 Component sp1 = component(m).impl(new ServiceProvider(e)).provides(ServiceInterface.class.getName()).build();
121 Component sp2 = component(m).impl(new ServiceProvider(e)).provides(ServiceInterface.class.getName()).build();
122 ServiceConsumer sci = new ServiceConsumer(e);
Pierre De Rop11527502016-02-18 21:07:16 +0000123 Component sc = component(m).impl(sci).withSvc(ServiceInterface.class, srv->srv.optional().add(sci::addRef).remove(sci::removeRef)).build();
124 Component sa2 = aspect(m, ServiceInterface.class).rank(20).impl(new ServiceAspect(e, 3)).build();
125 Component sa1 = aspect(m, ServiceInterface.class).rank(10).impl(new ServiceAspect(e, 4)).build();
Pierre De Ropfaca2892016-01-31 23:27:05 +0000126
127 // start with a service consumer
128 System.out.println("Adding consumer");
129 m.add(sc);
130
131 // then add two providers, so the consumer will see two services
132 System.out.println("Adding 2 providers");
133 m.add(sp1);
134 m.add(sp2);
135
136 // make sure consumer sees both services
137 Assert.assertEquals(2, sci.services());
138
139 // add an aspect with ranking 20
140 System.out.println("Adding aspect with rank 20");
141 m.add(sa2);
142
143 // make sure the consumer sees the two new aspects and no longer sees the two original services
144 Assert.assertEquals(2, sci.services());
145 Assert.assertEquals(20, sci.highestRanking());
146 Assert.assertEquals(20, sci.lowestRanking());
147
148 // add an aspect with ranking 10
149 System.out.println("Adding aspect with rank 10");
150 m.add(sa1);
151
152 // make sure the consumer still sees the two aspects with ranking 20
153 Assert.assertEquals(2, sci.services());
154 Assert.assertEquals(20, sci.highestRanking());
155 Assert.assertEquals(20, sci.lowestRanking());
156
157 // remove the aspect with ranking 20
158 System.out.println("Removing aspect with rank 20");
159 m.remove(sa2);
160
161 // make sure the consumer now sees the aspects with ranking 10
162 Assert.assertEquals(2, sci.services());
163 Assert.assertEquals(10, sci.highestRanking());
164 Assert.assertEquals(10, sci.lowestRanking());
165
166 // remove one of the original services
167 System.out.println("Removing 1 service");
168 m.remove(sp1);
169
170 // make sure the aspect of that service goes away
171 Assert.assertEquals(1, sci.services());
172 Assert.assertEquals(10, sci.highestRanking());
173 Assert.assertEquals(10, sci.lowestRanking());
174
175 // remove the aspect with ranking 10
176 System.out.println("Removing aspect with rank 10");
177 m.remove(sa1);
178
179 // make sure only the original service remains
180 Assert.assertEquals(1, sci.services());
181 Assert.assertEquals(0, sci.highestRanking());
182 Assert.assertEquals(0, sci.lowestRanking());
183
184 System.out.println("Done with test");
185
186 // end of test
187 m.remove(sa2);
188 m.remove(sp2);
189 m.remove(sc);
190 }
191
192 static interface ServiceInterface {
193 public void invoke(Runnable run);
194 }
195
196 static class ServiceProvider implements ServiceInterface {
197 private final Ensure m_ensure;
198 public ServiceProvider(Ensure e) {
199 m_ensure = e;
200 }
201 public void invoke(Runnable run) {
202 run.run();
203 }
204 }
205
206 static class ServiceAspect implements ServiceInterface {
207 private final Ensure m_ensure;
208 private volatile ServiceInterface m_parentService;
209 private final int m_step;
210
211 public ServiceAspect(Ensure e, int step) {
212 m_ensure = e;
213 m_step = step;
214 }
215 public void start() {
216 }
217
218 public void invoke(Runnable run) {
219 m_ensure.step(m_step);
220 m_parentService.invoke(run);
221 }
222
223 public void stop() {
224 }
225 }
226
227 static class ServiceConsumer implements Runnable {
228 private List m_services = new ArrayList();
229 private final Ensure m_ensure;
230
231 public ServiceConsumer(Ensure e) {
232 m_ensure = e;
233 }
234
235 public void init() {
236 Thread t = new Thread(this);
237 t.start();
238 }
239
240 public void run() {
241 }
242
243 public int services() {
244 return m_services.size();
245 }
246
247 public int highestRanking() {
248 int ranking = Integer.MIN_VALUE;
249 for (int i = 0; i < m_services.size(); i++) {
250 ServiceReference ref = (ServiceReference) m_services.get(i);
251 Integer r = (Integer) ref.getProperty(Constants.SERVICE_RANKING);
252 int rank = r == null ? 0 : r.intValue();
253 ranking = Math.max(ranking, rank);
254 }
255 return ranking;
256 }
257 public int lowestRanking() {
258 int ranking = Integer.MAX_VALUE;
259 for (int i = 0; i < m_services.size(); i++) {
260 ServiceReference ref = (ServiceReference) m_services.get(i);
261 Integer r = (Integer) ref.getProperty(Constants.SERVICE_RANKING);
262 int rank = r == null ? 0 : r.intValue();
263 ranking = Math.min(ranking, rank);
264 }
265 return ranking;
266 }
267
Pierre De Rop11527502016-02-18 21:07:16 +0000268 // method ref callback
269 public void addRef(ServiceInterface svc, ServiceReference ref) {
270 add(ref, svc);
271 }
272
273 // refection callback
Pierre De Ropfaca2892016-01-31 23:27:05 +0000274 public void add(ServiceReference ref, ServiceInterface svc) {
275 System.out.println("Added: " + ServiceUtil.toString(ref));
276 m_services.add(ref);
277 }
Pierre De Rop11527502016-02-18 21:07:16 +0000278
279 // method ref callback
280 public void removeRef(ServiceInterface svc, ServiceReference ref) {
281 remove(ref, svc);
282 }
283
284 // refection callback
Pierre De Ropfaca2892016-01-31 23:27:05 +0000285 public void remove(ServiceReference ref, ServiceInterface svc) {
286 System.out.println("Removed: " + ServiceUtil.toString(ref));
287 m_services.remove(ref);
Pierre De Rop11527502016-02-18 21:07:16 +0000288 }
Pierre De Ropfaca2892016-01-31 23:27:05 +0000289 }
290}