Repository: aries-jax-rs-whiteboard Updated Branches: refs/heads/master f37e0dd82 -> 31bf73834
Factor clashing detection logic out 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/31bf7383 Tree: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/tree/31bf7383 Diff: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/diff/31bf7383 Branch: refs/heads/master Commit: 31bf73834766999fe0315aa62d340b64ea35b7e7 Parents: ffc1175 Author: Carlos Sierra <[email protected]> Authored: Fri Aug 18 14:35:14 2017 +0200 Committer: Carlos Sierra <[email protected]> Committed: Fri Aug 18 15:59:21 2017 +0200 ---------------------------------------------------------------------- .../internal/AriesJaxRSServiceRuntime.java | 153 +++---------------- .../aries/jax/rs/whiteboard/internal/Utils.java | 114 +++++++++++++- .../jax/rs/whiteboard/internal/Whiteboard.java | 69 ++++++--- 3 files changed, 183 insertions(+), 153 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/31bf7383/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 11e9772..67166b0 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 @@ -17,8 +17,6 @@ package org.apache.aries.jax.rs.whiteboard.internal; -import org.apache.aries.osgi.functional.Event; -import org.apache.aries.osgi.functional.OSGi; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.osgi.service.jaxrs.runtime.JaxRSServiceRuntime; @@ -31,33 +29,27 @@ import org.osgi.service.jaxrs.whiteboard.JaxRSWhiteboardConstants; import javax.ws.rs.core.Application; import java.util.Comparator; -import java.util.Objects; +import java.util.Set; import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Stream; -import static org.osgi.service.jaxrs.whiteboard.JaxRSWhiteboardConstants.JAX_RS_APPLICATION_BASE; import static org.osgi.service.jaxrs.whiteboard.JaxRSWhiteboardConstants.JAX_RS_NAME; public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime { private static final long serialVersionUID = 1L; - private ConcurrentHashMap<String, TreeSet<Event<MutableTuple<Application>>>> + private ConcurrentHashMap<String, ServiceReference<Application>> _applications = new ConcurrentHashMap<>(); private TreeSet<ServiceReference<Application>> _ungettableApplications; - private Comparator<Event<MutableTuple<Application>>> - _applicationComparator; + private Set<ServiceReference<Application>> _shadowedApplications = + new TreeSet<>(); public AriesJaxRSServiceRuntime(BundleContext bundleContext) { - _applicationComparator = Comparator.comparing( - Event::getContent); - - _applicationComparator = _applicationComparator.reversed(); - _ungettableApplications = new TreeSet<>(Comparator.reverseOrder()); } @@ -73,69 +65,26 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime { return _ungettableApplications.remove(serviceReference); } - public OSGi<MutableTuple<Application>> processApplications( - OSGi<MutableTuple<Application>> source) { - - return - source.route( - router -> { - router.onIncoming(event -> { - MutableTuple<Application> - tuple = event.getContent(); - - ServiceReference<Application> serviceReference = - tuple.getServiceReference(); - - String path = serviceReference.getProperty(JAX_RS_APPLICATION_BASE). - toString(); - - TreeSet<Event<MutableTuple<Application>>> applicationReferences = - _applications.computeIfAbsent( - path, __ -> new TreeSet<>(_applicationComparator)); - - Event<MutableTuple<Application>> first = - applicationReferences.size() > 0 ? applicationReferences.first() : null; - - if (first == null || _applicationComparator.compare(event, first) < 0) { - if (first != null) { - router.signalLeave(first); - } - - router.signalAdd(event); - } - - applicationReferences.add(event); - }); - router.onLeaving(event -> { - MutableTuple<Application> tuple = event.getContent(); + public ServiceReference<Application> setApplicationForPath( + String path, ServiceReference<Application> serviceReference) { - ServiceReference<Application> serviceReference = - tuple.getServiceReference(); - - String path = serviceReference.getProperty(JAX_RS_APPLICATION_BASE). - toString(); - - TreeSet<Event<MutableTuple<Application>>> - applicationReferences = _applications.get(path); + return _applications.put(path, serviceReference); + } - Event<MutableTuple<Application>> first = - applicationReferences.first(); + public ServiceReference<Application> unsetApplicationForPath(String path) { + return _applications.remove(path); + } - if (tuple.equals(first.getContent())) { - router.signalLeave(first); + public boolean addShadowedApplication( + ServiceReference<Application> serviceReference) { - Event<MutableTuple<Application>> second = - applicationReferences.higher(first); + return _shadowedApplications.add(serviceReference); + } - if (second != null) { - router.signalAdd(second); - } - } + public boolean removeShadowedApplication( + ServiceReference<Application> serviceReference) { - applicationReferences.removeIf( - t -> t.getContent().equals(tuple)); - }); - }); + return _shadowedApplications.remove(serviceReference); } @Override @@ -164,15 +113,7 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime { private Stream<ApplicationDTO> applicationDTOStream() { return _applications.values().stream(). - flatMap( - tree -> tree.size() > 0 ? Stream.of(tree.first()) : Stream.empty() - ).filter( - Objects::nonNull - ).map( - Event::getContent - ).map( - MutableTuple::getServiceReference - ).map( + map( AriesJaxRSServiceRuntime::buildApplicationDTO ); } @@ -187,16 +128,8 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime { } private Stream<FailedApplicationDTO> shadowedApplications() { - return _applications.values().stream().flatMap( - tree -> tree.size() > 0 ? tree.tailSet(tree.first(), false).stream() : Stream.empty() - ).filter( - Objects::nonNull - ).map( - Event::getContent - ).map( - MutableTuple::getServiceReference - ).map( - sr -> buildFailedApplicationDTO( + return _shadowedApplications.stream(). + map(sr -> buildFailedApplicationDTO( DTOConstants.FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE, sr) ); @@ -248,48 +181,4 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime { serviceReference.getProperty("service.id").toString(); } - public static class MutableTuple<T> implements Comparable<MutableTuple<T>> { - - private final ServiceReference<T> _serviceReference; - private T _service; - - public MutableTuple(ServiceReference<T> a, T service) { - _serviceReference = a; - _service = service; - } - - @Override - public int compareTo(MutableTuple<T> o) { - return _serviceReference.compareTo(o._serviceReference); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - MutableTuple<?> that = (MutableTuple<?>) o; - - return _serviceReference.equals(that._serviceReference); - } - - @Override - public int hashCode() { - return _serviceReference.hashCode(); - } - - public ServiceReference<T> getServiceReference() { - return _serviceReference; - } - - public T getSecond() { - return _service; - } - - public void setService(T service) { - _service = service; - } - - } - } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/31bf7383/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 9846ebb..69310a4 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 @@ -17,7 +17,6 @@ package org.apache.aries.jax.rs.whiteboard.internal; -import org.apache.aries.jax.rs.whiteboard.internal.AriesJaxRSServiceRuntime.MutableTuple; import org.apache.aries.osgi.functional.Event; import org.apache.aries.osgi.functional.OSGi; import org.apache.cxf.Bus; @@ -31,9 +30,12 @@ import javax.ws.rs.core.Application; import javax.ws.rs.ext.Provider; import java.util.Comparator; import java.util.Map; +import java.util.NavigableSet; import java.util.SortedSet; import java.util.TreeSet; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.Consumer; +import java.util.function.Function; import static org.apache.aries.osgi.functional.OSGi.bundleContext; import static org.apache.aries.osgi.functional.OSGi.just; @@ -234,6 +236,73 @@ public class Utils { } + public static <K, T extends Comparable<? super T>> OSGi<T> highestPer( + Function<T, K> keySupplier, OSGi<T> program, + Consumer<T> onAddingShadowed, Consumer<T> onRemovedShadowed) { + + ConcurrentHashMap<K, TreeSet<Event<T>>> map = new ConcurrentHashMap<>(); + + return program.route( + router -> { + router.onIncoming(e -> { + K key = keySupplier.apply(e.getContent()); + + Comparator<Event<T>> comparator = Comparator.comparing( + Event::getContent); + + NavigableSet<Event<T>> set = map.computeIfAbsent( + key, __ -> new TreeSet<>(comparator)); + + Event<T> last = set.size() > 0 ? set.last() : null; + + boolean higher = + (last == null) || (comparator.compare(e, last) > 0); + + if (higher) { + if (last != null) { + router.signalLeave(last); + + onAddingShadowed.accept(last.getContent()); + } + + router.signalAdd(e); + } + else { + onAddingShadowed.accept(e.getContent()); + } + + set.add(e); + }); + router.onLeaving(e -> { + T content = e.getContent(); + + K key = keySupplier.apply(content); + + TreeSet<Event<T>> set = map.get(key); + + Event<T> last = set.last(); + + if (content.equals(last.getContent())) { + router.signalLeave(e); + + Event<T> penultimate = set.lower(last); + + if (penultimate != null) { + router.signalAdd(penultimate); + + onRemovedShadowed.accept(penultimate.getContent()); + } + } + else { + onRemovedShadowed.accept(content); + } + + set.removeIf(t -> t.getContent().equals(content)); + }); + } + ); + } + public static class ComparableResourceProvider implements ResourceProvider, Comparable<ComparableResourceProvider> { @@ -284,4 +353,47 @@ public class Utils { } + public static class MutableTuple<T> implements Comparable<MutableTuple<T>> { + + private final ServiceReference<T> _serviceReference; + private T _service; + + public MutableTuple(ServiceReference<T> a, T service) { + _serviceReference = a; + _service = service; + } + + @Override + public int compareTo(MutableTuple<T> o) { + return _serviceReference.compareTo(o._serviceReference); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + MutableTuple<?> that = (MutableTuple<?>) o; + + return _serviceReference.equals(that._serviceReference); + } + + @Override + public int hashCode() { + return _serviceReference.hashCode(); + } + + public ServiceReference<T> getServiceReference() { + return _serviceReference; + } + + public T getSecond() { + return _service; + } + + public void setService(T service) { + _service = service; + } + + } } http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/31bf7383/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 d4a4178..99980bb 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 @@ -17,7 +17,7 @@ package org.apache.aries.jax.rs.whiteboard.internal; -import org.apache.aries.jax.rs.whiteboard.internal.AriesJaxRSServiceRuntime.MutableTuple; +import org.apache.aries.jax.rs.whiteboard.internal.Utils.MutableTuple; import org.apache.aries.osgi.functional.OSGi; import org.apache.cxf.Bus; import org.apache.cxf.bus.extension.ExtensionManagerBus; @@ -41,9 +41,11 @@ import java.util.HashMap; import java.util.Hashtable; import java.util.Map; import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Function; import static java.lang.String.format; import static org.apache.aries.jax.rs.whiteboard.internal.Utils.deployRegistrator; +import static org.apache.aries.jax.rs.whiteboard.internal.Utils.highestPer; import static org.apache.aries.jax.rs.whiteboard.internal.Utils.onlyGettables; import static org.apache.aries.jax.rs.whiteboard.internal.Utils.safeRegisterEndpoint; import static org.apache.aries.jax.rs.whiteboard.internal.Utils.safeRegisterExtension; @@ -72,6 +74,9 @@ import static org.osgi.service.jaxrs.whiteboard.JaxRSWhiteboardConstants.JAX_RS_ * @author Carlos Sierra Andrés */ public class Whiteboard { + + public static final Function<MutableTuple<Application>, String> APPLICATION_BASE = ((Function<MutableTuple<Application>, ServiceReference<Application>>) Utils.MutableTuple::getServiceReference).andThen(Whiteboard::getApplicationBase); + public static OSGi<Void> createWhiteboard(Dictionary<String, ?> configuration) { @@ -231,40 +236,56 @@ public class Whiteboard { AriesJaxRSServiceRuntime runtime, Map<String, ?> configuration) { - OSGi<MutableTuple<Application>> applicationsForWhiteboard = - getApplicationsForWhiteboard(jaxRsRuntimeServiceReference). - flatMap( - sr -> onlyGettables( - sr, runtime::addNotGettable, runtime::removeNotGettable) - ); + OSGi<MutableTuple<Application>> gettableAplicationForWhiteboard = + getApplicationsForWhiteboard(jaxRsRuntimeServiceReference).flatMap( + sr -> onlyGettables( + sr, runtime::addNotGettable, runtime::removeNotGettable) + ); + + OSGi<MutableTuple<Application>> highestRankedPerPath = highestPer( + APPLICATION_BASE, + gettableAplicationForWhiteboard, + t -> runtime.addShadowedApplication(t.getServiceReference()), + t -> runtime.removeShadowedApplication(t.getServiceReference()) + ); return bundleContext().flatMap( - bundleContext -> - runtime.processApplications(applicationsForWhiteboard).flatMap( - ref -> deployApplication( - configuration, bundleContext, ref))); + bundleContext -> highestRankedPerPath.flatMap( + ref -> deployApplication(configuration, bundleContext, ref) + ).map( + MutableTuple::getServiceReference). + foreach( + sr -> runtime.setApplicationForPath( + getApplicationBase(sr), sr), + sr -> runtime.unsetApplicationForPath( + getApplicationBase(sr)) + ) + ); } - private static OSGi<Void> deployApplication( + private static OSGi<MutableTuple<Application>> deployApplication( Map<String, ?> configuration, BundleContext bundleContext, MutableTuple<Application> tuple) { ExtensionManagerBus bus = createBus(bundleContext, configuration); - ServiceReference<Application> serviceReference = tuple.getServiceReference(); + ServiceReference<Application> serviceReference = + tuple.getServiceReference(); Map<String, Object> properties = CXFJaxRsServiceRegistrator.getProperties( serviceReference, JAX_RS_APPLICATION_BASE); - return all( - deployRegistrator(bus, tuple.getSecond(), properties), - registerCXFServletService( - bus, serviceReference.getProperty(JAX_RS_APPLICATION_BASE).toString(), - properties) - ); - + return + all( + deployRegistrator(bus, tuple.getSecond(), properties), + registerCXFServletService( + bus, getApplicationBase(serviceReference), + properties)). + then( + just(tuple) + ); } private static OSGi<ServiceReference<Application>> @@ -384,4 +405,12 @@ public class Whiteboard { } } + public static String getApplicationBase( + ServiceReference<Application> serviceReference) { + + return serviceReference.getProperty(JAX_RS_APPLICATION_BASE).toString(); + } + + + }
