blob: 7192423fa0bd48b9aa5595a2f286e5740d040efe [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;
22
23import org.apache.felix.dm.Component;
24import org.apache.felix.dm.DependencyManager;
25import org.junit.Assert;
26
27/**
28 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
29 */
30public class ServiceDependencyInjectionTest extends TestBase {
31 public void testServiceInjection() {
32 DependencyManager m = getDM();
33 Ensure e = new Ensure();
34 // create a service provider and consumer
35 ServiceProvider provider = new ServiceProvider(e);
36 Component sp = component(m).impl(provider).provides(ServiceInterface2.class.getName()).build();
Pierre De Rop11527502016-02-18 21:07:16 +000037 Component sc = component(m).impl(new ServiceConsumer()).withSvc(ServiceInterface2.class).build();
Pierre De Ropfaca2892016-01-31 23:27:05 +000038
39 Component sc2 = component(m) // all dependencies are optional
40 .impl(new ServiceConsumerNamedInjection(false, false))
Pierre De Rop11527502016-02-18 21:07:16 +000041 .withSvc(ServiceInterface2.class, s->s.optional().autoConfig("m_service"))
42 .withSvc(ServiceInterface2.class, s->s.optional().autoConfig("m_service2"))
43 .withSvc(ServiceInterface2.class, s->s.optional().autoConfig("m_service3"))
Pierre De Ropfaca2892016-01-31 23:27:05 +000044 .build();
45
46 Component sc3 = component(m) // second dependency is required, first and third are optional
47 .impl(new ServiceConsumerNamedInjection(false, false))
Pierre De Rop11527502016-02-18 21:07:16 +000048 .withSvc(ServiceInterface2.class, s->s.optional().autoConfig("m_service"))
49 .withSvc(ServiceInterface2.class, s->s.required().autoConfig("m_service2"))
50 .withSvc(ServiceInterface2.class, s->s.optional().autoConfig("m_service3"))
Pierre De Ropfaca2892016-01-31 23:27:05 +000051 .build();
52
53 Component sc4 = component(m)
54 .impl(new ServiceConsumerNamedInjection(true, false)).build();
55 Component sc5 = component(m)
56 .impl(new ServiceConsumerNamedInjection(true, true)).build();
57 m.add(sp);
58 m.add(sc);
59 m.remove(sc);
60 m.add(sc2);
61 m.remove(sc2);
62 m.add(sc3);
63 m.remove(sc4);
64 m.add(sc4);
65 m.remove(sc4);
66 m.add(sc5);
67 m.remove(sc5);
68 m.remove(sp);
69 e.waitForStep(11, 5000);
70 m.clear();
71 }
72
73 static interface ServiceInterface {
74 public void invoke();
75 }
76
77 static interface ServiceInterface2 extends ServiceInterface {
78 public void invoke2();
79 }
80
81 static class ServiceProvider implements ServiceInterface2 {
82 private final Ensure m_ensure;
83 private Ensure.Steps m_invokeSteps = new Ensure.Steps(4, 5, 7, 8, 10, 11, 13, 14);
84 private Ensure.Steps m_invoke2Steps = new Ensure.Steps(1, 2, 3, 6, 9, 12);
85
86 public ServiceProvider(Ensure e) {
87 m_ensure = e;
88 }
89
90 public void invoke() {
91 System.out.println("invoke");
92 m_ensure.steps(m_invokeSteps);
93 }
94
95 public void invoke2() {
96 System.out.println("invoke2");
97 m_ensure.steps(m_invoke2Steps);
98 }
99 }
100
101 static class ServiceConsumer {
102 private volatile ServiceInterface2 m_service;
103 private volatile ServiceInterface2 m_service2;
104
105 public void init() {
106 // invoke the second method of the interface via both injected members, to ensure
107 // neither of them is a null object (or null)
108 m_service.invoke2();
109 m_service2.invoke2();
110 Assert.assertEquals("Both members should have been injected with the same service.", m_service, m_service2);
111 }
112 }
113
114 class ServiceConsumerNamedInjection {
115 private volatile ServiceInterface2 m_service;
116 private volatile ServiceInterface m_service2;
117 private volatile Object m_service3;
118 private final boolean m_secondDependencyRequired;
119 private final boolean m_instanceBound;
120
121 ServiceConsumerNamedInjection(boolean instanceBound, boolean withSecondRequired) {
122 m_secondDependencyRequired = withSecondRequired;
123 m_instanceBound = instanceBound;
124 }
125
126 public void init(Component c) {
127 if (m_instanceBound) {
128 DependencyManager m = c.getDependencyManager();
129 c.add(m.createServiceDependency().setService(ServiceInterface2.class).setRequired(false).setAutoConfig("m_service"),
130 m.createServiceDependency().setService(ServiceInterface2.class).setRequired(m_secondDependencyRequired).setAutoConfig("m_service2"),
131 m.createServiceDependency().setService(ServiceInterface2.class).setRequired(false).setAutoConfig("m_service3"));
132 } else {
133 check();
134 }
135 }
136
137 public void start() {
138 if (m_instanceBound) {
139 check();
140 }
141 }
142
143 public void check() {
144 warn("ServiceConsumerNamedInjectionInstanceBound: m_service=%s, m_service2=%s, m_service3=%s", m_service, m_service2, m_service3);
145 // invoke the second method
146 m_service.invoke2();
147 // invoke the first method (twice)
148 m_service2.invoke();
149 ((ServiceInterface) m_service3).invoke();
150 Assert.assertNotNull("Should have been injected", m_service);
151 Assert.assertNotNull("Should have been injected", m_service2);
152 Assert.assertNotNull("Should have been injected", m_service3);
153 Assert.assertEquals("Members should have been injected with the same service.", m_service, m_service2);
154 Assert.assertEquals("Members should have been injected with the same service.", m_service, m_service3);
155 }
156 }
157}