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/06/19 15:34:13 UTC

[09/11] aries-jax-rs-whiteboard git commit: Support application overriding and conflict resolution

Support application overriding and conflict resolution

Conflicting application must be signaled using
FailedApplicationDTO. Applications must be registered in order so
application with higher ranking will win.

When an application is shaded none of its methods should be available.

This commit includes a _hack_ to workaround a CXF hack filed under
https://issues.apache.org/jira/browse/CXF-7409


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/66e10da1
Tree: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/tree/66e10da1
Diff: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/diff/66e10da1

Branch: refs/heads/master
Commit: 66e10da1fc391b70685d733d7afa077b681e9d7a
Parents: 79cbaae
Author: Carlos Sierra <cs...@apache.org>
Authored: Thu Jun 15 17:15:59 2017 +0200
Committer: Carlos Sierra <cs...@apache.org>
Committed: Mon Jun 19 17:31:56 2017 +0200

----------------------------------------------------------------------
 .../activator/CXFJaxRsBundleActivator.java      |  5 +-
 .../internal/CXFJaxRsServiceRegistrator.java    | 64 +++++++++++++-
 .../aries/jax/rs/whiteboard/internal/Utils.java | 89 +++++++++++++++++---
 3 files changed, 140 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/66e10da1/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/activator/CXFJaxRsBundleActivator.java
----------------------------------------------------------------------
diff --git a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/activator/CXFJaxRsBundleActivator.java b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/activator/CXFJaxRsBundleActivator.java
index 0f05902..3546496 100644
--- a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/activator/CXFJaxRsBundleActivator.java
+++ b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/activator/CXFJaxRsBundleActivator.java
@@ -71,8 +71,9 @@ public class CXFJaxRsBundleActivator implements BundleActivator {
         registerCXFServletService(_bus);
 
         OSGi<?> applications =
-            serviceReferences(Application.class, getApplicationFilter()).
-                flatMap(ref ->
+            repeatInOrder(
+                serviceReferences(Application.class, getApplicationFilter())).
+            flatMap(ref ->
             just(
                 CXFJaxRsServiceRegistrator.getProperties(
                     ref, JAX_RS_APPLICATION_BASE)).

http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/66e10da1/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 886847f..726ecf8 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
@@ -17,11 +17,14 @@
 
 package org.apache.aries.jax.rs.whiteboard.internal;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Comparator;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.TreeSet;
 
 import javax.ws.rs.core.Application;
@@ -29,9 +32,15 @@ import javax.ws.rs.ext.RuntimeDelegate;
 
 import org.apache.cxf.Bus;
 import org.apache.cxf.endpoint.Server;
+import org.apache.cxf.endpoint.ServerImpl;
 import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
 import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
 import org.apache.cxf.jaxrs.provider.json.JSONProvider;
+import org.apache.cxf.service.factory.ServiceConstructionException;
+import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.transport.Destination;
+import org.apache.cxf.transport.DestinationFactory;
+import org.apache.cxf.transport.DestinationFactoryManager;
 import org.osgi.framework.ServiceReference;
 
 import static org.apache.aries.jax.rs.whiteboard.internal.Utils.safeToString;
@@ -149,6 +158,16 @@ public class CXFJaxRsServiceRegistrator {
         jaxRsServerFactoryBean.setBus(_bus);
         jaxRsServerFactoryBean.setProperties(_properties);
 
+        String address = safeToString(_properties.get(CXF_ENDPOINT_ADDRESS));
+
+        DestinationFactoryManager dfm = _bus.getExtension(
+            DestinationFactoryManager.class);
+        DestinationFactory destinationFactory = dfm.getDestinationFactoryForUri(
+            address);
+
+        jaxRsServerFactoryBean.setDestinationFactory(
+            new CXF7409DestinationFactory(destinationFactory));
+
         JSONProvider<Object> jsonProvider = new JSONProvider<>();
 
         jsonProvider.setDropCollectionWrapperElement(true);
@@ -167,8 +186,6 @@ public class CXFJaxRsServiceRegistrator {
                 resourceInformation.getResourceProvider());
         }
 
-        String address = safeToString(_properties.get(CXF_ENDPOINT_ADDRESS));
-
         jaxRsServerFactoryBean.setAddress(address);
 
         _server = jaxRsServerFactoryBean.create();
@@ -205,4 +222,47 @@ public class CXFJaxRsServiceRegistrator {
 
     }
 
+    /**
+     * This class exists as a workaround for
+     * https://issues.apache.org/jira/browse/CXF-7409
+     */
+    private static class CXF7409DestinationFactory
+        implements DestinationFactory {
+
+        private final DestinationFactory _destinationFactory;
+
+        public CXF7409DestinationFactory(
+            DestinationFactory destinationFactory) {
+
+            _destinationFactory = destinationFactory;
+        }
+
+        @Override
+        public Destination getDestination(
+            EndpointInfo endpointInfo, Bus bus) throws IOException {
+
+            Destination destination = _destinationFactory.getDestination(
+                endpointInfo, bus);
+
+            if (destination.getMessageObserver() != null) {
+                throw new RuntimeException(
+                    "There is already an application running at " +
+                        endpointInfo.getAddress());
+            }
+
+            return destination;
+        }
+
+        @Override
+        public Set<String> getUriPrefixes() {
+            return _destinationFactory.getUriPrefixes();
+        }
+
+        @Override
+        public List<String> getTransportIds() {
+            return _destinationFactory.getTransportIds();
+        }
+
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/66e10da1/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 4a7aa0c..6e52d81 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.jax.rs.whiteboard.internal.CXFJaxRsServiceRegistrator.ResourceInformation;
+import org.apache.aries.osgi.functional.Event;
 import org.apache.aries.osgi.functional.OSGi;
 import org.apache.cxf.Bus;
 import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
@@ -27,10 +28,15 @@ import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceObjects;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.service.jaxrs.runtime.dto.FailedApplicationDTO;
 
 import javax.ws.rs.core.Application;
 import javax.ws.rs.ext.Provider;
+import java.util.Comparator;
 import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.function.Consumer;
 
 import static org.apache.aries.osgi.functional.OSGi.bundleContext;
 import static org.apache.aries.osgi.functional.OSGi.just;
@@ -59,18 +65,23 @@ public class Utils {
         );
     }
 
-    public static OSGi<CXFJaxRsServiceRegistrator> cxfRegistrator(
+    public static OSGi<?> cxfRegistrator(
         Bus bus, Application application, Map<String, Object> props) {
 
-        CXFJaxRsServiceRegistrator registrator =
-            new CXFJaxRsServiceRegistrator(bus, application, props);
+        try {
+            CXFJaxRsServiceRegistrator registrator =
+                new CXFJaxRsServiceRegistrator(bus, application, props);
 
-        return
-            onClose(registrator::close).then(
-            register(CXFJaxRsServiceRegistrator.class, registrator, props).then(
-            just(registrator)
-        ));
-    }
+            return
+                onClose(registrator::close).then(
+                register(CXFJaxRsServiceRegistrator.class, registrator, props)
+            );
+        }
+        catch (Exception e) {
+            return register(
+                FailedApplicationDTO.class, new FailedApplicationDTO(), props);
+        }
+    };
 
     public static OSGi<?> safeRegisterGeneric(
         ServiceReference<?> serviceReference,
@@ -113,10 +124,17 @@ public class Utils {
                 unregisterEndpoint(registrator, serviceInformation)))));
     }
 
