Pierre De Rop | 3a00a21 | 2015-03-01 09:27:46 +0000 | [diff] [blame^] | 1 | /* |
| 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 | */ |
| 19 | package org.apache.felix.dm.itest.api; |
| 20 | |
| 21 | import java.util.Hashtable; |
| 22 | |
| 23 | import org.junit.Assert; |
| 24 | |
| 25 | import org.apache.felix.dm.Component; |
| 26 | import org.apache.felix.dm.Dependency; |
| 27 | import org.apache.felix.dm.DependencyManager; |
| 28 | import org.apache.felix.dm.itest.util.Ensure; |
| 29 | import 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"}) |
| 36 | public 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 | } |