Pierre De Rop | faca289 | 2016-01-31 23:27:05 +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.lambda.itest; |
| 20 | |
| 21 | import static org.apache.felix.dm.lambda.DependencyManagerActivator.component; |
| 22 | |
| 23 | import org.apache.felix.dm.Component; |
| 24 | import org.apache.felix.dm.DependencyManager; |
| 25 | import org.junit.Assert; |
| 26 | |
| 27 | /** |
| 28 | * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a> |
| 29 | */ |
Pierre De Rop | faca289 | 2016-01-31 23:27:05 +0000 | [diff] [blame] | 30 | public class MultipleExtraDependenciesTest extends TestBase { |
| 31 | /** |
| 32 | * Check that list of extra dependencies (defined from init method) are handled properly. |
| 33 | * The extra dependencies are added using a List object (Component.add(List)). |
| 34 | * A component c1 will define two extra dependencies over *available* c4/c5 services. |
| 35 | */ |
| 36 | public void testWithTwoAvailableExtraDependency() { |
| 37 | DependencyManager m = getDM(); |
| 38 | // Helper class that ensures certain steps get executed in sequence |
| 39 | Ensure e = new Ensure(); |
Pierre De Rop | 1152750 | 2016-02-18 21:07:16 +0000 | [diff] [blame] | 40 | Component c1 = component(m).provides(Service1.class).impl(new MyComponent1(e)).withSvc(Service2.class, srv->srv.autoConfig("m_service2")).build(); |
| 41 | Component c2 = component(m).impl(new MyComponent2(e)).withSvc(Service1.class, srv->srv.required(false).autoConfig(false).add("added")).build(); |
Pierre De Rop | faca289 | 2016-01-31 23:27:05 +0000 | [diff] [blame] | 42 | Component c3 = component(m).provides(Service2.class).impl(Service2Impl.class).build(); |
| 43 | Component c4 = component(m).impl(Service3Impl1.class).provides(Service3.class, type -> "xx").build(); |
| 44 | Component c5 = component(m).impl(Service3Impl2.class).provides(Service3.class, type -> "yy").build(); |
| 45 | |
| 46 | System.out.println("\n+++ Adding c2 / MyComponent2"); |
| 47 | m.add(c2); |
| 48 | System.out.println("\n+++ Adding c3 / Service2"); |
| 49 | m.add(c3); |
| 50 | System.out.println("\n+++ Adding c4 / Service3(xx)"); |
| 51 | m.add(c4); |
| 52 | System.out.println("\n+++ Adding c5 / Service3(yy)"); |
| 53 | m.add(c5); |
| 54 | System.out.println("\n+++ Adding c1 / MyComponent1"); |
| 55 | // c1 have declared two extra dependency on Service3 (xx/yy). |
| 56 | // both extra dependencies are available, so the c1 component should be started immediately. |
| 57 | m.add(c1); |
| 58 | e.waitForStep(3, 3000); |
| 59 | m.clear(); |
| 60 | } |
| 61 | |
| 62 | /** |
| 63 | * Check that list of extra dependencies (defined from init method) are handled properly. |
| 64 | * The extra dependencies are added using a List object (Component.add(List)). |
| 65 | * A component c1 will define two extra dependencies over c4/c5. At the point c1.init() |
| 66 | * is adding the two extra dependencies from its init method, c4 is available, but not c5. |
| 67 | * So, c1 is not yet activated. |
| 68 | * Then c5 is added, and it triggers the c1 activation ... |
| 69 | */ |
| 70 | public void testWithOneAvailableExtraDependency() { |
| 71 | DependencyManager m = getDM(); |
| 72 | // Helper class that ensures certain steps get executed in sequence |
| 73 | Ensure e = new Ensure(); |
Pierre De Rop | 1152750 | 2016-02-18 21:07:16 +0000 | [diff] [blame] | 74 | Component c1 = component(m).provides(Service1.class).impl(new MyComponent1(e)).withSvc(Service2.class, srv->srv.autoConfig("m_service2")).build(); |
| 75 | Component c2 = component(m).impl(new MyComponent2(e)).withSvc(Service1.class, srv->srv.required(false).autoConfig(false).add("added")).build(); |
Pierre De Rop | faca289 | 2016-01-31 23:27:05 +0000 | [diff] [blame] | 76 | Component c3 = component(m).provides(Service2.class).impl(Service2Impl.class).build(); |
| 77 | Component c4 = component(m).impl(Service3Impl1.class).provides(Service3.class, type -> "xx").build(); |
| 78 | Component c5 = component(m).impl(Service3Impl2.class).provides(Service3.class, type -> "yy").build(); |
| 79 | |
| 80 | System.out.println("\n+++ Adding c2 / MyComponent2"); |
| 81 | m.add(c2); |
| 82 | System.out.println("\n+++ Adding c3 / Service2"); |
| 83 | m.add(c3); |
| 84 | System.out.println("\n+++ Adding c4 / Service3(xx)"); |
| 85 | m.add(c4); |
| 86 | System.out.println("\n+++ Adding c1 / MyComponent1"); |
| 87 | m.add(c1); |
| 88 | |
| 89 | // c1 have declared two extra dependency on Service3 (xx/yy). |
| 90 | // So, because we have not yet added c5 (yy), c1 should not be started currently. |
| 91 | // But, now, we'll add c5 (Service3/yy) and c1 should then be started ... |
| 92 | System.out.println("\n+++ Adding c5 / Service3(yy)"); |
| 93 | m.add(c5); |
| 94 | e.waitForStep(3, 3000); |
| 95 | m.clear(); |
| 96 | } |
| 97 | |
| 98 | |
| 99 | public interface Service1 {} |
| 100 | public interface Service2 {} |
| 101 | public interface Service3 {} |
| 102 | |
| 103 | public static class Service2Impl implements Service2 {} |
| 104 | public static class Service3Impl1 implements Service3 {} |
| 105 | public static class Service3Impl2 implements Service3 {} |
| 106 | |
| 107 | public static class MyComponent1 implements Service1 { |
| 108 | Service2 m_service2; |
| 109 | Service3 m_service3_xx; |
| 110 | Service3 m_service3_yy; |
| 111 | Ensure m_ensure; |
| 112 | |
| 113 | public MyComponent1(Ensure e) { |
| 114 | m_ensure = e; |
| 115 | } |
| 116 | |
| 117 | void init(Component c) { |
| 118 | m_ensure.step(1); |
| 119 | // Service3/xx currently available |
| 120 | // Service3/yy not yet available |
| 121 | |
| 122 | component(c, comp -> comp |
Pierre De Rop | 1152750 | 2016-02-18 21:07:16 +0000 | [diff] [blame] | 123 | .withSvc(Service3.class, srv->srv.filter("(type=xx)").autoConfig("m_service3_xx")) |
| 124 | .withSvc(Service3.class, srv->srv.filter("(type=yy)").autoConfig("m_service3_yy"))); |
Pierre De Rop | faca289 | 2016-01-31 23:27:05 +0000 | [diff] [blame] | 125 | } |
| 126 | |
| 127 | void start() { |
| 128 | System.out.println("MyComponent1.start"); |
| 129 | Assert.assertNotNull(m_service2); |
| 130 | Assert.assertNotNull(m_service3_xx); |
| 131 | Assert.assertNotNull(m_service3_yy); |
| 132 | m_ensure.step(2); |
| 133 | } |
| 134 | } |
| 135 | |
| 136 | public static class MyComponent2 { |
| 137 | Ensure m_ensure; |
| 138 | |
| 139 | public MyComponent2(Ensure e) { |
| 140 | m_ensure = e; |
| 141 | } |
| 142 | |
| 143 | void added(Service1 s1) { |
| 144 | System.out.println("MyComponent2.bind(" + s1 + ")"); |
| 145 | Assert.assertNotNull(s1); |
| 146 | m_ensure.step(3); |
| 147 | } |
| 148 | |
| 149 | void start() { |
| 150 | System.out.println("MyComponent2.start"); |
| 151 | } |
| 152 | } |
| 153 | } |