-    public static <T> OSGi<ResourceInformation> registerEndpoint(
-        ServiceReference<?> serviceReference,
-        CXFJaxRsServiceRegistrator registrator,
-        ServiceObjects<T> serviceObjects) {
+    public static <T extends Comparable<? super T>> OSGi<T> repeatInOrder(
+        OSGi<T> program) {
+
+        return program.route(new RepeatInOrderRouter<>());
+    }
+
+    public static <T> OSGi<ResourceInformation<ServiceReference<?>>>
+        registerEndpoint(
+            ServiceReference<?> serviceReference,
+            CXFJaxRsServiceRegistrator registrator,
+            ServiceObjects<T> serviceObjects) {
 
         Thread thread = Thread.currentThread();
         ClassLoader contextClassLoader = thread.getContextClassLoader();
@@ -176,9 +194,52 @@ public class Utils {
 
     public static void unregisterEndpoint(
         CXFJaxRsServiceRegistrator registrator,
-        ResourceInformation resourceInformation) {
+        ResourceInformation<ServiceReference<?>> resourceInformation) {
 
         registrator.remove(resourceInformation);
     }
 
+    private static class RepeatInOrderRouter<T extends Comparable<? super T>>
+        implements Consumer<OSGi.Router<T>> {
+
+        private final TreeSet<Event<T>> _treeSet;
+
+        public RepeatInOrderRouter() {
+            Comparator<Event<T>> comparing = Comparator.comparing(
+                Event::getContent);
+
+            _treeSet = new TreeSet<>(comparing.reversed());
+        }
+
+        @Override
+        public void accept(OSGi.Router<T> router) {
+            router.onIncoming(ev -> {
+                _treeSet.add(ev);
+
+                SortedSet<Event<T>> events = _treeSet.tailSet(ev, false);
+                events.forEach(router::signalLeave);
+
+                router.signalAdd(ev);
+
+                events.forEach(router::signalAdd);
+            });
+            router.onLeaving(ev -> {
+                _treeSet.remove(ev);
+
+                SortedSet<Event<T>> events = _treeSet.tailSet(ev, false);
+                events.forEach(router::signalLeave);
+
+                router.signalLeave(ev);
+
+                events.forEach(router::signalAdd);
+            });
+            router.onClose(() -> {
+                _treeSet.forEach(router::signalLeave);
+
+                _treeSet.clear();
+            });
+        }
+
+    }
+
 }