blob: 32f78556624ce0b7a1f1abaaf919f79876054c78 [file] [log] [blame]
Pierre De Rop3a00a212015-03-01 09:27:46 +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.itest.api;
20
21import java.util.Hashtable;
22
23import org.junit.Assert;
24
25import org.apache.felix.dm.Component;
26import org.apache.felix.dm.Dependency;
27import org.apache.felix.dm.DependencyManager;
28import org.apache.felix.dm.itest.util.Ensure;
29import org.apache.felix.dm.itest.util.TestBase;
30
31
32/**
33 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
34 */
35@SuppressWarnings({"unchecked", "rawtypes"})
36public class MultipleExtraDependenciesTest extends TestBase {
37 /**
38 * Check that list of extra dependencies (defined from init method) are handled properly.
39 * The extra dependencies are added using a List object (Component.add(List)).
40 * A component c1 will define two extra dependencies over *available* c4/c5 services.
41 */
42 public void testWithTwoAvailableExtraDependency() {
43 DependencyManager m = getDM();
44 // Helper class that ensures certain steps get executed in sequence
45 Ensure e = new Ensure();
46 Component c1 = m.createComponent()
47 .setInterface(Service1.class.getName(), null)
48 .setImplementation(new MyComponent1(e))
49 .add(m.createServiceDependency()
50 .setService(Service2.class)
51 .setRequired(true)
52 .setAutoConfig("m_service2"));
53
54 Component c2 = m.createComponent()
55 .setImplementation(new MyComponent2(e))
56 .add(m.createServiceDependency()
57 .setService(Service1.class)
58 .setRequired(false)
59 .setAutoConfig(false)
60 .setCallbacks("added", null, null));
61
62 Component c3 = m.createComponent()
63 .setInterface(Service2.class.getName(), null)
64 .setImplementation(Service2Impl.class);
65
66 Hashtable h = new Hashtable();
67 h.put("type", "xx");
68 Component c4 = m.createComponent()
69 .setInterface(Service3.class.getName(), h)
70 .setImplementation(Service3Impl1.class);
71
72 h = new Hashtable();
73 h.put("type", "yy");
74 Component c5 = m.createComponent()
75 .setInterface(Service3.class.getName(), h)
76 .setImplementation(Service3Impl2.class);
77
78
79 System.out.println("\n+++ Adding c2 / MyComponent2");
80 m.add(c2);
81 System.out.println("\n+++ Adding c3 / Service2");
82 m.add(c3);
83 System.out.println("\n+++ Adding c4 / Service3(xx)");
84 m.add(c4);
85 System.out.println("\n+++ Adding c5 / Service3(yy)");
86 m.add(c5);
87 System.out.println("\n+++ Adding c1 / MyComponent1");
88 // c1 have declared two extra dependency on Service3 (xx/yy).
89 // both extra dependencies are available, so the c1 component should be started immediately.
90 m.add(c1);
91 e.waitForStep(3, 3000);
92 m.clear();
93 }
94
95 /**
96 * Check that list of extra dependencies (defined from init method) are handled properly.
97 * The extra dependencies are added using a List object (Component.add(List)).
98 * A component c1 will define two extra dependencies over c4/c5. At the point c1.init()
99 * is adding the two extra dependencies from its init method, c4 is available, but not c5.
100 * So, c1 is not yet activated.
101 * Then c5 is added, and it triggers the c1 activation ...
102 */
103 public void testWithOneAvailableExtraDependency() {
104 DependencyManager m = getDM();
105 // Helper class that ensures certain steps get executed in sequence
106 Ensure e = new Ensure();
107 Component c1 = m.createComponent()
108 .setInterface(Service1.class.getName(), null)
109 .setImplementation(new MyComponent1(e))
110 .add(m.createServiceDependency()
111 .setService(Service2.class)
112 .setRequired(true)
113 .setAutoConfig("m_service2"));
114
115 Component c2 = m.createComponent()
116 .setImplementation(new MyComponent2(e))
117 .add(m.createServiceDependency()
118 .setService(Service1.class)
119 .setRequired(false)
120 .setAutoConfig(false)
121 .setCallbacks("added", null, null));
122
123 Component c3 = m.createComponent()
124 .setInterface(Service2.class.getName(), null)
125 .setImplementation(Service2Impl.class);
126
127 Hashtable h = new Hashtable();
128 h.put("type", "xx");
129 Component c4 = m.createComponent()
130 .setInterface(Service3.class.getName(), h)
131 .setImplementation(Service3Impl1.class);
132
133 h = new Hashtable();
134 h.put("type", "yy");
135 Component c5 = m.createComponent()
136 .setInterface(Service3.class.getName(), h)
137 .setImplementation(Service3Impl2.class);
138
139
140 System.out.println("\n+++ Adding c2 / MyComponent2");
141 m.add(c2);
142 System.out.println("\n+++ Adding c3 / Service2");
143 m.add(c3);
144 System.out.println("\n+++ Adding c4 / Service3(xx)");
145 m.add(c4);
146 System.out.println("\n+++ Adding c1 / MyComponent1");
147 m.add(c1);
148
149 // c1 have declared two extra dependency on Service3 (xx/yy).
150 // So, because we have not yet added c5 (yy), c1 should not be started currently.
151 // But, now, we'll add c5 (Service3/yy) and c1 should then be started ...
152 System.out.println("\n+++ Adding c5 / Service3(yy)");
153 m.add(c5);
154 e.waitForStep(3, 3000);
155 m.clear();
156 }
157
158
159 public interface Service1 {}
160 public interface Service2 {}
161 public interface Service3 {}
162
163 public static class Service2Impl implements Service2 {}
164 public static class Service3Impl1 implements Service3 {}
165 public static class Service3Impl2 implements Service3 {}
166
167 public static class MyComponent1 implements Service1 {
168 Service2 m_service2;
169 Service3 m_service3_xx;
170 Service3 m_service3_yy;
171 Ensure m_ensure;
172
173 public MyComponent1(Ensure e) {
174 m_ensure = e;
175 }
176
177 void init(Component c) {
178 m_ensure.step(1);
179 DependencyManager dm = c.getDependencyManager();
180 // Service3/xx currently available
181 Dependency d1 =
182 dm.createServiceDependency()
183 .setService(Service3.class, "(type=xx)")
184 .setRequired(true)
185 .setAutoConfig("m_service3_xx");
186
187 // Service3/yy not yet available
188 Dependency d2 =
189 dm.createServiceDependency()
190 .setService(Service3.class, "(type=yy)")
191 .setRequired(true)
192 .setAutoConfig("m_service3_yy");
193 c.add(d1, d2);
194 }
195
196 void start() {
197 System.out.println("MyComponent1.start");
198 Assert.assertNotNull(m_service2);
199 Assert.assertNotNull(m_service3_xx);
200 Assert.assertNotNull(m_service3_yy);
201 m_ensure.step(2);
202 }
203 }
204
205 public static class MyComponent2 {
206 Ensure m_ensure;
207
208 public MyComponent2(Ensure e) {
209 m_ensure = e;
210 }
211
212 void added(Service1 s1) {
213 System.out.println("MyComponent2.bind(" + s1 + ")");
214 Assert.assertNotNull(s1);
215 m_ensure.step(3);
216 }
217
218 void start() {
219 System.out.println("MyComponent2.start");
220 }
221 }
222}