blob: eaa4c6b8524544b3b9c306625030f1e40d045598 [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;
20
21import static org.apache.felix.dm.lambda.DependencyManagerActivator.component;
22import static org.apache.felix.dm.lambda.DependencyManagerActivator.serviceDependency;
23
24import java.util.Hashtable;
25
26import org.apache.felix.dm.Component;
27import org.apache.felix.dm.DependencyManager;
28import org.apache.felix.dm.ServiceDependency;
29import org.junit.Assert;
30
31/**
32 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
33 */
34@SuppressWarnings({"unchecked", "rawtypes", "serial"})
35public class TemporalServiceDependencyTest extends TestBase {
36 public void testServiceConsumptionAndIntermittentAvailability() {
37 if (true) return;
38 final DependencyManager m = getDM();
39 // helper class that ensures certain steps get executed in sequence
40 Ensure e = new Ensure();
41 // create a service provider and consumer
42 TemporalServiceProvider provider = new TemporalServiceProvider(e);
43 Component sp = component(m).impl(provider).provides(TemporalServiceInterface.class.getName()).build();
44 TemporalServiceProvider2 provider2 = new TemporalServiceProvider2(e);
45 Component sp2 = component(m).impl(provider2).provides(TemporalServiceInterface.class.getName()).build();
46 TemporalServiceConsumer consumer = new TemporalServiceConsumer(e);
47 Component sc = component(m).impl(consumer).withSrv(TemporalServiceInterface.class, s->s.timeout(10000)).build();
48 // add the service consumer
49 m.add(sc);
50 // now add the first provider
51 m.add(sp);
52 e.waitForStep(2, 5000);
53 // and remove it again (this should not affect the consumer yet)
54 m.remove(sp);
55 // now add the second provider
56 m.add(sp2);
57 e.step(3);
58 e.waitForStep(4, 5000);
59 // and remove it again
60 m.remove(sp2);
61 // finally remove the consumer
62 m.remove(sc);
63 // ensure we executed all steps inside the component instance
64 e.step(6);
65 m.clear();
66 }
67
68 public void testServiceConsumptionWithCallbackAndIntermittentAvailability() {
69 if (true) return;
70 final DependencyManager m = getDM();
71 // helper class that ensures certain steps get executed in sequence
72 Ensure e = new Ensure();
73 // create a service provider and consumer
74 TemporalServiceProvider provider = new TemporalServiceProvider(e);
75 Component sp = component(m).impl(provider).provides(TemporalServiceInterface.class.getName()).build();
76 TemporalServiceProvider2 provider2 = new TemporalServiceProvider2(e);
77 Component sp2 = component(m).impl(provider2).provides(TemporalServiceInterface.class.getName()).build();
78 TemporalServiceConsumerWithCallback consumer = new TemporalServiceConsumerWithCallback(e);
79 Component sc = component(m).impl(consumer).withSrv(TemporalServiceInterface.class, srv->srv.cb("add", "remove").timeout(10000)).build();
80
81 // add the service consumer
82 m.add(sc);
83 // now add the first provider
84 m.add(sp);
85 e.waitForStep(2, 5000);
86 // and remove it again (this should not affect the consumer yet)
87 m.remove(sp);
88 // now add the second provider
89 m.add(sp2);
90 e.step(3);
91 e.waitForStep(4, 5000);
92 // and remove it again
93 m.remove(sp2);
94 // finally remove the consumer
95 m.remove(sc);
96 // Wait for the consumer.remove callback
97 e.waitForStep(6, 5000);
98 // ensure we executed all steps inside the component instance
99 e.step(7);
100 m.clear();
101 }
102
103 // Same test as testServiceConsumptionWithCallbackAndIntermittentAvailability, but the consumer is now
104 // an adapter for the Adaptee interface.
105 public void testFELIX4858_ServiceAdapterConsumptionWithCallbackAndIntermittentAvailability() {
106 if (true) return;
107 final DependencyManager m = getDM();
108 // helper class that ensures certain steps get executed in sequence
109 Ensure e = new Ensure();
110 // create a service provider and consumer
111 TemporalServiceProvider provider = new TemporalServiceProvider(e);
112 Component sp = component(m).impl(provider).provides(TemporalServiceInterface.class.getName()).build();
113 TemporalServiceProvider2 provider2 = new TemporalServiceProvider2(e);
114 Component sp2 = component(m).impl(provider2).provides(TemporalServiceInterface.class.getName()).build();
115 TemporalServiceConsumerAdapterWithCallback consumer = new TemporalServiceConsumerAdapterWithCallback(e);
116 Component sc = m.createAdapterService(Adaptee.class, null).setImplementation(consumer);
117 ServiceDependency temporalDep = serviceDependency(sc, TemporalServiceInterface.class).timeout(10000).cb("add", "remove").build();
118 sc.add(temporalDep);
119 Component adaptee = component(m).impl(new Adaptee()).provides(Adaptee.class.getName()).build();
120
121 // add the adapter service consumer
122 m.add(sc);
123 // add the adaptee (the adapter service depends on it)
124 m.add(adaptee);
125 // now add the first provider
126 m.add(sp);
127 e.waitForStep(2, 5000);
128 // and remove it again (this should not affect the consumer yet)
129 m.remove(sp);
130 // now add the second provider
131 m.add(sp2);
132 e.step(3);
133 e.waitForStep(4, 5000);
134 // and remove it again
135 m.remove(sp2);
136 // finally remove the consumer
137 m.remove(sc);
138 // Wait for the consumer.remove callback
139 e.waitForStep(6, 5000);
140 // ensure we executed all steps inside the component instance
141 e.step(7);
142 m.clear();
143 }
144
145 public void testFelix4602_PropagateServiceInvocationException() {
146 if (true) return;
147 final DependencyManager m = getDM();
148 final Ensure ensure = new Ensure();
149 Runnable provider = new Runnable() {
150 public void run() {
151 throw new UncheckedException();
152 }
153 };
154 Hashtable props = new Hashtable();
155 props.put("target", getClass().getSimpleName());
156 Component providerComp = component(m)
157 .provides(Runnable.class.getName(), props)
158 .impl(provider).build();
159
160 Object consumer = new Object() {
161 volatile Runnable m_provider;
162 @SuppressWarnings("unused")
163 void start() {
164 try {
165 ensure.step(1);
166 m_provider.run();
167 } catch (UncheckedException e) {
168 ensure.step(2);
169 }
170 }
171 };
172 Component consumerComp = component(m)
173 .impl(consumer)
174 .withSrv(Runnable.class, s->s.timeout(5000).filter("(target=" + getClass().getSimpleName() + ")")).build();
175 m.add(consumerComp);
176 m.add(providerComp);
177 ensure.waitForStep(2, 5000);
178 m.clear();
179 }
180
181 static class UncheckedException extends RuntimeException {
182 }
183
184 static interface TemporalServiceInterface {
185 public void invoke();
186 }
187
188 static class TemporalServiceProvider implements TemporalServiceInterface {
189 private final Ensure m_ensure;
190 public TemporalServiceProvider(Ensure e) {
191 m_ensure = e;
192 }
193 public void invoke() {
194 m_ensure.step(2);
195 }
196 }
197
198 static class TemporalServiceProvider2 implements TemporalServiceInterface {
199 protected final Ensure m_ensure;
200 public TemporalServiceProvider2(Ensure e) {
201 m_ensure = e;
202 }
203 public void invoke() {
204 m_ensure.step(4);
205 }
206 }
207
208 static class TemporalServiceConsumer implements Runnable {
209 protected volatile TemporalServiceInterface m_service;
210 protected final Ensure m_ensure;
211
212 public TemporalServiceConsumer(Ensure e) {
213 m_ensure = e;
214 }
215
216 public void init() {
217 m_ensure.step(1);
218 Thread t = new Thread(this);
219 t.start();
220 }
221
222 public void run() {
223 m_service.invoke();
224 m_ensure.waitForStep(3, 15000);
225 m_service.invoke();
226 }
227
228 public void destroy() {
229 m_ensure.step(5);
230 }
231 }
232
233 static class TemporalServiceConsumerWithCallback extends TemporalServiceConsumer {
234 public TemporalServiceConsumerWithCallback(Ensure e) {
235 super(e);
236 }
237
238 public void add(TemporalServiceInterface service) {
239 m_service = service;
240 }
241
242 public void remove(TemporalServiceInterface service) {
243 Assert.assertTrue(m_service == service);
244 m_ensure.step(6);
245 }
246 }
247
248 public static class Adaptee {
249 }
250
251 static class TemporalServiceConsumerAdapterWithCallback extends TemporalServiceConsumer {
252 volatile Adaptee m_adaptee;
253
254 public TemporalServiceConsumerAdapterWithCallback(Ensure e) {
255 super(e);
256 }
257
258 public void start() {
259 Assert.assertTrue(m_adaptee != null);
260 }
261
262 public void add(TemporalServiceInterface service) {
263 m_service = service;
264 }
265
266 public void remove(TemporalServiceInterface service) {
267 Assert.assertTrue(m_service == service);
268 m_ensure.step(6);
269 }
270 }
271}