You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by cs...@apache.org on 2017/11/03 15:25:00 UTC

[01/11] aries-jax-rs-whiteboard git commit: Register providers using in order

Repository: aries-jax-rs-whiteboard
Updated Branches:
  refs/heads/master ff21399e7 -> a544f13be


Register providers using in order

Using ServiceReference natural ordering


Project: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/repo
Commit: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/commit/7126342b
Tree: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/tree/7126342b
Diff: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/diff/7126342b

Branch: refs/heads/master
Commit: 7126342b668a3c870accf2cf450854a156a58934
Parents: 02e50f0
Author: Carlos Sierra <cs...@apache.org>
Authored: Mon Oct 30 08:28:35 2017 +0100
Committer: Carlos Sierra <cs...@apache.org>
Committed: Fri Nov 3 16:18:23 2017 +0100

----------------------------------------------------------------------
 .../jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java   | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/7126342b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java
----------------------------------------------------------------------
diff --git a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java
index c77da95..41e482a 100644
--- a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java
+++ b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java
@@ -21,6 +21,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Comparator;
+import java.util.TreeSet;
 import java.util.stream.Stream;
 
 import javax.ws.rs.core.Application;
@@ -46,7 +47,8 @@ public class CXFJaxRsServiceRegistrator {
 
     private final Application _application;
     private final Bus _bus;
-    private final Collection<ServiceTuple<?>> _providers = new ArrayList<>();
+    private final Collection<ServiceTuple<?>> _providers = new TreeSet<>(
+        Comparator.comparing(ServiceTuple::getServiceReference));
     private final Collection<ResourceProvider> _services = new ArrayList<>();
     private volatile boolean _closed = false;
     private Server _server;


[05/11] aries-jax-rs-whiteboard git commit: Null check

Posted by cs...@apache.org.
Null check


Project: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/repo
Commit: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/commit/d9b6c9f2
Tree: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/tree/d9b6c9f2
Diff: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/diff/d9b6c9f2

Branch: refs/heads/master
Commit: d9b6c9f2da78ef39154d98e0cc45b550d5da518b
Parents: d20ca62
Author: Carlos Sierra <cs...@apache.org>
Authored: Thu Nov 2 18:40:03 2017 +0100
Committer: Carlos Sierra <cs...@apache.org>
Committed: Fri Nov 3 16:18:24 2017 +0100

----------------------------------------------------------------------
 .../java/org/apache/aries/jax/rs/whiteboard/internal/Utils.java    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/d9b6c9f2/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Utils.java
----------------------------------------------------------------------
diff --git a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Utils.java b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Utils.java
index a509720..6fd93aa 100644
--- a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Utils.java
+++ b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Utils.java
@@ -421,7 +421,7 @@ public class Utils {
                         set.remove(e);
 
                         _sentEvents.compute(key, (___, sentEvent) -> {
-                            if (sentEvent.getEvent() == e) {
+                            if (sentEvent != null && sentEvent.getEvent() == e) {
                                 sentEvent.terminate();
 
                                 if (!set.isEmpty()) {


[04/11] aries-jax-rs-whiteboard git commit: Check for exceptions when adding providers

Posted by cs...@apache.org.
Check for exceptions when adding providers


Project: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/repo
Commit: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/commit/e7fde033
Tree: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/tree/e7fde033
Diff: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/diff/e7fde033

Branch: refs/heads/master
Commit: e7fde0335c2bb25ba8ba09e25959a43a31f345a5
Parents: 8fd8f7f
Author: Carlos Sierra <cs...@apache.org>
Authored: Mon Oct 30 14:51:50 2017 +0100
Committer: Carlos Sierra <cs...@apache.org>
Committed: Fri Nov 3 16:18:24 2017 +0100

----------------------------------------------------------------------
 .../jax/rs/whiteboard/internal/Whiteboard.java  | 43 ++++++++++++++------
 1 file changed, 31 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/e7fde033/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Whiteboard.java
----------------------------------------------------------------------
diff --git a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Whiteboard.java b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Whiteboard.java
index b7c412b..815dbac 100644
--- a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Whiteboard.java
+++ b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Whiteboard.java
@@ -529,21 +529,40 @@ public class Whiteboard {
                 just(serviceReference),
                 _runtime::addNotGettableExtension,
                 _runtime::removeNotGettableExtension
-            ).effects(
-                registrator::addProvider,
-                registrator::removeProvider
-            ).effects(
-                __ -> _runtime.addApplicationExtension(
-                    applicationName, serviceReference),
-                __ -> _runtime.removeApplicationExtension(
-                    applicationName, serviceReference)
-            ).then(
-                register(
-                    ApplicationExtensionRegistration.class,
-                    new ApplicationExtensionRegistration(){}, properties)
+            ).flatMap(
+                serviceTuple -> {
+                    try {
+                        registrator.addProvider(serviceTuple);
+
+                        _runtime.addApplicationExtension(
+                            applicationName, serviceReference);
+
+                        return
+                            onClose(() -> {
+                                registrator.removeProvider(serviceTuple);
+
+                                _runtime.removeApplicationExtension(
+                                    applicationName, serviceReference);
+                            }).then(
+                            register(
+                                ApplicationExtensionRegistration.class,
+                                new ApplicationExtensionRegistration(){},
+                                properties)
+                        );
+                    }
+                    catch(Exception e) {
+                        return nothing();
+                        /*_runtime.addErroredExtension(serviceReference);
+
+                        return onClose(() -> _runtime.removeErroredExtension(serviceReference)).then(
+                            nothing());*/
+                    }
+                }
             ))));
     }
 
+
+
     private OSGi<ServiceReference<Application>>
         waitForApplicationDependencies(
             ServiceReference<Application> applicationReference,


[10/11] aries-jax-rs-whiteboard git commit: Undo operation when error occurs

Posted by cs...@apache.org.
Undo operation when error occurs


Project: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/repo
Commit: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/commit/a544f13b
Tree: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/tree/a544f13b
Diff: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/diff/a544f13b

Branch: refs/heads/master
Commit: a544f13bef47924002619714f8dfaad7940a59f1
Parents: d9b6c9f
Author: Carlos Sierra <cs...@apache.org>
Authored: Fri Nov 3 16:14:25 2017 +0100
Committer: Carlos Sierra <cs...@apache.org>
Committed: Fri Nov 3 16:18:24 2017 +0100

----------------------------------------------------------------------
 .../internal/CXFJaxRsServiceRegistrator.java     | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/a544f13b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java
----------------------------------------------------------------------
diff --git a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java
index 70b4bf1..b85b902 100644
--- a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java
+++ b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java
@@ -67,7 +67,14 @@ public class CXFJaxRsServiceRegistrator {
 
         _services.add(resourceProvider);
 
-        rewire();
+        try {
+            rewire();
+        }
+        catch (Exception e) {
+            remove(resourceProvider);
+
+            throw e;
+        }
     }
 
     public void addProvider(ServiceTuple<?> tuple) {
@@ -77,7 +84,15 @@ public class CXFJaxRsServiceRegistrator {
 
         _providers.add(tuple);
 
-        rewire();
+        try {
+            rewire();
+        }
+        catch (Exception e) {
+            removeProvider(tuple);
+
+            throw e;
+        }
+
     }
 
     public void close() {


[02/11] aries-jax-rs-whiteboard git commit: Update router semantics

Posted by cs...@apache.org.
Update router semantics


Project: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/repo
Commit: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/commit/02e50f07
Tree: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/tree/02e50f07
Diff: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/diff/02e50f07

Branch: refs/heads/master
Commit: 02e50f07838a3ef3312f059b3ad25830f608de46
Parents: ff21399
Author: Carlos Sierra <cs...@apache.org>
Authored: Thu Oct 26 06:33:59 2017 +0200
Committer: Carlos Sierra <cs...@apache.org>
Committed: Fri Nov 3 16:18:23 2017 +0100

----------------------------------------------------------------------
 .../aries/jax/rs/whiteboard/internal/Utils.java | 44 +++++++++++---------
 1 file changed, 24 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/02e50f07/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Utils.java
----------------------------------------------------------------------
diff --git a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Utils.java b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Utils.java
index b373e20..ea1766b 100644
--- a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Utils.java
+++ b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Utils.java
@@ -36,6 +36,8 @@ import java.util.Iterator;
 import java.util.Map;
 import java.util.TreeSet;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Consumer;
 import java.util.function.Function;
 
@@ -284,31 +286,28 @@ public class Utils {
             return _serviceReference;
         }
 
-
-
     }
 
     private static class HighestRankedRouter<T extends Comparable<? super T>>
         implements Consumer<OSGi.Router<T>> {
 
-        private final TreeSet<Event<T>> _set;
         private final Comparator<Event<T>> _comparator;
-        private SentEvent _sent;
 
         public HighestRankedRouter() {
             _comparator = Comparator.comparing(Event::getContent);
-
-            _set = new TreeSet<>(_comparator);
         }
 
         @Override
         public void accept(OSGi.Router<T> router) {
+            AtomicReference<SentEvent<T>> _sent = new AtomicReference<>();
+            final TreeSet<Event<T>> _set = new TreeSet<>(_comparator);
+
             router.onIncoming(ev -> {
                 synchronized (_set) {
                     _set.add(ev);
 
                     if (ev == _set.last()) {
-                        _sent = router.signalAdd(ev);
+                        _sent.set(router.signalAdd(ev));
                     }
                 }
             });
@@ -320,22 +319,19 @@ public class Utils {
 
                     _set.remove(ev);
 
-                    if (_sent != null && _sent.getEvent() == ev) {
-                        _sent = null;
+                    SentEvent<T> sent = _sent.get();
+
+                    if (sent != null && sent.getEvent() == ev) {
+                        sent.terminate();
+
+                        _sent.set(null);
                     }
 
                     if (!_set.isEmpty()) {
-                        _sent = router.signalAdd(_set.last());
+                        _sent.set(router.signalAdd(_set.last()));
                     }
                 }
             });
-            router.onClose(() -> {
-                if (_sent != null) {
-                    _sent.terminate();
-                }
-
-                _sent = null;
-            });
         }
 
     }
@@ -344,11 +340,8 @@ public class Utils {
         implements Consumer<OSGi.Router<T>> {
 
         private final Function<T, K> _keySupplier;
-        private final ConcurrentHashMap<K, TreeSet<Event<T>>> _map =
-            new ConcurrentHashMap<>();
         private final Consumer<T> _onAddingShadowed;
         private final Consumer<T> _onRemovedShadowed;
-        private final Map<K, SentEvent<T>> _sentEvents = new HashMap<>();
 
         public HighestPerRouter(
             Function<T, K> keySupplier,
@@ -361,6 +354,15 @@ public class Utils {
 
         @Override
         public void accept(OSGi.Router<T> router) {
+            /**
+             * These can't be fields on the class or they would be shared among
+             * invocations to OSGiResult.run :-O
+             */
+            final ConcurrentHashMap<K, TreeSet<Event<T>>> _map =
+                new ConcurrentHashMap<>();
+
+            final Map<K, SentEvent<T>> _sentEvents = new HashMap<>();
+
             router.onIncoming(e -> {
                 K key = _keySupplier.apply(e.getContent());
 
@@ -413,6 +415,8 @@ public class Utils {
 
                         _sentEvents.compute(key, (___, sentEvent) -> {
                             if (sentEvent.getEvent() == e) {
+                                sentEvent.terminate();
+
                                 if (!set.isEmpty()) {
                                     Event<T> last = set.last();
 


[11/11] aries-jax-rs-whiteboard git commit: Move to CachingServiceReference

Posted by cs...@apache.org.
Move to CachingServiceReference


Project: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/repo
Commit: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/commit/d825a6c4
Tree: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/tree/d825a6c4
Diff: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/diff/d825a6c4

Branch: refs/heads/master
Commit: d825a6c4311a6e1d8b908ef7f4d3dadbbbb321b3
Parents: bd57dd7
Author: Carlos Sierra <cs...@apache.org>
Authored: Wed Nov 1 12:22:18 2017 +0100
Committer: Carlos Sierra <cs...@apache.org>
Committed: Fri Nov 3 16:18:24 2017 +0100

----------------------------------------------------------------------
 .../internal/AriesJaxRSServiceRuntime.java      | 102 ++++++++++---------
 .../internal/CXFJaxRsServiceRegistrator.java    |   8 +-
 .../rs/whiteboard/internal/TargetFilter.java    |   5 +-
 .../aries/jax/rs/whiteboard/internal/Utils.java |  59 ++++++-----
 .../jax/rs/whiteboard/internal/Whiteboard.java  |  78 +++++++-------
 5 files changed, 133 insertions(+), 119 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/d825a6c4/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/AriesJaxRSServiceRuntime.java
----------------------------------------------------------------------
diff --git a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/AriesJaxRSServiceRuntime.java b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/AriesJaxRSServiceRuntime.java
index 12d8fb2..7d53b21 100644
--- a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/AriesJaxRSServiceRuntime.java
+++ b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/AriesJaxRSServiceRuntime.java
@@ -18,7 +18,7 @@
 package org.apache.aries.jax.rs.whiteboard.internal;
 
 import org.apache.aries.jax.rs.whiteboard.internal.Utils.PropertyHolder;
-import org.osgi.framework.ServiceReference;
+import org.apache.aries.osgi.functional.CachingServiceReference;
 import org.osgi.service.jaxrs.runtime.JaxRSServiceRuntime;
 import org.osgi.service.jaxrs.runtime.dto.ApplicationDTO;
 import org.osgi.service.jaxrs.runtime.dto.DTOConstants;
@@ -57,79 +57,81 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime {
         Whiteboard.class);
     private ConcurrentHashMap<String, Map<String, Object>>
         _applications = new ConcurrentHashMap<>();
-    private ConcurrentHashMap<String, Collection<ServiceReference<?>>>
+    private ConcurrentHashMap<String, Collection<CachingServiceReference<?>>>
         _applicationEndpoints = new ConcurrentHashMap<>();
-    private ConcurrentHashMap<String, Collection<ServiceReference<?>>>
+    private ConcurrentHashMap<String, Collection<CachingServiceReference<?>>>
         _applicationExtensions = new ConcurrentHashMap<>();
-    private Collection<ServiceReference<Application>>
+    private Collection<CachingServiceReference<Application>>
         _ungettableApplications = new CopyOnWriteArrayList<>();
-    private Collection<ServiceReference<Application>> _shadowedApplications =
+    private Collection<CachingServiceReference<Application>> _shadowedApplications =
         new CopyOnWriteArrayList<>();
-    private Set<ServiceReference<Application>> _dependentApplications =
+    private Set<CachingServiceReference<Application>> _dependentApplications =
         ConcurrentHashMap.newKeySet();
-    private Collection<ServiceReference<Application>> _clashingApplications =
+    private Collection<CachingServiceReference<Application>> _clashingApplications =
         new CopyOnWriteArrayList<>();
-    private Collection<ServiceReference<Application>> _erroredApplications =
+    private Collection<CachingServiceReference<Application>> _erroredApplications =
         new CopyOnWriteArrayList<>();
-    private Collection<ServiceReference<?>> _erroredEndpoints =
+    private Collection<CachingServiceReference<?>> _erroredEndpoints =
         new CopyOnWriteArrayList<>();
-    private Collection<ServiceReference<?>> _ungettableEndpoints =
+    private Collection<CachingServiceReference<?>> _ungettableEndpoints =
         new CopyOnWriteArrayList<>();
-    private Collection<ServiceReference<?>> _ungettableExtensions =
+    private Collection<CachingServiceReference<?>> _ungettableExtensions =
         new CopyOnWriteArrayList<>();
-    private Set<ServiceReference<?>> _dependentServices =
+    private Set<CachingServiceReference<?>> _dependentServices =
         ConcurrentHashMap.newKeySet();
-    private Collection<ServiceReference<?>> _invalidExtensions =
+    private Collection<CachingServiceReference<?>> _invalidExtensions =
         new CopyOnWriteArrayList<>();
     private volatile Map<String, Object> _defaultApplicationProperties;
 
     public void addApplicationEndpoint(
-        String applicationName, ServiceReference<?> endpointServiceReference) {
+        String applicationName, CachingServiceReference<?> endpointImmutableServiceReference) {
 
         _applicationEndpoints.compute(
-            applicationName, merger(endpointServiceReference));
+            applicationName, merger(endpointImmutableServiceReference));
     }
 
     public void addApplicationExtension(
         String applicationName,
-        ServiceReference<?> extensionServiceReference) {
+        CachingServiceReference<?> extensionImmutableServiceReference) {
 
         _applicationExtensions.compute(
-            applicationName, merger(extensionServiceReference));
+            applicationName, merger(extensionImmutableServiceReference));
     }
 
     public void addClashingApplication(
-        ServiceReference<Application> serviceReference) {
+        CachingServiceReference<Application> serviceReference) {
 
         _clashingApplications.add(serviceReference);
     }
 
     public void addDependentApplication(
-        ServiceReference<Application> applicationReference) {
+        CachingServiceReference<Application> applicationReference) {
 
         _dependentApplications.add(applicationReference);
     }
 
-    public void addDependentService(ServiceReference<?> serviceReference) {
+    public void addDependentService(CachingServiceReference<?> serviceReference) {
         _dependentServices.add(serviceReference);
     }
 
     public void addErroredApplication(
-        ServiceReference<Application> serviceReference) {
+        CachingServiceReference<Application> serviceReference) {
 
         _erroredApplications.add(serviceReference);
     }
 
-    public <T> void addErroredEndpoint(ServiceReference<T> serviceReference) {
+    public <T> void addErroredEndpoint(CachingServiceReference<T> serviceReference) {
         _erroredEndpoints.add(serviceReference);
     }
 
-    public void addInvalidExtension(ServiceReference<?> serviceReference) {
+    public void addInvalidExtension(
+        CachingServiceReference<?> serviceReference) {
+
         _invalidExtensions.add(serviceReference);
     }
 
     public boolean addNotGettableApplication(
-        ServiceReference<Application> serviceReference) {
+        CachingServiceReference<Application> serviceReference) {
 
         if (_LOGGER.isWarnEnabled()) {
             _LOGGER.warn(
@@ -141,7 +143,7 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime {
     }
 
     public <T> boolean addNotGettableEndpoint(
-        ServiceReference<T> serviceReference) {
+        CachingServiceReference<T> serviceReference) {
 
         if (_LOGGER.isWarnEnabled()) {
             _LOGGER.warn(
@@ -153,7 +155,7 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime {
     }
 
     public <T> void addNotGettableExtension(
-        ServiceReference<T> serviceReference) {
+        CachingServiceReference<T> serviceReference) {
 
         if (_LOGGER.isWarnEnabled()) {
             _LOGGER.warn(
@@ -165,7 +167,7 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime {
     }
 
     public boolean addShadowedApplication(
-        ServiceReference<Application> serviceReference) {
+        CachingServiceReference<Application> serviceReference) {
 
         return _shadowedApplications.add(serviceReference);
     }
@@ -235,69 +237,69 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime {
     }
 
     public void removeApplicationEndpoint(
-        String applicationName, ServiceReference<?> endpointServiceReference) {
+        String applicationName, CachingServiceReference<?> endpointImmutableServiceReference) {
 
         _applicationEndpoints.compute(
-            applicationName, remover(endpointServiceReference));
+            applicationName, remover(endpointImmutableServiceReference));
     }
 
     public void removeApplicationExtension(
-        String applicationName, ServiceReference<?> extensionServiceReference) {
+        String applicationName, CachingServiceReference<?> extensionImmutableServiceReference) {
 
         _applicationExtensions.computeIfPresent(
-            applicationName, remover(extensionServiceReference));
+            applicationName, remover(extensionImmutableServiceReference));
     }
 
     public void removeClashingApplication(
-        ServiceReference<Application> serviceReference) {
+        CachingServiceReference<Application> serviceReference) {
 
         _clashingApplications.remove(serviceReference);
     }
 
     public void removeDependentApplication(
-        ServiceReference<Application> applicationReference) {
+        CachingServiceReference<Application> applicationReference) {
 
         _dependentApplications.remove(applicationReference);
     }
 
-    public void removeDependentService(ServiceReference<?> serviceReference) {
+    public void removeDependentService(CachingServiceReference<?> serviceReference) {
         _dependentServices.remove(serviceReference);
     }
 
     public void removeErroredApplication(
-        ServiceReference<Application> serviceReference) {
+        CachingServiceReference<Application> serviceReference) {
 
         _erroredApplications.remove(serviceReference);
     }
 
-    public <T> void removeErroredEndpoint(ServiceReference<T> serviceReference) {
+    public <T> void removeErroredEndpoint(CachingServiceReference<T> serviceReference) {
         _erroredEndpoints.remove(serviceReference);
     }
 
-    public void removeInvalidExtension(ServiceReference<?> serviceReference) {
+    public void removeInvalidExtension(CachingServiceReference<?> serviceReference) {
         _invalidExtensions.remove(serviceReference);
     }
 
     public boolean removeNotGettableApplication(
-        ServiceReference<Application> serviceReference) {
+        CachingServiceReference<Application> serviceReference) {
 
         return _ungettableApplications.remove(serviceReference);
     }
 
     public <T> boolean removeNotGettableEndpoint(
-        ServiceReference<T> serviceReference) {
+        CachingServiceReference<T> serviceReference) {
 
         return _ungettableEndpoints.remove(serviceReference);
     }
 
     public <T> void removeNotGettableExtension(
-        ServiceReference<T> serviceReference) {
+        CachingServiceReference<T> serviceReference) {
 
         _ungettableExtensions.remove(serviceReference);
     }
 
     public boolean removeShadowedApplication(
-        ServiceReference<Application> serviceReference) {
+        CachingServiceReference<Application> serviceReference) {
 
         return _shadowedApplications.remove(serviceReference);
     }
@@ -351,7 +353,7 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime {
     }
 
     private FailedExtensionDTO buildFailedExtensionDTO(
-        int reason, ServiceReference<?> serviceReference) {
+        int reason, CachingServiceReference<?> serviceReference) {
 
         FailedExtensionDTO failedExtensionDTO = new FailedExtensionDTO();
 
@@ -363,7 +365,7 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime {
     }
 
     private FailedResourceDTO buildFailedResourceDTO(
-        int reason, ServiceReference<?> serviceReference) {
+        int reason, CachingServiceReference<?> serviceReference) {
 
         FailedResourceDTO failedResourceDTO = new FailedResourceDTO();
 
@@ -403,10 +405,10 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime {
     }
 
     private Stream<ResourceDTO> getApplicationEndpointsStream(String name) {
-        Collection<ServiceReference<?>> applicationEndpoints =
+        Collection<CachingServiceReference<?>> applicationEndpoints =
             _applicationEndpoints.get(name);
 
-        Stream<ServiceReference<?>> applicationEndpointStream =
+        Stream<CachingServiceReference<?>> applicationEndpointStream =
             applicationEndpoints != null ?
                 applicationEndpoints.stream() :
                 Stream.empty();
@@ -418,10 +420,10 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime {
     }
 
     private Stream<ExtensionDTO> getApplicationExtensionsStream(String name) {
-        Collection<ServiceReference<?>> applicationExtensions =
+        Collection<CachingServiceReference<?>> applicationExtensions =
             _applicationExtensions.get(name);
 
-        Stream<ServiceReference<?>> applicationExtensionStream =
+        Stream<CachingServiceReference<?>> applicationExtensionStream =
             applicationExtensions != null ?
                 applicationExtensions.stream() :
                 Stream.empty();
@@ -468,7 +470,7 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime {
     }
 
     private static FailedApplicationDTO buildFailedApplicationDTO(
-        int reason, ServiceReference<Application> serviceReference) {
+        int reason, CachingServiceReference<Application> serviceReference) {
 
         FailedApplicationDTO failedApplicationDTO = new FailedApplicationDTO();
 
@@ -501,7 +503,7 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime {
     }
 
     private static ExtensionDTO populateExtensionDTO(
-        ExtensionDTO extensionDTO, ServiceReference<?> serviceReference) {
+        ExtensionDTO extensionDTO, CachingServiceReference<?> serviceReference) {
 
         extensionDTO.name = serviceReference.getProperty(JAX_RS_NAME).
             toString();
@@ -519,7 +521,7 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime {
     }
 
     private static ResourceDTO populateResourceDTO(
-        ResourceDTO resourceDTO, ServiceReference<?> serviceReference) {
+        ResourceDTO resourceDTO, CachingServiceReference<?> serviceReference) {
 
         resourceDTO.name = getApplicationName(serviceReference::getProperty);
         resourceDTO.serviceId = (Long)serviceReference.getProperty(

http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/d825a6c4/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java
----------------------------------------------------------------------
diff --git a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java
index 41e482a..bac6758 100644
--- a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java
+++ b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java
@@ -37,7 +37,6 @@ import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
 import org.apache.cxf.jaxrs.model.ClassResourceInfo;
 import org.apache.cxf.jaxrs.model.OperationResourceInfo;
 import org.apache.cxf.jaxrs.provider.json.JSONProvider;
-import org.apache.cxf.jaxrs.utils.ResourceUtils;
 import org.apache.cxf.message.Message;
 import org.osgi.framework.ServiceReference;
 
@@ -48,7 +47,7 @@ public class CXFJaxRsServiceRegistrator {
     private final Application _application;
     private final Bus _bus;
     private final Collection<ServiceTuple<?>> _providers = new TreeSet<>(
-        Comparator.comparing(ServiceTuple::getServiceReference));
+        Comparator.comparing(ServiceTuple::getCachingServiceReference));
     private final Collection<ResourceProvider> _services = new ArrayList<>();
     private volatile boolean _closed = false;
     private Server _server;
@@ -129,7 +128,7 @@ public class CXFJaxRsServiceRegistrator {
 
         static {
             comparator = Comparator.comparing(
-                ServiceReferenceResourceProvider::getServiceReference);
+                srrp -> srrp.getImmutableServiceReference());
         }
 
         @Override
@@ -198,7 +197,8 @@ public class CXFJaxRsServiceRegistrator {
             jaxRsServerFactoryBean.setProvider(
                 (Feature) featureContext -> {
                     ServiceReference<?> serviceReference =
-                        provider.getServiceReference();
+                        provider.getCachingServiceReference().
+                            getServiceReference();
 
                     String[] interfaces = canonicalize(
                         serviceReference.getProperty("objectClass"));

http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/d825a6c4/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/TargetFilter.java
----------------------------------------------------------------------
diff --git a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/TargetFilter.java b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/TargetFilter.java
index 901f23a..1340989 100644
--- a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/TargetFilter.java
+++ b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/TargetFilter.java
@@ -4,6 +4,7 @@ import static org.osgi.service.jaxrs.whiteboard.JaxRSWhiteboardConstants.JAX_RS_
 
 import java.util.function.Predicate;
 
+import org.apache.aries.osgi.functional.CachingServiceReference;
 import org.osgi.framework.Filter;
 import org.osgi.framework.FrameworkUtil;
 import org.osgi.framework.InvalidSyntaxException;
@@ -11,14 +12,14 @@ import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class TargetFilter<T> implements Predicate<ServiceReference<T>>  {
+public class TargetFilter<T> implements Predicate<CachingServiceReference<T>>  {
 
     public TargetFilter(ServiceReference<?> serviceRuntimeReference) {
         _serviceRuntimeReference = serviceRuntimeReference;
     }
 
     @Override
-    public boolean test(ServiceReference<T> ref) {
+    public boolean test(CachingServiceReference<T> ref) {
         String target = (String)ref.getProperty(JAX_RS_WHITEBOARD_TARGET);
 
         if (target == null) {

http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/d825a6c4/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Utils.java
----------------------------------------------------------------------
diff --git a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Utils.java b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Utils.java
index ea1766b..a509720 100644
--- a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Utils.java
+++ b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Utils.java
@@ -18,6 +18,7 @@
 package org.apache.aries.jax.rs.whiteboard.internal;
 
 import org.apache.aries.osgi.functional.Event;
+import org.apache.aries.osgi.functional.CachingServiceReference;
 import org.apache.aries.osgi.functional.OSGi;
 import org.apache.aries.osgi.functional.SentEvent;
 import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
@@ -25,18 +26,15 @@ import org.apache.cxf.message.Message;
 import org.osgi.framework.ServiceObjects;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
-import org.slf4j.Logger;
 
 import java.util.Collection;
 import java.util.Comparator;
 import java.util.Dictionary;
 import java.util.HashMap;
 import java.util.Hashtable;
-import java.util.Iterator;
 import java.util.Map;
 import java.util.TreeSet;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Consumer;
 import java.util.function.Function;
@@ -77,7 +75,7 @@ public class Utils {
         return ".generated.for." + propertyHolder.get("service.id");
     }
 
-    public static Map<String, Object> getProperties(ServiceReference<?> sref) {
+    public static Map<String, Object> getProperties(CachingServiceReference<?> sref) {
         String[] propertyKeys = sref.getPropertyKeys();
         Map<String, Object> properties = new HashMap<>(propertyKeys.length);
 
@@ -91,8 +89,9 @@ public class Utils {
     public static <T> ResourceProvider getResourceProvider(
         ServiceObjects<T> serviceObjects) {
 
-        ServiceReference<T> serviceReference =
-            serviceObjects.getServiceReference();
+        CachingServiceReference<T> serviceReference =
+            new CachingServiceReference<>(
+                serviceObjects.getServiceReference());
 
         return new ServiceReferenceResourceProvider(
             serviceReference, serviceObjects);
@@ -108,35 +107,37 @@ public class Utils {
     }
 
     public static <T> OSGi<ServiceTuple<T>> onlyGettables(
-        OSGi<ServiceReference<T>> program,
-        Consumer<ServiceReference<T>> whenAddedNotGettable,
-        Consumer<ServiceReference<T>> whenLeavingNotGettable) {
+        OSGi<CachingServiceReference<T>> program,
+        Consumer<CachingServiceReference<T>> whenAddedNotGettable,
+        Consumer<CachingServiceReference<T>> whenLeavingNotGettable) {
 
         return bundleContext().flatMap(bundleContext ->
-            program.flatMap(serviceReference -> {
+            program.flatMap(immutable -> {
                 T service = null;
 
                 try {
-                    service = bundleContext.getService(serviceReference);
+                    service = bundleContext.getService(
+                        immutable.getServiceReference());
                 }
                 catch (Exception e){
                 }
                 if (service == null) {
-                    whenAddedNotGettable.accept(serviceReference);
+                    whenAddedNotGettable.accept(immutable);
 
                     return
                         onClose(
                             () -> whenLeavingNotGettable.accept(
-                                serviceReference)
+                                immutable)
                         ).then(
                             nothing()
                         );
                 }
                 return
                     onClose(
-                        () -> bundleContext.ungetService(serviceReference)
+                        () -> bundleContext.ungetService(
+                            immutable.getServiceReference())
                     ).then(
-                        just(new ServiceTuple<>(serviceReference, service))
+                        just(new ServiceTuple<>(immutable, service))
                     );
             }));
     }
@@ -147,7 +148,12 @@ public class Utils {
         return program.route(new HighestRankedRouter<>());
     }
 
-    public static <T> OSGi<T> service(ServiceReference<T> serviceReference) {
+    public static <T> OSGi<T> service(
+        CachingServiceReference<T> immutableServiceReference) {
+
+        ServiceReference<T> serviceReference =
+            immutableServiceReference.getServiceReference();
+
         return
             bundleContext().flatMap(bundleContext ->
             onClose(() -> bundleContext.ungetService(serviceReference)).then(
@@ -156,11 +162,12 @@ public class Utils {
     }
 
     public static <T> OSGi<ServiceObjects<T>> serviceObjects(
-        ServiceReference<T> serviceReference) {
+        CachingServiceReference<T> immutableServiceReference) {
 
         return
             bundleContext().flatMap(bundleContext ->
-            just(bundleContext.getServiceObjects(serviceReference))
+            just(bundleContext.getServiceObjects(
+                immutableServiceReference.getServiceReference()))
         );
     }
 
@@ -174,8 +181,8 @@ public class Utils {
     public static void updateProperty(
         ServiceRegistration<?> serviceRegistration, String key, Object value) {
 
-        ServiceReference<?> serviceReference =
-            serviceRegistration.getReference();
+        CachingServiceReference<?> serviceReference =
+            new CachingServiceReference<>(serviceRegistration.getReference());
 
         Dictionary<String, Object> properties = new Hashtable<>();
 
@@ -203,10 +210,10 @@ public class Utils {
         implements ResourceProvider {
 
         private final ServiceObjects<?> _serviceObjects;
-        private ServiceReference<?> _serviceReference;
+        private CachingServiceReference<?> _serviceReference;
 
         ServiceReferenceResourceProvider(
-            ServiceReference<?> serviceReference,
+            CachingServiceReference<?> serviceReference,
             ServiceObjects<?> serviceObjects) {
             _serviceReference = serviceReference;
 
@@ -242,7 +249,7 @@ public class Utils {
             return false;
         }
 
-        ServiceReference<?> getServiceReference() {
+        CachingServiceReference<?> getImmutableServiceReference() {
             return _serviceReference;
         }
 
@@ -250,10 +257,10 @@ public class Utils {
 
     public static class ServiceTuple<T> implements Comparable<ServiceTuple<T>> {
 
-        private final ServiceReference<T> _serviceReference;
+        private final CachingServiceReference<T> _serviceReference;
         private final T _service;
 
-        ServiceTuple(ServiceReference<T> a, T service) {
+        ServiceTuple(CachingServiceReference<T> a, T service) {
             _serviceReference = a;
             _service = service;
         }
@@ -282,7 +289,7 @@ public class Utils {
             return _serviceReference.equals(that._serviceReference);
         }
 
-        ServiceReference<T> getServiceReference() {
+        CachingServiceReference<T> getCachingServiceReference() {
             return _serviceReference;
         }
 

http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/d825a6c4/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Whiteboard.java
----------------------------------------------------------------------
diff --git a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Whiteboard.java b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Whiteboard.java
index 815dbac..c107941 100644
--- a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Whiteboard.java
+++ b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Whiteboard.java
@@ -20,6 +20,7 @@ package org.apache.aries.jax.rs.whiteboard.internal;
 import org.apache.aries.jax.rs.whiteboard.internal.Utils.ApplicationExtensionRegistration;
 import org.apache.aries.jax.rs.whiteboard.internal.Utils.PropertyHolder;
 import org.apache.aries.jax.rs.whiteboard.internal.Utils.ServiceTuple;
+import org.apache.aries.osgi.functional.CachingServiceReference;
 import org.apache.aries.osgi.functional.OSGi;
 import org.apache.aries.osgi.functional.OSGiResult;
 import org.apache.cxf.Bus;
@@ -125,13 +126,13 @@ public class Whiteboard {
     static final String DEFAULT_NAME = ".default";
     private static final Function<ServiceTuple<Application>, String>
         APPLICATION_BASE =
-        ((Function<ServiceTuple<Application>, ServiceReference<Application>>)
-            ServiceTuple::getServiceReference).andThen(
+        ((Function<ServiceTuple<Application>, CachingServiceReference<Application>>)
+            ServiceTuple::getCachingServiceReference).andThen(
                 sr -> getApplicationBase(sr::getProperty));
     private static final Function<ServiceTuple<Application>, String>
         APPLICATION_NAME =
-        ((Function<ServiceTuple<Application>, ServiceReference<Application>>)
-            ServiceTuple::getServiceReference).andThen(
+        ((Function<ServiceTuple<Application>, CachingServiceReference<Application>>)
+            ServiceTuple::getCachingServiceReference).andThen(
             sr -> getApplicationName(sr::getProperty));
 
     private final AriesJaxRSServiceRuntime _runtime;
@@ -240,21 +241,21 @@ public class Whiteboard {
 
         OSGi<ServiceTuple<Application>> highestRankedPerName = highestPer(
             APPLICATION_NAME, gettableAplicationForWhiteboard,
-            t -> _runtime.addClashingApplication(t.getServiceReference()),
-            t -> _runtime.removeClashingApplication(t.getServiceReference())
+            t -> _runtime.addClashingApplication(t.getCachingServiceReference()),
+            t -> _runtime.removeClashingApplication(t.getCachingServiceReference())
         );
 
         OSGi<ServiceTuple<Application>> highestRankedPerPath = highestPer(
             APPLICATION_BASE, highestRankedPerName,
-            t -> _runtime.addShadowedApplication(t.getServiceReference()),
-            t -> _runtime.removeShadowedApplication(t.getServiceReference())
+            t -> _runtime.addShadowedApplication(t.getCachingServiceReference()),
+            t -> _runtime.removeShadowedApplication(t.getCachingServiceReference())
         );
 
         return
             highestRankedPerPath.flatMap(
                 this::deployApplication
             ).map(
-                ServiceTuple::getServiceReference
+                ServiceTuple::getCachingServiceReference
             ).map(
                 Utils::getProperties
             ).foreach(
@@ -314,7 +315,7 @@ public class Whiteboard {
         return bus;
     }
 
-    private OSGi<ServiceReference<CXFJaxRsServiceRegistrator>>
+    private OSGi<CachingServiceReference<CXFJaxRsServiceRegistrator>>
         defaultApplication() {
 
         return
@@ -335,8 +336,8 @@ public class Whiteboard {
         return
             just(this::createBus).flatMap(bus ->
             just(() -> {
-                ServiceReference<Application> serviceReference =
-                    tuple.getServiceReference();
+                CachingServiceReference<Application> serviceReference =
+                    tuple.getCachingServiceReference();
 
                 Map<String, Object> properties = getProperties(
                     serviceReference);
@@ -371,8 +372,8 @@ public class Whiteboard {
                         );
                 }
                 catch (RuntimeException e) {
-                    ServiceReference<Application> serviceReference =
-                        tuple.getServiceReference();
+                    CachingServiceReference<Application> serviceReference =
+                        tuple.getCachingServiceReference();
 
                     _runtime.addErroredApplication(serviceReference);
 
@@ -386,14 +387,14 @@ public class Whiteboard {
             }));
     }
 
-    private OSGi<ServiceReference<Object>>
+    private OSGi<CachingServiceReference<Object>>
         getApplicationExtensionsForWhiteboard() {
 
         return serviceReferences(getApplicationExtensionsFilter()).
             filter(new TargetFilter<>(_runtimeReference));
     }
 
-    private OSGi<ServiceReference<Application>>
+    private OSGi<CachingServiceReference<Application>>
         getApplicationsForWhiteboard() {
 
         return
@@ -401,7 +402,7 @@ public class Whiteboard {
             filter(new TargetFilter<>(_runtimeReference));
     }
 
-    private OSGi<ServiceReference<Object>> getResourcesForWhiteboard() {
+    private OSGi<CachingServiceReference<Object>> getResourcesForWhiteboard() {
         return serviceReferences(getResourcesFilter()).
             filter(
                 new TargetFilter<>(_runtimeReference));
@@ -463,8 +464,8 @@ public class Whiteboard {
     }
 
     private <T> OSGi<?> safeRegisterEndpoint(
-        ServiceReference<T> serviceReference,
-        ServiceReference<CXFJaxRsServiceRegistrator> registratorReference) {
+        CachingServiceReference<T> serviceReference,
+        CachingServiceReference<CXFJaxRsServiceRegistrator> registratorReference) {
 
         String applicationName = getApplicationName(
             registratorReference::getProperty);
@@ -507,8 +508,8 @@ public class Whiteboard {
     }
 
     private OSGi<?> safeRegisterExtension(
-        ServiceReference<?> serviceReference,
-        ServiceReference<CXFJaxRsServiceRegistrator> registratorReference) {
+        CachingServiceReference<?> serviceReference,
+        CachingServiceReference<CXFJaxRsServiceRegistrator> registratorReference) {
 
         return
             just(() -> getApplicationName(registratorReference::getProperty)).
@@ -563,10 +564,10 @@ public class Whiteboard {
 
 
 
-    private OSGi<ServiceReference<Application>>
+    private OSGi<CachingServiceReference<Application>>
         waitForApplicationDependencies(
-            ServiceReference<Application> applicationReference,
-            OSGi<ServiceReference<Application>> program) {
+            CachingServiceReference<Application> applicationReference,
+            OSGi<CachingServiceReference<Application>> program) {
 
         String[] extensionDependencies = canonicalize(
             applicationReference.getProperty(JAX_RS_EXTENSION_SELECT));
@@ -608,7 +609,9 @@ public class Whiteboard {
                                 return nothing();
                             }
 
-                            if (filter.match(applicationReference)) {
+                            if (filter.match(
+                                applicationReference.getServiceReference())) {
+
                                 return just(applicationReference);
                             }
 
@@ -631,7 +634,7 @@ public class Whiteboard {
     }
 
     private OSGi<?> waitForExtensionDependencies(
-        ServiceReference<?> serviceReference, String applicationName,
+        CachingServiceReference<?> serviceReference, String applicationName,
         OSGi<?> program) {
 
         String[] extensionDependencies = canonicalize(
@@ -657,8 +660,9 @@ public class Whiteboard {
                         filter(
                             sr -> getApplicationName(sr::getProperty).equals(
                                 applicationName)
-                        ).
-                        filter(
+                        ).map(
+                            CachingServiceReference::getServiceReference
+                        ).filter(
                             extensionFilter::match
                         )).effects(
                             __ -> {},
@@ -687,16 +691,16 @@ public class Whiteboard {
         return properties.get(JAX_RS_APPLICATION_BASE).toString();
     }
 
-    private static OSGi<ServiceReference<CXFJaxRsServiceRegistrator>>
+    private static OSGi<CachingServiceReference<CXFJaxRsServiceRegistrator>>
         allApplicationReferences() {
 
         return serviceReferences(CXFJaxRsServiceRegistrator.class);
     }
 
-    private static OSGi<ServiceReference<CXFJaxRsServiceRegistrator>>
+    private static OSGi<CachingServiceReference<CXFJaxRsServiceRegistrator>>
         chooseApplication(
-            ServiceReference<?> serviceReference,
-            Supplier<OSGi<ServiceReference<CXFJaxRsServiceRegistrator>>>
+            CachingServiceReference<?> serviceReference,
+            Supplier<OSGi<CachingServiceReference<CXFJaxRsServiceRegistrator>>>
                 theDefault) {
 
         Object applicationSelectProperty = serviceReference.getProperty(
@@ -747,10 +751,10 @@ public class Whiteboard {
         return format("(%s=true)", JAX_RS_RESOURCE);
     }
 
-    private static OSGi<ServiceReference<Object>> onlySupportedInterfaces(
-        OSGi<ServiceReference<Object>> program,
-        Consumer<ServiceReference<?>> onInvalidAdded,
-        Consumer<ServiceReference<?>> onInvalidRemoved) {
+    private static OSGi<CachingServiceReference<Object>> onlySupportedInterfaces(
+        OSGi<CachingServiceReference<Object>> program,
+        Consumer<CachingServiceReference<?>> onInvalidAdded,
+        Consumer<CachingServiceReference<?>> onInvalidRemoved) {
 
         return program.flatMap(sr -> {
             if (signalsValidInterface(sr)) {
@@ -806,7 +810,7 @@ public class Whiteboard {
     }
 
     private static boolean signalsValidInterface(
-        ServiceReference<Object> serviceReference) {
+        CachingServiceReference<Object> serviceReference) {
 
         String[] objectClasses = canonicalize(serviceReference.getProperty(
             "objectClass"));


[06/11] aries-jax-rs-whiteboard git commit: Handle error endpoint registration

Posted by cs...@apache.org.
Handle error endpoint registration


Project: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/repo
Commit: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/commit/388fbfdb
Tree: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/tree/388fbfdb
Diff: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/diff/388fbfdb

Branch: refs/heads/master
Commit: 388fbfdb466d6cb28d97ef5a914cd618019f4f8c
Parents: 7126342
Author: Carlos Sierra <cs...@apache.org>
Authored: Mon Oct 30 08:32:01 2017 +0100
Committer: Carlos Sierra <cs...@apache.org>
Committed: Fri Nov 3 16:18:24 2017 +0100

----------------------------------------------------------------------
 .../internal/AriesJaxRSServiceRuntime.java      | 22 +++++++++++-
 .../jax/rs/whiteboard/internal/Whiteboard.java  | 38 +++++++++++++-------
 2 files changed, 46 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/388fbfdb/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/AriesJaxRSServiceRuntime.java
----------------------------------------------------------------------
diff --git a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/AriesJaxRSServiceRuntime.java b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/AriesJaxRSServiceRuntime.java
index 1e72f6b..12d8fb2 100644
--- a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/AriesJaxRSServiceRuntime.java
+++ b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/AriesJaxRSServiceRuntime.java
@@ -71,6 +71,8 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime {
         new CopyOnWriteArrayList<>();
     private Collection<ServiceReference<Application>> _erroredApplications =
         new CopyOnWriteArrayList<>();
+    private Collection<ServiceReference<?>> _erroredEndpoints =
+        new CopyOnWriteArrayList<>();
     private Collection<ServiceReference<?>> _ungettableEndpoints =
         new CopyOnWriteArrayList<>();
     private Collection<ServiceReference<?>> _ungettableExtensions =
@@ -118,6 +120,10 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime {
         _erroredApplications.add(serviceReference);
     }
 
+    public <T> void addErroredEndpoint(ServiceReference<T> serviceReference) {
+        _erroredEndpoints.add(serviceReference);
+    }
+
     public void addInvalidExtension(ServiceReference<?> serviceReference) {
         _invalidExtensions.add(serviceReference);
     }
@@ -203,7 +209,10 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime {
 
         runtimeDTO.failedResourceDTOs =
             Stream.concat(
-                unreferenciableEndpointsDTOStream(), dependentServiceStreamDTO()
+                unreferenciableEndpointsDTOStream(),
+                Stream.concat(
+                    dependentServiceStreamDTO(),
+                    erroredEndpointsStreamDTO())
             ).toArray(
                 FailedResourceDTO[]::new
             );
@@ -218,6 +227,13 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime {
         return runtimeDTO;
     }
 
+    private Stream<FailedResourceDTO> erroredEndpointsStreamDTO() {
+        return _erroredEndpoints.stream().map(
+            sr -> buildFailedResourceDTO(
+                DTOConstants.FAILURE_REASON_UNKNOWN, sr)
+        );
+    }
+
     public void removeApplicationEndpoint(
         String applicationName, ServiceReference<?> endpointServiceReference) {
 
@@ -254,6 +270,10 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime {
         _erroredApplications.remove(serviceReference);
     }
 
+    public <T> void removeErroredEndpoint(ServiceReference<T> serviceReference) {
+        _erroredEndpoints.remove(serviceReference);
+    }
+
     public void removeInvalidExtension(ServiceReference<?> serviceReference) {
         _invalidExtensions.remove(serviceReference);
     }

http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/388fbfdb/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Whiteboard.java
----------------------------------------------------------------------
diff --git a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Whiteboard.java b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Whiteboard.java
index 4324ada..0277965 100644
--- a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Whiteboard.java
+++ b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Whiteboard.java
@@ -476,20 +476,32 @@ public class Whiteboard {
                 _runtime::removeNotGettableEndpoint
             ).flatMap(
                 tuple -> serviceObjects(serviceReference).flatMap(
-                    serviceObjects -> registerEndpoint(
-                        registrator, serviceObjects).flatMap(
-                            resourceProvider ->
-                                onClose(
-                                    () -> Utils.unregisterEndpoint(
-                                        registrator, resourceProvider)
-                                )
-                    )
+                    serviceObjects -> {
+                        try {
+                            return registerEndpoint(
+                                registrator, serviceObjects).flatMap(
+                                resourceProvider ->
+                                    onClose(
+                                        () -> Utils.unregisterEndpoint(
+                                            registrator, resourceProvider)
+                                    ).effects(
+                                        __ -> _runtime.addApplicationEndpoint(
+                                            applicationName, serviceReference),
+                                        __ -> _runtime.removeApplicationEndpoint(
+                                            applicationName, serviceReference)
+                                    ));
+                        }
+                        catch (Exception e) {
+                            return
+                                just(serviceReference).
+                                effects(
+                                    _runtime::addErroredEndpoint,
+                                    _runtime::removeErroredEndpoint).
+                                then(nothing());
+                        }
+                    }
+
                 )
-            ).effects(
-                __ -> _runtime.addApplicationEndpoint(
-                    applicationName, serviceReference),
-                __ -> _runtime.removeApplicationEndpoint(
-                    applicationName, serviceReference)
             ));
     }
 


[08/11] aries-jax-rs-whiteboard git commit: Improve dependency checking

Posted by cs...@apache.org.
Improve dependency checking

It only uses the first one of each dependency as a trigger for
starting and the last one of each dependency as a trigger for
closing.


Project: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/repo
Commit: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/commit/8fd8f7f8
Tree: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/tree/8fd8f7f8
Diff: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/diff/8fd8f7f8

Branch: refs/heads/master
Commit: 8fd8f7f8bf832db35272df301bd1a534f75b5275
Parents: 388fbfd
Author: Carlos Sierra <cs...@apache.org>
Authored: Mon Oct 30 08:33:25 2017 +0100
Committer: Carlos Sierra <cs...@apache.org>
Committed: Fri Nov 3 16:18:24 2017 +0100

----------------------------------------------------------------------
 .../jax/rs/whiteboard/internal/Whiteboard.java  | 21 ++++++++------------
 1 file changed, 8 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/8fd8f7f8/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Whiteboard.java
----------------------------------------------------------------------
diff --git a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Whiteboard.java b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Whiteboard.java
index 0277965..b7c412b 100644
--- a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Whiteboard.java
+++ b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Whiteboard.java
@@ -84,6 +84,7 @@ import static org.apache.aries.osgi.functional.OSGi.join;
 import static org.apache.aries.osgi.functional.OSGi.just;
 import static org.apache.aries.osgi.functional.OSGi.nothing;
 import static org.apache.aries.osgi.functional.OSGi.onClose;
+import static org.apache.aries.osgi.functional.OSGi.once;
 import static org.apache.aries.osgi.functional.OSGi.register;
 import static org.apache.aries.osgi.functional.OSGi.serviceReferences;
 import static org.osgi.service.http.runtime.HttpServiceRuntimeConstants.HTTP_SERVICE_ENDPOINT;
@@ -552,12 +553,10 @@ public class Whiteboard {
             applicationReference.getProperty(JAX_RS_EXTENSION_SELECT));
 
         if (extensionDependencies.length > 0) {
-            program = onClose(
-                () -> _runtime.removeDependentApplication(
-                    applicationReference)).
-                then(program);
-
-            _runtime.addDependentApplication(applicationReference);
+            program = just(0).effects(
+                __ -> _runtime.addDependentApplication(applicationReference),
+                __ -> _runtime.removeDependentApplication(applicationReference)
+            ).then(program);
         }
         else {
             return program;
@@ -570,7 +569,7 @@ public class Whiteboard {
                 extensionDependency);
 
             program =
-                serviceReferences(extensionDependency).
+                once(serviceReferences(extensionDependency)).
                     flatMap(
                         sr -> {
                             Object applicationSelectProperty =
@@ -604,10 +603,6 @@ public class Whiteboard {
                     then(program);
         }
 
-        program = onClose(
-            ()-> _runtime.removeDependentApplication(applicationReference)).
-            then(program);
-
         program = program.effects(
             __ -> _runtime.removeDependentApplication(applicationReference),
             __ -> {}
@@ -639,14 +634,14 @@ public class Whiteboard {
                     extensionDependency);
 
                 program =
-                    serviceReferences(ApplicationExtensionRegistration.class).
+                    once(serviceReferences(ApplicationExtensionRegistration.class).
                         filter(
                             sr -> getApplicationName(sr::getProperty).equals(
                                 applicationName)
                         ).
                         filter(
                             extensionFilter::match
-                        ).effects(
+                        )).effects(
                             __ -> {},
                             __ -> _runtime.addDependentService(serviceReference)
                         ).


[09/11] aries-jax-rs-whiteboard git commit: Test application rebase

Posted by cs...@apache.org.
Test application rebase


Project: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/repo
Commit: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/commit/bd57dd77
Tree: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/tree/bd57dd77
Diff: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/diff/bd57dd77

Branch: refs/heads/master
Commit: bd57dd774c6ea55ed17fa402b27a73369fe7aece
Parents: 1b95426
Author: Carlos Sierra <cs...@apache.org>
Authored: Mon Oct 30 14:53:44 2017 +0100
Committer: Carlos Sierra <cs...@apache.org>
Committed: Fri Nov 3 16:18:24 2017 +0100

----------------------------------------------------------------------
 jax-rs.itests/src/main/java/test/JaxrsTest.java | 38 ++++++++++++++++++++
 1 file changed, 38 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/bd57dd77/jax-rs.itests/src/main/java/test/JaxrsTest.java
----------------------------------------------------------------------
diff --git a/jax-rs.itests/src/main/java/test/JaxrsTest.java b/jax-rs.itests/src/main/java/test/JaxrsTest.java
index 65c34f8..59f6b1c 100644
--- a/jax-rs.itests/src/main/java/test/JaxrsTest.java
+++ b/jax-rs.itests/src/main/java/test/JaxrsTest.java
@@ -364,6 +364,44 @@ public class JaxrsTest extends TestHelper {
     }
 
     @Test
+    public void testApplicationRebase() {
+        assertEquals(0, getRuntimeDTO().applicationDTOs.length);
+
+        ServiceRegistration<Application> serviceRegistration =
+            registerApplication(new TestApplication());
+
+        assertEquals(1, getRuntimeDTO().applicationDTOs.length);
+
+        WebTarget webTarget = createDefaultTarget().path("/test-application");
+
+        Response response = webTarget.request().get();
+
+        assertEquals("Hello application", response.readEntity(String.class));
+
+        serviceRegistration.setProperties(
+            new Hashtable<String, Object>() {{
+                put(JAX_RS_APPLICATION_BASE, "/test-application-rebased");
+            }});
+
+        webTarget = createDefaultTarget().path("/test-application-rebased");
+
+        response = webTarget.request().get();
+
+        assertEquals("Hello application", response.readEntity(String.class));
+
+        serviceRegistration.setProperties(
+            new Hashtable<String, Object>() {{
+                put(JAX_RS_APPLICATION_BASE, "/test-application-rebased-again");
+            }});
+
+        webTarget = createDefaultTarget().path("/test-application-rebased-again");
+
+        response = webTarget.request().get();
+
+        assertEquals("Hello application", response.readEntity(String.class));
+    }
+
+    @Test
     public void testApplicationReplaceDefault() {
         assertEquals(0, getRuntimeDTO().applicationDTOs.length);
         assertEquals(0, getRuntimeDTO().failedApplicationDTOs.length);


[03/11] aries-jax-rs-whiteboard git commit: Use portable registration API

Posted by cs...@apache.org.
Use portable registration API


Project: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/repo
Commit: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/commit/d20ca62f
Tree: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/tree/d20ca62f
Diff: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/diff/d20ca62f

Branch: refs/heads/master
Commit: d20ca62fd253d6aaf4d9fd5008496283f95a53a2
Parents: d825a6c
Author: Carlos Sierra <cs...@apache.org>
Authored: Wed Nov 1 12:22:37 2017 +0100
Committer: Carlos Sierra <cs...@apache.org>
Committed: Fri Nov 3 16:18:24 2017 +0100

----------------------------------------------------------------------
 .../jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/d20ca62f/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java
----------------------------------------------------------------------
diff --git a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java
index bac6758..70b4bf1 100644
--- a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java
+++ b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java
@@ -26,6 +26,7 @@ import java.util.stream.Stream;
 
 import javax.ws.rs.core.Application;
 import javax.ws.rs.core.Feature;
+import javax.ws.rs.ext.RuntimeDelegate;
 
 import org.apache.aries.jax.rs.whiteboard.internal.Utils.ServiceReferenceResourceProvider;
 import org.apache.aries.jax.rs.whiteboard.internal.Utils.ServiceTuple;
@@ -92,7 +93,10 @@ public class CXFJaxRsServiceRegistrator {
     }
 
     public <T> T createEndpoint(Application app, Class<T> endpointType) {
-        JAXRSServerFactoryBean bean = ResourceUtils.createApplication(app, false);
+        JAXRSServerFactoryBean bean =
+            RuntimeDelegate.getInstance().createEndpoint(
+                app, JAXRSServerFactoryBean.class);
+
         if (JAXRSServerFactoryBean.class.isAssignableFrom(endpointType)) {
             return endpointType.cast(bean);
         }


[07/11] aries-jax-rs-whiteboard git commit: Add ignored test for Feature registration

Posted by cs...@apache.org.
Add ignored test for Feature registration

This test fails due to an alleged CXF bug


Project: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/repo
Commit: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/commit/1b954268
Tree: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/tree/1b954268
Diff: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/diff/1b954268

Branch: refs/heads/master
Commit: 1b9542685392ed55312f82d5dea13b94fb9990df
Parents: e7fde03
Author: Carlos Sierra <cs...@apache.org>
Authored: Mon Oct 30 14:52:55 2017 +0100
Committer: Carlos Sierra <cs...@apache.org>
Committed: Fri Nov 3 16:18:24 2017 +0100

----------------------------------------------------------------------
 jax-rs.itests/src/main/java/test/JaxrsTest.java | 49 ++++++++++++++++++++
 1 file changed, 49 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/1b954268/jax-rs.itests/src/main/java/test/JaxrsTest.java
----------------------------------------------------------------------
diff --git a/jax-rs.itests/src/main/java/test/JaxrsTest.java b/jax-rs.itests/src/main/java/test/JaxrsTest.java
index a85e5e6..65c34f8 100644
--- a/jax-rs.itests/src/main/java/test/JaxrsTest.java
+++ b/jax-rs.itests/src/main/java/test/JaxrsTest.java
@@ -33,6 +33,7 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.junit.After;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.PrototypeServiceFactory;
@@ -59,6 +60,8 @@ import javax.ws.rs.client.InvocationCallback;
 import javax.ws.rs.client.WebTarget;
 import javax.ws.rs.container.ContainerResponseFilter;
 import javax.ws.rs.core.Application;
+import javax.ws.rs.core.Feature;
+import javax.ws.rs.core.FeatureContext;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.ext.ExceptionMapper;
 
@@ -741,6 +744,31 @@ public class JaxrsTest extends TestHelper {
         filterRegistration.unregister();
     }
 
+    @Ignore
+    @Test
+    public void testFeatureExtension() {
+        WebTarget webTarget = createDefaultTarget().path("/test-application");
+
+        registerApplication(new TestApplication());
+
+        registerExtension(
+            Feature.class,
+            context -> {
+                context.register(new TestAddonConflict2());
+
+                return true;
+            },
+            "Feature",
+            JAX_RS_APPLICATION_SELECT,
+            "(" + JAX_RS_APPLICATION_BASE + "=/test-application)");
+
+        Response response = webTarget.request().get();
+
+        assertEquals("Hello application", response.readEntity(String.class));
+
+        assertEquals("true", response.getHeaders().getFirst("Filtered"));
+    }
+
     @Test
     public void testGettableAndNotGettableApplication()
         throws InterruptedException {
@@ -1367,6 +1395,27 @@ public class JaxrsTest extends TestHelper {
         return serviceRegistration;
     }
 
+    private <T> ServiceRegistration<T> registerExtension(
+        Class<T> clazz, T extension, String name, Object... keyValues) {
+
+        Dictionary<String, Object> properties = new Hashtable<>();
+
+        properties.put(JAX_RS_EXTENSION, true);
+        properties.put(JAX_RS_NAME, name);
+
+        for (int i = 0; i < keyValues.length; i = i + 2) {
+            properties.put(keyValues[i].toString(), keyValues[i + 1]);
+        }
+
+        ServiceRegistration<T> serviceRegistration =
+            bundleContext.registerService(clazz, extension, properties);
+
+        _registrations.add(serviceRegistration);
+
+        return serviceRegistration;
+    }
+
+
     private ServiceRegistration<?> registerInvalidExtension(
         String name, Object... keyValues) {