blob: 9c1a4b110afe737d7883001c4333d3ebf94f3775 [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.ArrayList;
25import java.util.Hashtable;
26import java.util.List;
27import java.util.Properties;
28
29import org.apache.felix.dm.Component;
30import org.apache.felix.dm.Dependency;
31import org.apache.felix.dm.DependencyManager;
32import org.junit.Assert;
33import org.osgi.framework.BundleContext;
34import org.osgi.framework.ServiceReference;
35
36/**
37 * One consumer, Three providers. The Consumer has two required dependency on provider1, provider2, and one
38 * instance-bound required dependency on provider3.
39 * When the three providers are there, the consumer is started.
40 *
41 * This test asserts the following correct behaviors:
42 * - when we remove the dependency on provider2, then the consumer is not stopped.
43 * - when we remove the (instance-bound) dependency on provider3, then the consumer os not stopped.
44 *
45 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
46 */
47@SuppressWarnings({"unchecked", "rawtypes", "unused"})
48public class RemovedDependencyTest extends TestBase {
49 public void testRemoveDependencyAndConsumerMustRemainStarted() {
50 DependencyManager m = getDM();
51 // helper class that ensures certain steps get executed in sequence
52 Ensure e = new Ensure();
53 // Create two providers
54 Hashtable props = new Hashtable();
55 props.put("name", "provider1");
56 Component sp = component(m).impl(new ServiceProvider(e)).provides(ServiceInterface.class, props).build();
57 props = new Properties();
58 props.put("name", "provider2");
59 Component sp2 = component(m).impl(new ServiceProvider(e)).provides(ServiceInterface.class.getName(), props).build();
60 props = new Properties();
61 props.put("name", "provider3");
62 Component sp3 = component(m).impl(new ServiceProvider(e)).provides(ServiceInterface.class.getName(), props).build();
63
64 // Create the consumer, and start it
65 Dependency d3 = m.createServiceDependency().setService(ServiceInterface.class, "(name=provider3)").setRequired(true).setCallbacks("add", "remove");
66
67 ServiceConsumer consumer = new ServiceConsumer(e, d3);
68 Component sc = component(m).impl(consumer).build();
69
Pierre De Rop11527502016-02-18 21:07:16 +000070 Dependency d1 = serviceDependency(sc, ServiceInterface.class).filter("(name=provider1)").add("add").remove("remove").build();
71 Dependency d2 = serviceDependency(sc, ServiceInterface.class).filter("(name=provider2)").add("add").remove("remove").build();
Pierre De Ropfaca2892016-01-31 23:27:05 +000072
73 sc.add(d1, d2);
74
75 // Add the first two providers and the consumer
76 m.add(sp);
77 m.add(sp2);
78 m.add(sp3);
79 m.add(sc);
80
81 // Check if consumer has been bound to the three providers
82 e.waitForStep(3, 5000);
83 Assert.assertEquals(3, consumer.getProvidersCount());
84 Assert.assertNotNull(consumer.getProvider("provider1"));
85 Assert.assertNotNull(consumer.getProvider("provider2"));
86 Assert.assertNotNull(consumer.getProvider("provider3"));
87
88 // Now remove the provider2, and check if the consumer is still alive
89 sc.remove(d2);
90 Assert.assertFalse(consumer.isStopped());
91 Assert.assertEquals(2, consumer.getProvidersCount());
92 Assert.assertNotNull(consumer.getProvider("provider1"));
93 Assert.assertNull(consumer.getProvider("provider2"));
94 Assert.assertNotNull(consumer.getProvider("provider3"));
95
96 // Now remove the provider3 (the consumer has an instance bound dependency on it), and check if the consumer is still alive
97 sc.remove(d3);
98 Assert.assertFalse(consumer.isStopped());
99 Assert.assertEquals(1, consumer.getProvidersCount());
100 Assert.assertNotNull(consumer.getProvider("provider1"));
101 Assert.assertNull(consumer.getProvider("provider2"));
102 Assert.assertNull(consumer.getProvider("provider3"));
103
104 m.clear();
105 }
106
107 static interface ServiceInterface {
108 public void invoke();
109 }
110
111 class ServiceProvider implements ServiceInterface {
112 final Ensure m_ensure;
113
114 public ServiceProvider(Ensure e) {
115 m_ensure = e;
116 }
117 public void invoke() {
118 m_ensure.step();
119 }
120 }
121
122 class ServiceConsumer {
123 private final Ensure m_ensure;
124 private final List<ServiceReference> m_providers = new ArrayList<>();
125 private BundleContext m_bc;
126 private boolean m_stopped;
127 private final Dependency m_dependency3;
128
129 public ServiceConsumer(Ensure e, Dependency dependency3) {
130 m_ensure = e;
131 m_dependency3 = dependency3;
132 }
133
134 public void add(ServiceReference ref) {
135 debug("ServiceConsumer.add(%s)", ref);
136 m_providers.add(ref);
137 ServiceInterface s = (ServiceInterface) m_bc.getService(ref);
138 s.invoke();
139 }
140
141 public void remove(ServiceReference ref) {
142 debug("ServiceConsumer.remove(%s)", ref);
143 m_providers.remove(ref);
144 debug("ServiceConsumer: current providers list=%s", m_providers);
145 }
146
147 public void init(Component c) {
148 c.add(m_dependency3);
149 }
150
151 public int getProvidersCount() {
152 return m_providers.size();
153 }
154
155 public ServiceInterface getProvider(String name) {
156 for (ServiceReference ref : m_providers) {
157 Object n = ref.getProperty("name");
158 if (n.equals(name)) {
159 return (ServiceInterface) m_bc.getService(ref);
160 }
161 }
162 return null;
163 }
164
165 public void stop() {
166 m_stopped = true;
167 }
168
169 public boolean isStopped() {
170 return m_stopped;
171 }
172 }
173}