Move application clashing handling to the runtime
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/bf5454a3 Tree: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/tree/bf5454a3 Diff: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/diff/bf5454a3 Branch: refs/heads/master Commit: bf5454a394dd36768cad350e5e2dd30c91695e82 Parents: 988a7cb Author: Carlos Sierra <[email protected]> Authored: Thu Aug 17 10:50:23 2017 +0200 Committer: Carlos Sierra <[email protected]> Committed: Fri Aug 18 15:59:21 2017 +0200 ---------------------------------------------------------------------- .../internal/AriesJaxRSServiceRuntime.java | 161 ++++++++++++++++++- .../jax/rs/whiteboard/internal/Whiteboard.java | 49 +++--- 2 files changed, 185 insertions(+), 25 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/bf5454a3/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 80d99ff..5317b66 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,15 +17,99 @@ 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.ServiceReference; import org.osgi.service.jaxrs.runtime.JaxRSServiceRuntime; +import org.osgi.service.jaxrs.runtime.dto.ApplicationDTO; +import org.osgi.service.jaxrs.runtime.dto.DTOConstants; +import org.osgi.service.jaxrs.runtime.dto.FailedApplicationDTO; import org.osgi.service.jaxrs.runtime.dto.RequestInfoDTO; import org.osgi.service.jaxrs.runtime.dto.RuntimeDTO; +import org.osgi.service.jaxrs.whiteboard.JaxRSWhiteboardConstants; + +import javax.ws.rs.core.Application; +import java.util.Comparator; +import java.util.Objects; +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<ServiceReference<Application>>>> _applications = + new ConcurrentHashMap<>(); + + private Comparator<Event<ServiceReference<Application>>> _applicationComparator; + public AriesJaxRSServiceRuntime() { + _applicationComparator = Comparator.comparing(Event::getContent); + + _applicationComparator = _applicationComparator.reversed(); + } + + public OSGi<ServiceReference<Application>> processApplications( + OSGi<ServiceReference<Application>> source) { + + return source.route(router -> { + router.onIncoming(event -> { + ServiceReference<Application> serviceReference = + event.getContent(); + + String path = serviceReference.getProperty(JAX_RS_APPLICATION_BASE). + toString(); + + TreeSet<Event<ServiceReference<Application>>> applicationReferences = + _applications.computeIfAbsent( + path, __ -> new TreeSet<>(_applicationComparator)); + + Event<ServiceReference<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 -> { + ServiceReference<Application> serviceReference = + event.getContent(); + + String path = serviceReference.getProperty(JAX_RS_APPLICATION_BASE). + toString(); + + TreeSet<Event<ServiceReference<Application>>> + applicationReferences = _applications.get(path); + + Event<ServiceReference<Application>> first = + applicationReferences.first(); + + if (serviceReference.equals(first.getContent())) { + router.signalLeave(first); + + Event<ServiceReference<Application>> second = + applicationReferences.higher(first); + + if (second != null) { + router.signalAdd(second); + } + } + + applicationReferences.removeIf( + t -> t.getContent().equals(serviceReference)); + }); + }); } @Override @@ -35,7 +119,82 @@ public class AriesJaxRSServiceRuntime implements JaxRSServiceRuntime { @Override public RuntimeDTO getRuntimeDTO() { - return null; + RuntimeDTO runtimeDTO = new RuntimeDTO(); + + runtimeDTO.applicationDTOs = _applications.values().stream(). + flatMap( + tree -> tree.size() > 0 ? Stream.of(tree.first()) : Stream.empty() + ).filter( + Objects::nonNull + ).map( + Event::getContent + ).map( + AriesJaxRSServiceRuntime::buildApplicationDTO + ).toArray( + ApplicationDTO[]::new + ); + + runtimeDTO.failedApplicationDTOs = _applications.values().stream(). + flatMap( + tree -> tree.size() > 0 ? tree.tailSet(tree.first(), false).stream() : Stream.empty() + ).filter( + Objects::nonNull + ).map( + Event::getContent + ).map( + sr -> buildFailedApplicationDTO( + DTOConstants.FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE, sr) + ).toArray( + FailedApplicationDTO[]::new + ); + + return runtimeDTO; + } + + private static ApplicationDTO buildApplicationDTO( + ServiceReference<Application> serviceReference) { + + ApplicationDTO applicationDTO = new ApplicationDTO(){}; + + applicationDTO.name = getApplicationName(serviceReference); + + return applicationDTO; + } + + private static FailedApplicationDTO buildFailedApplicationDTO( + int reason, ServiceReference<Application> serviceReference) { + + FailedApplicationDTO failedApplicationDTO = new FailedApplicationDTO(); + + Object nameProperty = serviceReference.getProperty( + JaxRSWhiteboardConstants.JAX_RS_NAME); + + failedApplicationDTO.name = nameProperty == null ? + generateApplicationName(serviceReference) : + nameProperty.toString(); + + failedApplicationDTO.failureReason = reason; + + return failedApplicationDTO; + } + + private static String getApplicationName( + ServiceReference<Application> serviceReference) { + + Object property = serviceReference.getProperty(JAX_RS_NAME); + + if (property == null) { + return generateApplicationName(serviceReference); + } + + return property.toString(); + } + + private static String generateApplicationName( + ServiceReference<Application> serviceReference) { + + return "jax-rs-application-" + + serviceReference.getProperty("service.id").toString(); } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/bf5454a3/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 ca404a8..33284a5 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 @@ -43,7 +43,6 @@ import java.util.concurrent.atomic.AtomicLong; import static java.lang.String.format; import static org.apache.aries.jax.rs.whiteboard.internal.Utils.cxfRegistrator; -import static org.apache.aries.jax.rs.whiteboard.internal.Utils.repeatInOrder; 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; @@ -73,14 +72,16 @@ import static org.osgi.service.jaxrs.whiteboard.JaxRSWhiteboardConstants.JAX_RS_ */ public class Whiteboard { public static OSGi<Void> createWhiteboard(Dictionary<String, ?> configuration) { + AriesJaxRSServiceRuntime runtime = new AriesJaxRSServiceRuntime(); + return bundleContext().flatMap(bundleContext -> - registerJaxRSServiceRuntime(bundleContext, Maps.from(configuration)).flatMap(registratorRegistration -> + registerJaxRSServiceRuntime(runtime, bundleContext, Maps.from(configuration)).flatMap(runtimeResgistration -> createDefaultJaxRsServiceRegistrator(Maps.from(configuration)).flatMap(defaultServiceRegistrator -> - just(new ServiceRegistrationChangeCounter(registratorRegistration)).flatMap(counter -> - just(registratorRegistration.getReference()).flatMap(reference -> + just(new ServiceRegistrationChangeCounter(runtimeResgistration)).flatMap(counter -> + just(runtimeResgistration.getReference()).flatMap(reference -> all( - countChanges(whiteboardApplications(reference, Maps.from(configuration)), counter), + countChanges(whiteboardApplications(reference, runtime, Maps.from(configuration)), counter), countChanges(whiteBoardApplicationSingletons(reference), counter), countChanges(whiteboardExtensions(reference, defaultServiceRegistrator), counter), countChanges(whiteboardSingletons(reference, defaultServiceRegistrator), counter) @@ -161,6 +162,7 @@ public class Whiteboard { private static OSGi<ServiceRegistration<?>> registerJaxRSServiceRuntime( + JaxRSServiceRuntime runtime, BundleContext bundleContext, Map<String, ?> configuration) { Map<String, Object> properties = new HashMap<>(configuration); @@ -189,9 +191,7 @@ public class Whiteboard { bestEffortCalculationOfEnpoints(filter).flatMap(endpoints -> { properties.put(JAX_RS_SERVICE_ENDPOINT, endpoints); - return register( - new String[]{JaxRSServiceRuntime.class.getName()}, - new AriesJaxRSServiceRuntime(), properties); + return register(JaxRSServiceRuntime.class, runtime, properties); } ); } @@ -226,26 +226,27 @@ public class Whiteboard { private static OSGi<?> whiteboardApplications( ServiceReference<?> jaxRsRuntimeServiceReference, + AriesJaxRSServiceRuntime runtime, Map<String, ?> configuration) { return - bundleContext().flatMap(bundleContext -> - repeatInOrder( + bundleContext().flatMap( + bundleContext -> runtime.processApplications( serviceReferences(Application.class, getApplicationFilter()). - filter(new TargetFilter<>(jaxRsRuntimeServiceReference))). - flatMap(ref -> - just(createBus(bundleContext, configuration)). - flatMap(bus -> - just(CXFJaxRsServiceRegistrator.getProperties(ref, JAX_RS_APPLICATION_BASE)). - flatMap(properties -> - service(ref).flatMap(application -> - all( - cxfRegistrator(bus, application, properties), - registerCXFServletService( - bus, ref.getProperty(JAX_RS_APPLICATION_BASE).toString(), - properties) - ) - ))))); + filter(new TargetFilter<>(jaxRsRuntimeServiceReference))).flatMap( + ref -> + just(createBus(bundleContext, configuration)). + flatMap(bus -> + just(CXFJaxRsServiceRegistrator.getProperties(ref, JAX_RS_APPLICATION_BASE)). + flatMap(properties -> + service(ref).flatMap(application -> + all( + cxfRegistrator(bus, application, properties), + registerCXFServletService( + bus, ref.getProperty(JAX_RS_APPLICATION_BASE).toString(), + properties) + ) + ))))); } private static OSGi<?> whiteboardExtensions(
