Use mutable references to avoid calling getService twice
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/6e52bcb4 Tree: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/tree/6e52bcb4 Diff: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/diff/6e52bcb4 Branch: refs/heads/master Commit: 6e52bcb4bcdc4526470d00f807743b3f009a54bb Parents: cabf65d Author: Carlos Sierra <[email protected]> Authored: Thu Aug 17 17:29:26 2017 +0200 Committer: Carlos Sierra <[email protected]> Committed: Fri Aug 18 15:59:21 2017 +0200 ---------------------------------------------------------------------- .../internal/AriesJaxRSServiceRuntime.java | 178 +++++++++++++------ .../jax/rs/whiteboard/internal/Whiteboard.java | 34 ++-- 2 files changed, 138 insertions(+), 74 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/6e52bcb4/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 e312432..62acc89 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 @@ -44,98 +44,112 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime { private static final long serialVersionUID = 1L; - private ConcurrentHashMap<String, TreeSet<Event<ServiceReference<Application>>>> _applications = - new ConcurrentHashMap<>(); + private ConcurrentHashMap<String, TreeSet<Event<MutableTuple<Application>>>> + _applications = new ConcurrentHashMap<>(); - private Collection<Event<ServiceReference<Application>>> + private Collection<Event<MutableTuple<Application>>> _ungettableApplications; - - private Comparator<Event<ServiceReference<Application>>> _applicationComparator; + private Comparator<Event<MutableTuple<Application>>> + _applicationComparator; private BundleContext _bundleContext; public AriesJaxRSServiceRuntime(BundleContext bundleContext) { _bundleContext = bundleContext; - _applicationComparator = Comparator.comparing(Event::getContent); + _applicationComparator = Comparator.comparing( + Event::getContent); _applicationComparator = _applicationComparator.reversed(); _ungettableApplications = new TreeSet<>(_applicationComparator); } - public OSGi<ServiceReference<Application>> processApplications( + public OSGi<MutableTuple<Application>> processApplications( OSGi<ServiceReference<Application>> source) { - return source.route(router -> { - router.onIncoming(event -> { - ServiceReference<Application> serviceReference = - event.getContent(); + return + source.map( + sr -> new MutableTuple<>(sr, null) + ). + route( + router -> { + router.onIncoming(event -> { + MutableTuple<Application> + tuple = event.getContent(); - if (!checkGettable(serviceReference)) { - _ungettableApplications.add(event); + ServiceReference<Application> serviceReference = + tuple.getServiceReference(); - return; - } + Application application = checkGettable(serviceReference); - String path = serviceReference.getProperty(JAX_RS_APPLICATION_BASE). - toString(); + if (application == null) { + _ungettableApplications.add(event); - TreeSet<Event<ServiceReference<Application>>> applicationReferences = - _applications.computeIfAbsent( - path, __ -> new TreeSet<>(_applicationComparator)); + return; + } - Event<ServiceReference<Application>> first = - applicationReferences.size() > 0 ? - applicationReferences.first() : null; + tuple.setService(application); - if (first == null || _applicationComparator.compare(event, first) < 0) { - if (first != null) { - router.signalLeave(first); + 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); } - router.signalAdd(event); - } + applicationReferences.add(event); + }); + router.onLeaving(event -> { + MutableTuple<Application> tuple = event.getContent(); - applicationReferences.add(event); - }); - router.onLeaving(event -> { - ServiceReference<Application> serviceReference = - event.getContent(); + ServiceReference<Application> serviceReference = + tuple.getServiceReference(); - boolean ungettable = _ungettableApplications.removeIf( - t -> t.getContent().equals(serviceReference)); + boolean ungettable = _ungettableApplications.removeIf( + t -> t.getContent().equals(tuple)); - if (ungettable) { - return; - } + if (ungettable) { + return; + } - String path = serviceReference.getProperty(JAX_RS_APPLICATION_BASE). - toString(); + String path = serviceReference.getProperty(JAX_RS_APPLICATION_BASE). + toString(); - TreeSet<Event<ServiceReference<Application>>> - applicationReferences = _applications.get(path); + TreeSet<Event<MutableTuple<Application>>> + applicationReferences = _applications.get(path); - Event<ServiceReference<Application>> first = - applicationReferences.first(); + Event<MutableTuple<Application>> first = + applicationReferences.first(); - if (serviceReference.equals(first.getContent())) { - router.signalLeave(first); + if (tuple.equals(first.getContent())) { + router.signalLeave(first); - Event<ServiceReference<Application>> second = - applicationReferences.higher(first); + Event<MutableTuple<Application>> second = + applicationReferences.higher(first); - if (second != null) { - router.signalAdd(second); + if (second != null) { + router.signalAdd(second); + } } - } - applicationReferences.removeIf( - t -> t.getContent().equals(serviceReference)); + applicationReferences.removeIf( + t -> t.getContent().equals(tuple)); + }); }); - }); } - private boolean checkGettable( + private Application checkGettable( ServiceReference<Application> serviceReference) { Application application = null; @@ -148,13 +162,13 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime { } if (application == null) { - return false; + return null; } else { _bundleContext.ungetService(serviceReference); } - return true; + return application; } @Override @@ -190,6 +204,8 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime { ).map( Event::getContent ).map( + MutableTuple::getServiceReference + ).map( AriesJaxRSServiceRuntime::buildApplicationDTO ); } @@ -199,6 +215,8 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime { map( Event::getContent ).map( + MutableTuple::getServiceReference + ).map( sr -> buildFailedApplicationDTO( DTOConstants.FAILURE_REASON_SERVICE_NOT_GETTABLE, sr) @@ -213,6 +231,8 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime { ).map( Event::getContent ).map( + MutableTuple::getServiceReference + ).map( sr -> buildFailedApplicationDTO( DTOConstants.FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE, sr) @@ -265,4 +285,48 @@ 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/6e52bcb4/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 aaee9ac..4628fb7 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 @@ -46,7 +46,6 @@ import static org.apache.aries.jax.rs.whiteboard.internal.Utils.deployRegistrato import static org.apache.aries.jax.rs.whiteboard.internal.Utils.safeRegisterEndpoint; import static org.apache.aries.jax.rs.whiteboard.internal.Utils.safeRegisterExtension; import static org.apache.aries.jax.rs.whiteboard.internal.Utils.safeRegisterGeneric; -import static org.apache.aries.jax.rs.whiteboard.internal.Utils.service; import static org.apache.aries.osgi.functional.OSGi.all; import static org.apache.aries.osgi.functional.OSGi.bundleContext; import static org.apache.aries.osgi.functional.OSGi.just; @@ -80,12 +79,12 @@ public class Whiteboard { registerJaxRSServiceRuntime(runtime, bundleContext, Maps.from(configuration)).flatMap(runtimeResgistration -> createDefaultJaxRsServiceRegistrator(Maps.from(configuration)).flatMap(defaultServiceRegistrator -> just(new ServiceRegistrationChangeCounter(runtimeResgistration)).flatMap(counter -> - just(runtimeResgistration.getReference()).flatMap(reference -> + just(runtimeResgistration.getReference()).flatMap(runtimeRegistration -> all( - countChanges(whiteboardApplications(reference, runtime, Maps.from(configuration)), counter), - countChanges(whiteBoardApplicationSingletons(reference), counter), - countChanges(whiteboardExtensions(reference, defaultServiceRegistrator), counter), - countChanges(whiteboardSingletons(reference, defaultServiceRegistrator), counter) + countChanges(whiteboardApplications(runtimeRegistration, runtime, Maps.from(configuration)), counter), + countChanges(whiteBoardApplicationSingletons(runtimeRegistration), counter), + countChanges(whiteboardExtensions(runtimeRegistration, defaultServiceRegistrator), counter), + countChanges(whiteboardSingletons(runtimeRegistration, defaultServiceRegistrator), counter) ))))))); } @@ -243,22 +242,23 @@ public class Whiteboard { private static OSGi<Void> deployApplication( Map<String, ?> configuration, BundleContext bundleContext, - ServiceReference<Application> ref) { + AriesJaxRSServiceRuntime.MutableTuple<Application> tuple) { ExtensionManagerBus bus = createBus(bundleContext, configuration); + + ServiceReference<Application> serviceReference = tuple.getServiceReference(); + Map<String, Object> properties = CXFJaxRsServiceRegistrator.getProperties( - ref, JAX_RS_APPLICATION_BASE); + serviceReference, JAX_RS_APPLICATION_BASE); + + return all( + deployRegistrator(bus, tuple.getSecond(), properties), + registerCXFServletService( + bus, serviceReference.getProperty(JAX_RS_APPLICATION_BASE).toString(), + properties) + ); - return service(ref).flatMap( - application -> - all( - deployRegistrator(bus, application, properties), - registerCXFServletService( - bus, ref.getProperty(JAX_RS_APPLICATION_BASE).toString(), - properties) - ) - ); } private static OSGi<ServiceReference<Application>>
