Fix FELIX-4232 Service Dependency Interceptors should be indicated in the instance architecture
Added interceptors to the instance architecture and implement some tests.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1524348 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/runtime/core-it/ipojo-core-service-dependency-interceptor-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/interceptors/FilterRankingInterceptor.java b/ipojo/runtime/core-it/ipojo-core-service-dependency-interceptor-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/interceptors/FilterRankingInterceptor.java
index 8331a96..4e7a7d6 100644
--- a/ipojo/runtime/core-it/ipojo-core-service-dependency-interceptor-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/interceptors/FilterRankingInterceptor.java
+++ b/ipojo/runtime/core-it/ipojo-core-service-dependency-interceptor-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/interceptors/FilterRankingInterceptor.java
@@ -64,7 +64,6 @@
if (inverse) {
Collections.reverse(references);
}
- System.out.println("Ref: " + references + " / " + matching);
return references;
}
diff --git a/ipojo/runtime/core-it/ipojo-core-service-dependency-interceptor-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/TestBindingInterceptors.java b/ipojo/runtime/core-it/ipojo-core-service-dependency-interceptor-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/TestBindingInterceptors.java
index b20ad3e..36b3f68 100644
--- a/ipojo/runtime/core-it/ipojo-core-service-dependency-interceptor-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/TestBindingInterceptors.java
+++ b/ipojo/runtime/core-it/ipojo-core-service-dependency-interceptor-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/TestBindingInterceptors.java
@@ -174,4 +174,30 @@
assertThat(check.getProps().get("enhanced")).isNotNull();
}
+ @Test
+ public void testArchitecture() {
+ // Create the interceptor
+ Properties configuration = new Properties();
+ configuration.put("target", "(dependency.id=foo)");
+ ComponentInstance interceptor = ipojoHelper.createComponentInstance("org.apache.felix.ipojo.runtime.core.test" +
+ ".interceptors.ProxyBindingInterceptor", configuration);
+
+ // Create the FooConsumer
+ ComponentInstance instance = ipojoHelper.createComponentInstance("org.apache.felix.ipojo.runtime.core.test" +
+ ".components.FooConsumer");
+
+ osgiHelper.waitForService(CheckService.class.getName(),
+ "(instance.name=" + instance.getInstanceName() + ")",
+ 1000, true);
+
+ assertThat(instance.getInstanceDescription().getDescription().toString()).contains
+ ("servicebindinginterceptor");
+ assertThat(instance.getInstanceDescription().getDescription().toString()).contains
+ ("target=\"(dependency.id=foo)\"");
+ assertThat(instance.getInstanceDescription().getDescription().toString()).contains
+ ("instance.name=\"" + interceptor.getInstanceName() + "\"");
+ assertThat(instance.getInstanceDescription().getDescription().toString()).contains
+ ("bundle.id=\"" + getTestBundle().getBundleId() + "\"");
+ }
+
}
diff --git a/ipojo/runtime/core-it/ipojo-core-service-dependency-interceptor-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/TestHidingServices.java b/ipojo/runtime/core-it/ipojo-core-service-dependency-interceptor-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/TestHidingServices.java
index c4cdab2..b67af97 100644
--- a/ipojo/runtime/core-it/ipojo-core-service-dependency-interceptor-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/TestHidingServices.java
+++ b/ipojo/runtime/core-it/ipojo-core-service-dependency-interceptor-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/TestHidingServices.java
@@ -20,6 +20,7 @@
package org.apache.felix.ipojo.runtime.core.test.dependencies;
import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.runtime.core.test.services.CheckService;
import org.apache.felix.ipojo.runtime.core.test.services.Setter;
import org.junit.Before;
import org.junit.Test;
@@ -102,5 +103,31 @@
assertThat(instance.getState()).isEqualTo(ComponentInstance.VALID);
}
+ @Test
+ public void testArchitecture() {
+ // Create the interceptor
+ Properties configuration = new Properties();
+ configuration.put("target", "(dependency.id=foo)");
+
+
+ // Create the FooConsumer
+ ComponentInstance instance = ipojoHelper.createComponentInstance("org.apache.felix.ipojo.runtime.core.test" +
+ ".components.FooConsumer");
+
+ assertThat(instance.getState()).isEqualTo(ComponentInstance.VALID);
+
+ ComponentInstance interceptor = ipojoHelper.createComponentInstance("org.apache.felix.ipojo.runtime.core.test" +
+ ".interceptors.HidingTrackingInterceptor", configuration);
+
+ assertThat(instance.getInstanceDescription().getDescription().toString()).contains
+ ("servicetrackinginterceptor");
+ assertThat(instance.getInstanceDescription().getDescription().toString()).contains
+ ("target=\"(dependency.id=foo)\"");
+ assertThat(instance.getInstanceDescription().getDescription().toString()).contains
+ ("instance.name=\"" + interceptor.getInstanceName() + "\"");
+ assertThat(instance.getInstanceDescription().getDescription().toString()).contains
+ ("bundle.id=\"" + getTestBundle().getBundleId() + "\"");
+ }
+
}
diff --git a/ipojo/runtime/core-it/ipojo-core-service-dependency-interceptor-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/TestRankingServices.java b/ipojo/runtime/core-it/ipojo-core-service-dependency-interceptor-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/TestRankingServices.java
index ac7cc06..c405eb1 100644
--- a/ipojo/runtime/core-it/ipojo-core-service-dependency-interceptor-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/TestRankingServices.java
+++ b/ipojo/runtime/core-it/ipojo-core-service-dependency-interceptor-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/TestRankingServices.java
@@ -183,6 +183,35 @@
assertThat(consumer.getState()).isEqualTo(ComponentInstance.INVALID);
}
+ @Test
+ public void testArchitecture() {
+ // Provider with grade 0 first
+ provider1 = provider(0);
+ provider2 = provider(1);
+
+ // Create the interceptor
+ Properties configuration = new Properties();
+ configuration.put("target", "(dependency.id=foo)");
+ ComponentInstance interceptor = ipojoHelper.createComponentInstance("org.apache.felix.ipojo.runtime.core" +
+ ".test.interceptors.FilterRankingInterceptor", configuration);
+
+ // Create the FooConsumer
+ ComponentInstance instance = ipojoHelper.createComponentInstance("org.apache.felix.ipojo.runtime.core.test" +
+ ".components.FooConsumer");
+
+ // Check we are using provider 2
+ osgiHelper.waitForService(CheckService.class.getName(), null, 1000, true);
+
+ assertThat(instance.getInstanceDescription().getDescription().toString()).contains
+ ("servicerankinginterceptor");
+ assertThat(instance.getInstanceDescription().getDescription().toString()).contains
+ ("target=\"(dependency.id=foo)\"");
+ assertThat(instance.getInstanceDescription().getDescription().toString()).contains
+ ("instance.name=\"" + interceptor.getInstanceName() + "\"");
+ assertThat(instance.getInstanceDescription().getDescription().toString()).contains
+ ("bundle.id=\"" + getTestBundle().getBundleId() + "\"");
+ }
+
private ComponentInstance provider(int i) {
Dictionary<String, String> configuration = new Hashtable<String, String>();
configuration.put("grade", Integer.toString(i));
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/dependency/impl/ServiceReferenceManager.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/dependency/impl/ServiceReferenceManager.java
index 96e5ed7..80849c6 100644
--- a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/dependency/impl/ServiceReferenceManager.java
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/dependency/impl/ServiceReferenceManager.java
@@ -872,6 +872,70 @@
m_dependency.onChange(changeset);
}
+ /**
+ * Gets the list of tracking interceptors attached to the current service dependency.
+ * @return the list of service references of the tracking interceptors participating to the resolution of the
+ * current service dependency. An empty list is returned is there are no participating interceptors.
+ * @since 1.10.2
+ */
+ public List<ServiceReference> getTrackingInterceptorReferences() {
+ try {
+ m_dependency.acquireReadLockIfNotHeld();
+ if (m_trackingInterceptorTracker != null) {
+ List<ServiceReference> refs = m_trackingInterceptorTracker.getUsedServiceReferences();
+ if (refs != null) {
+ return refs;
+ }
+ }
+ return Collections.emptyList();
+ } finally {
+ m_dependency.releaseReadLockIfHeld();
+ }
+ }
+
+ /**
+ * Gets the list of binding interceptors attached to the current service dependency.
+ * @return the list of service references of the binding interceptors participating to the resolution of the
+ * current service dependency. An empty list is returned is there are no participating interceptors.
+ * @since 1.10.2
+ */
+ public List<ServiceReference> getBindingInterceptorReferences() {
+ try {
+ m_dependency.acquireReadLockIfNotHeld();
+ if (m_bindingInterceptorTracker != null) {
+ List<ServiceReference> refs = m_bindingInterceptorTracker.getUsedServiceReferences();
+ if (refs != null) {
+ return refs;
+ }
+ }
+ return Collections.emptyList();
+ } finally {
+ m_dependency.releaseReadLockIfHeld();
+ }
+ }
+
+ /**
+ * Gets the service reference of the currently attached ranking interceptor. As only one ranking interceptor can
+ * be attached at a point on time, this is not a list but only one reference.
+ * @return the service reference of the ranking interceptor participating to the resolution of the current
+ * service dependency. {@code null} if no (external) ranking interceptor is currently attached.
+ * @since 1.10.2
+ */
+ public ServiceReference getRankingInterceptorReference() {
+ try {
+ m_dependency.acquireReadLockIfNotHeld();
+ if (m_rankingInterceptorTracker != null) {
+ List<ServiceReference> references = m_rankingInterceptorTracker.getUsedServiceReferences();
+ if (references != null && ! references.isEmpty()) {
+ return references.get(0);
+ }
+ }
+ return null;
+ } finally {
+ m_dependency.releaseReadLockIfHeld();
+ }
+ }
+
private class RankingResult {
final List<ServiceReference> departures;
final List<ServiceReference> arrivals;
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java
index b5cf947..a29b18b 100644
--- a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java
@@ -20,6 +20,8 @@
import org.apache.felix.ipojo.Factory;
import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.dependency.impl.ServiceReferenceManager;
+import org.apache.felix.ipojo.dependency.interceptors.ServiceTrackingInterceptor;
import org.apache.felix.ipojo.metadata.Attribute;
import org.apache.felix.ipojo.metadata.Element;
import org.apache.felix.ipojo.util.DependencyModel;
@@ -27,6 +29,7 @@
import org.osgi.framework.ServiceReference;
import java.util.List;
+import java.util.Map;
/**
* Dependency Handler Description.
@@ -68,103 +71,138 @@
*/
public Element getHandlerInfo() {
Element deps = super.getHandlerInfo();
- for (int i = 0; i < m_dependencies.length; i++) {
+ for (DependencyDescription dependency : m_dependencies) {
String state = "resolved";
- if (m_dependencies[i].getState() == DependencyModel.UNRESOLVED) {
+ if (dependency.getState() == DependencyModel.UNRESOLVED) {
state = "unresolved";
}
- if (m_dependencies[i].getState() == DependencyModel.BROKEN) {
+ if (dependency.getState() == DependencyModel.BROKEN) {
state = "broken";
}
Element dep = new Element("Requires", "");
- dep.addAttribute(new Attribute("Specification", m_dependencies[i].getInterface()));
- dep.addAttribute(new Attribute("Id", m_dependencies[i].getId()));
-
- if (m_dependencies[i].getFilter() != null) {
- dep.addAttribute(new Attribute("Filter", m_dependencies[i].getFilter()));
+ dep.addAttribute(new Attribute("Specification", dependency.getInterface()));
+ dep.addAttribute(new Attribute("Id", dependency.getId()));
+
+ if (dependency.getFilter() != null) {
+ dep.addAttribute(new Attribute("Filter", dependency.getFilter()));
}
-
- if (m_dependencies[i].isOptional()) {
+
+ if (dependency.isOptional()) {
dep.addAttribute(new Attribute("Optional", "true"));
- if (m_dependencies[i].supportsNullable()) {
- dep.addAttribute(new Attribute("Nullable", "true"));
+ if (dependency.supportsNullable()) {
+ dep.addAttribute(new Attribute("Nullable", "true"));
}
- if (m_dependencies[i].getDefaultImplementation() != null) {
- dep.addAttribute(new Attribute("Default-Implementation", m_dependencies[i].getDefaultImplementation()));
+ if (dependency.getDefaultImplementation() != null) {
+ dep.addAttribute(new Attribute("Default-Implementation", dependency.getDefaultImplementation()));
}
} else {
dep.addAttribute(new Attribute("Optional", "false"));
}
- if (m_dependencies[i].isMultiple()) {
+ if (dependency.isMultiple()) {
dep.addAttribute(new Attribute("Aggregate", "true"));
} else {
dep.addAttribute(new Attribute("Aggregate", "false"));
}
-
- if (m_dependencies[i].isProxy()) {
+
+ if (dependency.isProxy()) {
dep.addAttribute(new Attribute("Proxy", "true"));
} else {
dep.addAttribute(new Attribute("Proxy", "false"));
}
-
+
String policy = "dynamic";
- if (m_dependencies[i].getPolicy() == DependencyModel.STATIC_BINDING_POLICY) {
+ if (dependency.getPolicy() == DependencyModel.STATIC_BINDING_POLICY) {
policy = "static";
- } else if (m_dependencies[i].getPolicy() == DependencyModel.DYNAMIC_PRIORITY_BINDING_POLICY) {
+ } else if (dependency.getPolicy() == DependencyModel.DYNAMIC_PRIORITY_BINDING_POLICY) {
policy = "dynamic-priority";
}
dep.addAttribute(new Attribute("Binding-Policy", policy));
-
- if (m_dependencies[i].getComparator() != null) {
- dep.addAttribute(new Attribute("Comparator", m_dependencies[i].getComparator()));
+
+ if (dependency.getComparator() != null) {
+ dep.addAttribute(new Attribute("Comparator", dependency.getComparator()));
}
-
+
dep.addAttribute(new Attribute("State", state));
- List<ServiceReference> set = m_dependencies[i].getUsedServices();
+ List<ServiceReference> set = dependency.getUsedServices();
if (set != null) {
for (ServiceReference ref : set) {
Element use = new Element("Uses", "");
- use.addAttribute(new Attribute(Constants.SERVICE_ID, ref.getProperty(Constants.SERVICE_ID).toString()));
- String instance = (String) ref.getProperty(Factory.INSTANCE_NAME_PROPERTY);
- if (instance != null) {
- use.addAttribute(new Attribute(Factory.INSTANCE_NAME_PROPERTY, instance));
- }
+ computeServiceReferenceDescription(ref, use);
dep.addElement(use);
}
}
- set = m_dependencies[i].getServiceReferences();
+ set = dependency.getServiceReferences();
if (set != null) {
for (ServiceReference ref : set) {
Element use = new Element("Selected", "");
- use.addAttribute(new Attribute(Constants.SERVICE_ID, ref.getProperty(Constants.SERVICE_ID).toString()));
- String instance = (String) ref.getProperty(Factory.INSTANCE_NAME_PROPERTY);
- if (instance != null) {
- use.addAttribute(new Attribute(Factory.INSTANCE_NAME_PROPERTY, instance));
- }
+ computeServiceReferenceDescription(ref, use);
dep.addElement(use);
}
}
- if (m_dependencies[i].getDependency() != null) {
- set = m_dependencies[i].getDependency().getServiceReferenceManager().getMatchingServices();
- if (set != null) {
- for (ServiceReference ref : set) {
- Element use = new Element("Matches", "");
- use.addAttribute(new Attribute(Constants.SERVICE_ID, ref.getProperty(Constants.SERVICE_ID).toString()));
- String instance = (String) ref.getProperty(Factory.INSTANCE_NAME_PROPERTY);
- if (instance != null) {
- use.addAttribute(new Attribute(Factory.INSTANCE_NAME_PROPERTY, instance));
- }
- dep.addElement(use);
- }
+ final ServiceReferenceManager serviceReferenceManager = dependency.getDependency()
+ .getServiceReferenceManager();
+ if (serviceReferenceManager == null) {
+ // Exit here, cannot compute anything else.
+ deps.addElement(dep);
+ continue;
+ }
+
+ set = serviceReferenceManager.getMatchingServices();
+ if (set != null) {
+ for (ServiceReference ref : set) {
+ Element use = new Element("Matches", "");
+ computeServiceReferenceDescription(ref, use);
+ dep.addElement(use);
}
}
+ // Add interceptors to the description
+ List<ServiceReference> interceptors = serviceReferenceManager.getTrackingInterceptorReferences();
+ for (ServiceReference ref : interceptors) {
+ Element itcp = new Element("ServiceTrackingInterceptor", "");
+ computeInterceptorDescription(ref, itcp);
+ dep.addElement(itcp);
+ }
+
+ ServiceReference ref = serviceReferenceManager.getRankingInterceptorReference();
+ if (ref != null) {
+ Element itcp = new Element("ServiceRankingInterceptor", "");
+ computeInterceptorDescription(ref, itcp);
+ dep.addElement(itcp);
+ }
+
+ interceptors = serviceReferenceManager.getBindingInterceptorReferences();
+ for (ServiceReference rf : interceptors) {
+ Element itcp = new Element("ServiceBindingInterceptor", "");
+ computeInterceptorDescription(rf, itcp);
+ dep.addElement(itcp);
+ }
+
deps.addElement(dep);
}
return deps;
}
+ private void computeServiceReferenceDescription(ServiceReference ref, Element use) {
+ use.addAttribute(new Attribute(Constants.SERVICE_ID, ref.getProperty(Constants.SERVICE_ID).toString()));
+ String instance = (String) ref.getProperty(Factory.INSTANCE_NAME_PROPERTY);
+ if (instance != null) {
+ use.addAttribute(new Attribute(Factory.INSTANCE_NAME_PROPERTY, instance));
+ }
+ }
+
+ private void computeInterceptorDescription(ServiceReference ref, Element itcp) {
+ itcp.addAttribute(new Attribute(Constants.SERVICE_ID, ref.getProperty(Constants.SERVICE_ID).toString()));
+ itcp.addAttribute(new Attribute("bundle.id", Long.toString(ref.getBundle().getBundleId())));
+ String instance = (String) ref.getProperty(Factory.INSTANCE_NAME_PROPERTY);
+ if (instance != null) {
+ itcp.addAttribute(new Attribute(Factory.INSTANCE_NAME_PROPERTY, instance));
+ }
+ itcp.addAttribute(new Attribute("target", ref.getProperty(ServiceTrackingInterceptor.TARGET_PROPERTY)
+ .toString()));
+ }
+
}