Repository: aries-jax-rs-whiteboard Updated Branches: refs/heads/master 2cf7f7f0e -> 5e82038ef
Refactor Whiteboard and move shared state to fields 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/5e82038e Tree: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/tree/5e82038e Diff: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/diff/5e82038e Branch: refs/heads/master Commit: 5e82038efefcb3c53a8318c07e7163264cde9b1b Parents: 2cf7f7f Author: Carlos Sierra <[email protected]> Authored: Tue Sep 5 11:46:20 2017 +0200 Committer: Carlos Sierra <[email protected]> Committed: Tue Sep 5 11:46:20 2017 +0200 ---------------------------------------------------------------------- .../activator/CXFJaxRsBundleActivator.java | 19 +- .../aries/jax/rs/whiteboard/internal/Utils.java | 25 +- .../jax/rs/whiteboard/internal/Whiteboard.java | 573 ++++++++++--------- 3 files changed, 331 insertions(+), 286 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/5e82038e/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 fc140b3..effd182 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 @@ -36,6 +36,8 @@ import org.slf4j.LoggerFactory; import static org.apache.aries.jax.rs.whiteboard.internal.Whiteboard.createWhiteboard; import static org.apache.aries.osgi.functional.OSGi.configurations; +import static org.apache.aries.osgi.functional.OSGi.just; +import static org.apache.aries.osgi.functional.OSGi.onClose; import static org.apache.aries.osgi.functional.OSGi.register; public class CXFJaxRsBundleActivator implements BundleActivator { @@ -57,8 +59,9 @@ public class CXFJaxRsBundleActivator implements BundleActivator { } OSGi<?> whiteboards = - configurations("org.apache.aries.jax.rs.whiteboard"). - flatMap(Whiteboard::createWhiteboard); + configurations("org.apache.aries.jax.rs.whiteboard").flatMap( + configuration -> runWhiteboard(bundleContext, configuration) + ); _whiteboardsResult = whiteboards.run(bundleContext); @@ -71,7 +74,7 @@ public class CXFJaxRsBundleActivator implements BundleActivator { _defaultOSGiResult = register( ClientBuilder.class, new ClientBuilderFactory(), null).then( - createWhiteboard(defaultConfiguration)) + runWhiteboard(bundleContext, defaultConfiguration)) .run(bundleContext); if (_log.isDebugEnabled()) { @@ -94,4 +97,14 @@ public class CXFJaxRsBundleActivator implements BundleActivator { } } + private static OSGi<?> runWhiteboard( + BundleContext bundleContext, Dictionary<String, ?> configuration) { + + Whiteboard whiteboard = createWhiteboard(bundleContext, configuration); + + whiteboard.start(); + + return onClose(whiteboard::stop); + } + } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/5e82038e/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 8bee358..d278e4e 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 @@ -23,11 +23,14 @@ import org.apache.cxf.jaxrs.lifecycle.ResourceProvider; 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; @@ -135,7 +138,7 @@ public class Utils { })); } - public static <T extends Comparable<? super T>> OSGi<T> repeatInOrder( + public static <T extends Comparable<? super T>> OSGi<T> highestRanked( OSGi<T> program) { return program.route(new HighestRankedRouter<>()); @@ -165,7 +168,25 @@ public class Utils { registrator.remove(resourceProvider); } - static OSGi<Void> ignore(OSGi<?> program) { + public static void updateProperty( + ServiceRegistration<?> serviceRegistration, String key, Object value) { + + ServiceReference<?> serviceReference = + serviceRegistration.getReference(); + + Dictionary<String, Object> properties = new Hashtable<>(); + + for (String propertyKey : serviceReference.getPropertyKeys()) { + properties.put( + propertyKey, serviceReference.getProperty(propertyKey)); + } + + properties.put(key, value); + + serviceRegistration.setProperties(properties); + } + + static OSGi<Void> ignoreResult(OSGi<?> program) { return program.map(t -> null); } http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/5e82038e/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 7668c6a..48dc680 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 @@ -21,6 +21,7 @@ import org.apache.aries.jax.rs.whiteboard.internal.Utils.ApplicationExtensionReg 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.OSGi; +import org.apache.aries.osgi.functional.OSGiResult; import org.apache.cxf.Bus; import org.apache.cxf.bus.extension.ExtensionManagerBus; import org.apache.cxf.jaxrs.lifecycle.ResourceProvider; @@ -49,6 +50,7 @@ import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.ParamConverterProvider; import javax.ws.rs.ext.ReaderInterceptor; import javax.ws.rs.ext.WriterInterceptor; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -56,8 +58,8 @@ import java.util.Dictionary; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; +import java.util.List; import java.util.Map; -import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; import java.util.function.Function; @@ -70,13 +72,13 @@ import static org.apache.aries.jax.rs.whiteboard.internal.Utils.generateApplicat import static org.apache.aries.jax.rs.whiteboard.internal.Utils.getProperties; import static org.apache.aries.jax.rs.whiteboard.internal.Utils.getResourceProvider; import static org.apache.aries.jax.rs.whiteboard.internal.Utils.highestPer; -import static org.apache.aries.jax.rs.whiteboard.internal.Utils.ignore; +import static org.apache.aries.jax.rs.whiteboard.internal.Utils.ignoreResult; import static org.apache.aries.jax.rs.whiteboard.internal.Utils.onlyGettables; -import static org.apache.aries.jax.rs.whiteboard.internal.Utils.repeatInOrder; +import static org.apache.aries.jax.rs.whiteboard.internal.Utils.highestRanked; import static org.apache.aries.jax.rs.whiteboard.internal.Utils.service; import static org.apache.aries.jax.rs.whiteboard.internal.Utils.serviceObjects; +import static org.apache.aries.jax.rs.whiteboard.internal.Utils.updateProperty; 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; import static org.apache.aries.osgi.functional.OSGi.nothing; import static org.apache.aries.osgi.functional.OSGi.onClose; @@ -128,129 +130,164 @@ public class Whiteboard { ServiceTuple::getServiceReference).andThen( sr -> getApplicationName(sr::getProperty)); - public static OSGi<?> createWhiteboard( - Dictionary<String, ?> configuration) { + private final AriesJaxRSServiceRuntime _runtime; + private final Map<String, ?> _configurationMap; + private final BundleContext _bundleContext; + private final ServiceRegistrationChangeCounter _counter; + private final ServiceReference<?> _runtimeReference; + private final OSGi<Void> _program; + private final List<Object> _endpoints; + private final ServiceRegistration<?> _runtimeRegistration; + private OSGiResult<Void> _osgiResult; - AriesJaxRSServiceRuntime runtime = new AriesJaxRSServiceRuntime(); + private Whiteboard( + BundleContext bundleContext, Dictionary<String, ?> configuration) { - Map<String, ?> configurationMap = Maps.from(configuration); + _bundleContext = bundleContext; - return - bundleContext().flatMap(bundleContext -> - registerJaxRSServiceRuntime( - runtime, bundleContext, configurationMap). - flatMap(runtimeRegistration -> - just(new ServiceRegistrationChangeCounter(runtimeRegistration)). - flatMap(counter -> - just(runtimeRegistration.getReference()).flatMap(runtimeReference -> - registerDefaultApplication(configurationMap).then( - all( - ignore( - whiteboardApplications( - bundleContext, runtimeReference, runtime, - configurationMap, counter)), - ignore( - whiteBoardApplicationResources( - bundleContext, runtimeReference, runtime, counter)), - ignore( - whiteBoardApplicationExtensions( - bundleContext, runtimeReference, runtime, counter) - ))))))); - } - - public static String getApplicationBase(PropertyHolder properties) { - return properties.get(JAX_RS_APPLICATION_BASE).toString(); + _runtime = new AriesJaxRSServiceRuntime(); + + _configurationMap = Maps.from(configuration); + + _endpoints = new ArrayList<>(); + + _runtimeRegistration = registerJaxRSServiceRuntime( + new HashMap<>(_configurationMap)); + + _runtimeReference = _runtimeRegistration.getReference(); + + _counter = new ServiceRegistrationChangeCounter(_runtimeRegistration); + + _program = + all( + ignoreResult(bestEffortCalculationOfEnpoints()), + ignoreResult(registerDefaultApplication()), + ignoreResult(applications()), + ignoreResult(applicationResources()), + ignoreResult(applicationExtensions() + )); } - public static <T> OSGi<ResourceProvider> - registerEndpoint( - CXFJaxRsServiceRegistrator registrator, - ServiceObjects<T> serviceObjects) { + public static Whiteboard createWhiteboard( + BundleContext bundleContext, Dictionary<String, ?> configuration) { - ResourceProvider resourceProvider = getResourceProvider(serviceObjects); - registrator.add(resourceProvider); - return just(resourceProvider); + return new Whiteboard(bundleContext, configuration); } - public static <T> OSGi<?> safeRegisterEndpoint( - ServiceReference<T> serviceReference, - ServiceReference<CXFJaxRsServiceRegistrator> registratorReference, - AriesJaxRSServiceRuntime runtime) { + public void start() { + _osgiResult = _program.run(_bundleContext); + } - String applicationName = getApplicationName( - registratorReference::getProperty); + public void stop() { + _osgiResult.close(); - return - service(registratorReference).flatMap(registrator -> - onlyGettables( - just(serviceReference), - runtime::addNotGettableEndpoint, - runtime::removeNotGettableEndpoint - ).flatMap( - tuple -> serviceObjects(serviceReference).flatMap( - serviceObjects -> registerEndpoint( - registrator, serviceObjects).flatMap( - resourceProvider -> - onClose( - () -> Utils.unregisterEndpoint( - registrator, resourceProvider) - ) - ) - ) - ).foreach( - __ -> runtime.addApplicationEndpoint( - applicationName, serviceReference), - __ -> runtime.removeApplicationEndpoint( - applicationName, serviceReference) - )); + _runtimeRegistration.unregister(); } - public static OSGi<?> safeRegisterExtension( - ServiceReference<?> serviceReference, - ServiceReference<CXFJaxRsServiceRegistrator> registratorReference, - AriesJaxRSServiceRuntime runtime) { + private void addHttpEndpoints(List<String> endpoints) { + synchronized (_runtimeRegistration) { + _endpoints.addAll(endpoints); - Map<String, Object> properties = getProperties(serviceReference); + updateProperty( + _runtimeRegistration, JAX_RS_SERVICE_ENDPOINT, _endpoints); + } + } - String applicationName = getApplicationName( - registratorReference::getProperty); + private OSGi<?> applicationExtensions() { - properties.put(JAX_RS_NAME, applicationName); - properties.put( - "original.objectClass", - serviceReference.getProperty("objectClass")); + return + onlySupportedInterfaces( + countChanges( + getApplicationExtensionsForWhiteboard(), _counter), + _runtime::addInvalidExtension, + _runtime::removeInvalidExtension). + flatMap(resourceReference -> + chooseApplication( + resourceReference, Whiteboard::allApplicationReferences). + flatMap(registratorReference -> + waitForExtensionDependencies( + _bundleContext, resourceReference, + getApplicationName(registratorReference::getProperty), _runtime, + safeRegisterExtension( + resourceReference, registratorReference, _runtime) + ))); + } + private OSGi<?> applicationResources() { return - service(registratorReference).flatMap(registrator -> + countChanges(getResourcesForWhiteboard(), _counter). + flatMap(resourceReference -> + chooseApplication(resourceReference, this::defaultApplication). + flatMap(registratorReference -> + waitForExtensionDependencies( + _bundleContext, resourceReference, + getApplicationName(registratorReference::getProperty), _runtime, + safeRegisterEndpoint( + resourceReference, registratorReference, _runtime) + ))); + } + + private OSGi<?> applications() { + + OSGi<ServiceTuple<Application>> gettableAplicationForWhiteboard = onlyGettables( - just(serviceReference), - runtime::addNotGettableExtension, - runtime::removeNotGettableExtension - ).foreach( - registrator::addProvider, - registrator::removeProvider + countChanges( + getApplicationsForWhiteboard(), _counter). + flatMap( + sr -> waitForApplicationDependencies( + _bundleContext, sr, _runtime, just(sr))), + _runtime::addNotGettableApplication, + _runtime::removeNotGettableApplication); + + OSGi<ServiceTuple<Application>> highestRankedPerName = highestPer( + APPLICATION_NAME, gettableAplicationForWhiteboard, + t -> _runtime.addClashingApplication(t.getServiceReference()), + t -> _runtime.removeClashingApplication(t.getServiceReference()) + ); + + OSGi<ServiceTuple<Application>> highestRankedPerPath = highestPer( + APPLICATION_BASE, highestRankedPerName, + t -> _runtime.addShadowedApplication(t.getServiceReference()), + t -> _runtime.removeShadowedApplication(t.getServiceReference()) + ); + + return + highestRankedPerPath.flatMap( + tuple -> deployApplication( + _configurationMap, _bundleContext, tuple, _runtime) + ).map( + ServiceTuple::getServiceReference + ).map( + Utils::getProperties ).foreach( - __ -> runtime.addApplicationExtension( - applicationName, serviceReference), - __ -> runtime.removeApplicationExtension( - applicationName, serviceReference) - ).then( - register( - ApplicationExtensionRegistration.class, - new ApplicationExtensionRegistration(){}, properties) - )); + p -> _runtime.setApplicationForPath( + getApplicationBase(p::get), p), + p -> _runtime.unsetApplicationForPath( + getApplicationBase(p::get)) + ); } - private static OSGi<ServiceReference<CXFJaxRsServiceRegistrator>> - allApplicationReferences() { + private OSGi<?> bestEffortCalculationOfEnpoints() { + Object whiteBoardTargetProperty = _configurationMap.get( + HTTP_WHITEBOARD_TARGET); - return serviceReferences(CXFJaxRsServiceRegistrator.class); - } + String targetFilter = + whiteBoardTargetProperty != null ? + whiteBoardTargetProperty.toString() : + "(osgi.http.endpoint=*)"; - private static OSGi<Collection<String>> bestEffortCalculationOfEnpoints( - Filter filter) { + Filter filter; - Collection<String> endPoints = new CopyOnWriteArrayList<>(); + try { + filter = _bundleContext.createFilter( + format( + "(&(objectClass=%s)%s)", HttpServiceRuntime.class.getName(), + targetFilter)); + } + catch (InvalidSyntaxException ise) { + throw new IllegalArgumentException( + format("Invalid syntax for filter %s", targetFilter)); + } return serviceReferences(HttpServiceRuntime.class, filter.toString()). @@ -260,10 +297,85 @@ public class Whiteboard { r.getProperty(HTTP_SERVICE_ENDPOINT))) ). foreach( - endPoints::addAll, - endPoints::removeAll - ). - then(just(endPoints)); + this::addHttpEndpoints, + this::removeHttpEndpoints + ); + } + + private OSGi<ServiceReference<CXFJaxRsServiceRegistrator>> + defaultApplication() { + + return + highestRanked( + serviceReferences( + CXFJaxRsServiceRegistrator.class, + String.format( + "(%s=%s)", JAX_RS_NAME, DEFAULT_NAME) + ).filter( + new TargetFilter<>(_runtimeReference) + ) + ); + } + + private OSGi<ServiceReference<Object>> + getApplicationExtensionsForWhiteboard() { + + return serviceReferences(getApplicationExtensionsFilter()). + filter(new TargetFilter<>(_runtimeReference)); + } + + private OSGi<ServiceReference<Application>> + getApplicationsForWhiteboard() { + + return + serviceReferences(Application.class, getApplicationFilter()). + filter(new TargetFilter<>(_runtimeReference)); + } + + private OSGi<ServiceReference<Object>> getResourcesForWhiteboard() { + return serviceReferences(getResourcesFilter()). + filter( + new TargetFilter<>(_runtimeReference)); + } + + private OSGi<ServiceRegistration<Application>> + registerDefaultApplication() { + + Map<String, Object> properties = new HashMap<>(_configurationMap); + properties.put(JAX_RS_NAME, DEFAULT_NAME); + properties.put(JAX_RS_APPLICATION_BASE, "/"); + properties.put("service.ranking", Integer.MIN_VALUE); + + return register( + Application.class, new DefaultApplication(), properties); + } + + private ServiceRegistration<?> + registerJaxRSServiceRuntime(Map<String, Object> properties) { + + properties.putIfAbsent(Constants.SERVICE_RANKING, Integer.MIN_VALUE); + + return _bundleContext.registerService( + JaxRSServiceRuntime.class, _runtime, new Hashtable<>(properties)); + } + + private void removeHttpEndpoints(List<String> endpoints) { + synchronized (_runtimeRegistration) { + _endpoints.removeAll(endpoints); + + updateProperty( + _runtimeRegistration, JAX_RS_SERVICE_ENDPOINT, _endpoints); + } + } + + static String getApplicationBase(PropertyHolder properties) { + return properties.get(JAX_RS_APPLICATION_BASE).toString(); + } + + private static OSGi<ServiceReference<CXFJaxRsServiceRegistrator>> + allApplicationReferences() { + + return serviceReferences(CXFJaxRsServiceRegistrator.class); } private static OSGi<ServiceReference<CXFJaxRsServiceRegistrator>> @@ -317,19 +429,6 @@ public class Whiteboard { return cxfNonSpringServlet; } - private static OSGi<ServiceReference<CXFJaxRsServiceRegistrator>> - defaultApplication() { - - return - repeatInOrder( - serviceReferences( - CXFJaxRsServiceRegistrator.class, - String.format( - "(%s=%s)", JAX_RS_NAME, DEFAULT_NAME) - ) - ); - } - private static OSGi<ServiceTuple<Application>> deployApplication( Map<String, ?> configuration, BundleContext bundleContext, ServiceTuple<Application> tuple, AriesJaxRSServiceRuntime runtime) { @@ -391,15 +490,6 @@ public class Whiteboard { return format("(%s=*)", JAX_RS_APPLICATION_BASE); } - private static OSGi<ServiceReference<Application>> - getApplicationsForWhiteboard( - ServiceReference<?> jaxRsRuntimeServiceReference) { - - return - serviceReferences(Application.class, getApplicationFilter()). - filter(new TargetFilter<>(jaxRsRuntimeServiceReference)); - } - private static String getExtensionsFilter() { return format("(%s=true)", JAX_RS_EXTENSION); } @@ -451,52 +541,83 @@ public class Whiteboard { return register(Servlet.class, cxfNonSpringServlet, properties); } - private static OSGi<ServiceRegistration<Application>> - registerDefaultApplication(Map<String, ?> configuration) { - - Map<String, Object> properties = new HashMap<>(configuration); - properties.put(JAX_RS_NAME, DEFAULT_NAME); - properties.put(JAX_RS_APPLICATION_BASE, "/"); - properties.put("service.ranking", Integer.MIN_VALUE); + private static <T> OSGi<ResourceProvider> + registerEndpoint( + CXFJaxRsServiceRegistrator registrator, + ServiceObjects<T> serviceObjects) { - return register( - Application.class, new DefaultApplication(), properties); + ResourceProvider resourceProvider = getResourceProvider(serviceObjects); + registrator.add(resourceProvider); + return just(resourceProvider); } - private static OSGi<ServiceRegistration<?>> - registerJaxRSServiceRuntime( - JaxRSServiceRuntime runtime, - BundleContext bundleContext, Map<String, ?> configuration) { + private static <T> OSGi<?> safeRegisterEndpoint( + ServiceReference<T> serviceReference, + ServiceReference<CXFJaxRsServiceRegistrator> registratorReference, + AriesJaxRSServiceRuntime runtime) { - Map<String, Object> properties = new HashMap<>(configuration); + String applicationName = getApplicationName( + registratorReference::getProperty); - properties.putIfAbsent( - HTTP_WHITEBOARD_TARGET, "(osgi.http.endpoint=*)"); + return + service(registratorReference).flatMap(registrator -> + onlyGettables( + just(serviceReference), + runtime::addNotGettableEndpoint, + runtime::removeNotGettableEndpoint + ).flatMap( + tuple -> serviceObjects(serviceReference).flatMap( + serviceObjects -> registerEndpoint( + registrator, serviceObjects).flatMap( + resourceProvider -> + onClose( + () -> Utils.unregisterEndpoint( + registrator, resourceProvider) + ) + ) + ) + ).foreach( + __ -> runtime.addApplicationEndpoint( + applicationName, serviceReference), + __ -> runtime.removeApplicationEndpoint( + applicationName, serviceReference) + )); + } - properties.putIfAbsent(Constants.SERVICE_RANKING, -1); + private static OSGi<?> safeRegisterExtension( + ServiceReference<?> serviceReference, + ServiceReference<CXFJaxRsServiceRegistrator> registratorReference, + AriesJaxRSServiceRuntime runtime) { - String targetFilter = (String)properties.get(HTTP_WHITEBOARD_TARGET); + Map<String, Object> properties = getProperties(serviceReference); - Filter filter; + String applicationName = getApplicationName( + registratorReference::getProperty); - try { - filter = bundleContext.createFilter( - format( - "(&(objectClass=%s)%s)", HttpServiceRuntime.class.getName(), - targetFilter)); - } - catch (InvalidSyntaxException ise) { - throw new IllegalArgumentException( - format("Invalid syntax for filter %s", targetFilter)); - } + properties.put(JAX_RS_NAME, applicationName); + properties.put( + "original.objectClass", + serviceReference.getProperty("objectClass")); return - bestEffortCalculationOfEnpoints(filter).flatMap(endpoints -> { - properties.put(JAX_RS_SERVICE_ENDPOINT, endpoints); - - return register(JaxRSServiceRuntime.class, runtime, properties); - } - ); + service(registratorReference).flatMap(registrator -> + onlyGettables( + just(serviceReference), + runtime::addNotGettableExtension, + runtime::removeNotGettableExtension + ).foreach( + registrator::addProvider, + registrator::removeProvider + ).foreach( + __ -> runtime.addApplicationExtension( + applicationName, serviceReference), + __ -> runtime.removeApplicationExtension( + applicationName, serviceReference) + ).then( + register( + ApplicationExtensionRegistration.class, + new ApplicationExtensionRegistration(){}, properties) + )); } private static boolean signalsValidInterface( @@ -638,104 +759,9 @@ public class Whiteboard { return program; } - private static OSGi<?> whiteBoardApplicationExtensions( - BundleContext bundleContext, - ServiceReference<?> jaxRsRuntimeServiceReference, - AriesJaxRSServiceRuntime runtime, - ServiceRegistrationChangeCounter counter) { + private interface ChangeCounter { - OSGi<ServiceReference<Object>> extensionsForApplications = - serviceReferences(getApplicationExtensionsFilter()). - filter(new TargetFilter<>(jaxRsRuntimeServiceReference)); - - return - onlySupportedInterfaces( - countChanges(extensionsForApplications, counter), - runtime::addInvalidExtension, - runtime::removeInvalidExtension). - flatMap(resourceReference -> - chooseApplication( - resourceReference, Whiteboard::allApplicationReferences). - flatMap(registratorReference -> - waitForExtensionDependencies( - bundleContext, resourceReference, - getApplicationName(registratorReference::getProperty), runtime, - safeRegisterExtension( - resourceReference, registratorReference, runtime) - ))); - } - - private static OSGi<?> whiteBoardApplicationResources( - BundleContext bundleContext, - ServiceReference<?> jaxRsRuntimeServiceReference, - AriesJaxRSServiceRuntime runtime, - ServiceRegistrationChangeCounter counter) { - return - countChanges( - serviceReferences(getResourcesFilter()). - filter( - new TargetFilter<>(jaxRsRuntimeServiceReference)), - counter). - flatMap(resourceReference -> - chooseApplication( - resourceReference, Whiteboard::defaultApplication). - flatMap(registratorReference -> - waitForExtensionDependencies( - bundleContext, resourceReference, - getApplicationName(registratorReference::getProperty), runtime, - safeRegisterEndpoint( - resourceReference, registratorReference, runtime) - ))); - } - - private static OSGi<?> whiteboardApplications( - BundleContext bundleContext, - ServiceReference<?> jaxRsRuntimeServiceReference, - AriesJaxRSServiceRuntime runtime, Map<String, ?> configuration, - ServiceRegistrationChangeCounter counter) { - - OSGi<ServiceTuple<Application>> gettableAplicationForWhiteboard = - onlyGettables( - countChanges( - getApplicationsForWhiteboard(jaxRsRuntimeServiceReference), - counter). - flatMap( - sr -> waitForApplicationDependencies( - bundleContext, sr, runtime, just(sr))), - runtime::addNotGettableApplication, - runtime::removeNotGettableApplication); - - OSGi<ServiceTuple<Application>> highestRankedPerName = highestPer( - APPLICATION_NAME, gettableAplicationForWhiteboard, - t -> runtime.addClashingApplication(t.getServiceReference()), - t -> runtime.removeClashingApplication(t.getServiceReference()) - ); - - OSGi<ServiceTuple<Application>> highestRankedPerPath = highestPer( - APPLICATION_BASE, highestRankedPerName, - t -> runtime.addShadowedApplication(t.getServiceReference()), - t -> runtime.removeShadowedApplication(t.getServiceReference()) - ); - - return - highestRankedPerPath.flatMap( - tuple -> deployApplication( - configuration, bundleContext, tuple, runtime) - ).map( - ServiceTuple::getServiceReference - ).map( - Utils::getProperties - ).foreach( - p -> runtime.setApplicationForPath( - getApplicationBase(p::get), p), - p -> runtime.unsetApplicationForPath( - getApplicationBase(p::get)) - ); - } - - private static interface ChangeCounter { - - public void inc(); + void inc(); } @@ -744,36 +770,21 @@ public class Whiteboard { private static final String changecount = "service.changecount"; private final AtomicLong _atomicLong = new AtomicLong(); - private final Hashtable<String, Object> _properties; - private ServiceRegistration<?> _serviceRegistration; + private final ServiceRegistration<?> _serviceRegistration; - public ServiceRegistrationChangeCounter( + ServiceRegistrationChangeCounter( ServiceRegistration<?> serviceRegistration) { _serviceRegistration = serviceRegistration; - - ServiceReference<?> serviceReference = - _serviceRegistration.getReference(); - - _properties = new Hashtable<>(); - - for (String propertyKey : serviceReference.getPropertyKeys()) { - _properties.put( - propertyKey, serviceReference.getProperty(propertyKey)); - } } @Override public void inc() { long l = _atomicLong.incrementAndGet(); - @SuppressWarnings("unchecked") - Hashtable<String, Object> properties = - (Hashtable<String, Object>)_properties.clone(); - - properties.put(changecount, l); - - _serviceRegistration.setProperties(properties); + synchronized (_serviceRegistration) { + updateProperty(_serviceRegistration, changecount, l); + } } }
