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 2019/09/11 13:15:43 UTC

[aries-jax-rs-whiteboard] 02/10: [ARIES-1929] Special error handling in the first rewire

This is an automated email from the ASF dual-hosted git repository.

csierra pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/aries-jax-rs-whiteboard.git

commit 0816520e651c2ba7172720463a118753859b9a00
Author: Carlos Sierra <cs...@apache.org>
AuthorDate: Fri Sep 6 17:13:28 2019 +0200

    [ARIES-1929] Special error handling in the first rewire
    
    If we get a wiring error in the first (probably bulk) rewire we need to
    discard one by one the possible services that are causing it. Since CXF
    does not inform about which service is causing the error we need to try
    incrementally. Once we have ruled out the failing services we mark them
    as such in the runtime and in the extension registry, which might cause
    some more extensions or services to be unregistered from the
    application (even the very application).
    
    During this process we disable the registrator so we don't get
    re-entrant rewires and, when finalized, we try to wire the application
    again. If the application still fails we mark it as failing.
---
 .../jax/rs/whiteboard/internal/Whiteboard.java     |   3 +-
 .../internal/cxf/CxfJaxrsServiceRegistrator.java   | 105 +++++++++++++++++++--
 2 files changed, 98 insertions(+), 10 deletions(-)

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 4bf6ca9..32d90ca 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
@@ -717,7 +717,8 @@ public class Whiteboard {
 
         return
             just(() -> new CxfJaxrsServiceRegistrator(
-                    createBus(extensions), tuple, props.get())).
+                    createBus(extensions), tuple, props.get(),
+                _applicationExtensionRegistry, _runtime)).
             effects(
                 __ -> {},
                 CxfJaxrsServiceRegistrator::enable,
diff --git a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/cxf/CxfJaxrsServiceRegistrator.java b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/cxf/CxfJaxrsServiceRegistrator.java
index 6c780ad..2c51445 100644
--- a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/cxf/CxfJaxrsServiceRegistrator.java
+++ b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/cxf/CxfJaxrsServiceRegistrator.java
@@ -21,6 +21,7 @@ import static java.util.stream.Collectors.toMap;
 import static org.apache.aries.jax.rs.whiteboard.internal.Whiteboard.SUPPORTED_EXTENSION_INTERFACES;
 import static org.apache.aries.jax.rs.whiteboard.internal.utils.Utils.canonicalize;
 import static org.apache.cxf.jaxrs.provider.ProviderFactory.DEFAULT_FILTER_NAME_BINDING;
+import static org.osgi.service.jaxrs.whiteboard.JaxrsWhiteboardConstants.JAX_RS_NAME;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -42,6 +43,8 @@ import javax.ws.rs.core.FeatureContext;
 import javax.ws.rs.ext.RuntimeDelegate;
 
 import org.apache.aries.component.dsl.CachingServiceReference;
+import org.apache.aries.jax.rs.whiteboard.internal.ApplicationExtensionRegistry;
+import org.apache.aries.jax.rs.whiteboard.internal.AriesJaxrsServiceRuntime;
 import org.apache.aries.jax.rs.whiteboard.internal.utils.ServiceTuple;
 import org.apache.cxf.Bus;
 import org.apache.cxf.common.util.ClassHelper;
@@ -64,16 +67,24 @@ public class CxfJaxrsServiceRegistrator {
 
     public CxfJaxrsServiceRegistrator(
         Bus bus, ServiceTuple<Application> applicationTuple,
-        Map<String, ?> properties) {
+        Map<String, ?> properties,
+        ApplicationExtensionRegistry applicationExtensionRegistry,
+        AriesJaxrsServiceRuntime ariesJaxrsServiceRuntime) {
 
         _bus = bus;
         _applicationTuple = applicationTuple;
         _properties = Collections.unmodifiableMap(new HashMap<>(properties));
+        _ariesJaxrsServiceRuntime = ariesJaxrsServiceRuntime;
+        _applicationName = AriesJaxrsServiceRuntime.getServiceName(
+            _properties::get);
+        _applicationExtensionRegistry = applicationExtensionRegistry;
 
         Comparator<ServiceTuple<?>> comparing = Comparator.comparing(
             ServiceTuple::getCachingServiceReference);
 
         _providers = new TreeSet<>(comparing);
+        _erroredProviders = new ArrayList<>();
+        _erroredServices = new ArrayList<>();
     }
 
     public synchronized void add(ResourceProvider resourceProvider) {
@@ -106,7 +117,58 @@ public class CxfJaxrsServiceRegistrator {
     public void enable() {
         _enabled = true;
 
-        rewire();
+        try {
+            rewire();
+        }
+        catch (Exception e) {
+            ArrayList<ServiceTuple<?>> providers = new ArrayList<>();
+            ArrayList<ResourceProvider> services = new ArrayList<>();
+
+            for (ServiceTuple<?> provider : _providers) {
+                providers.add(provider);
+
+                try {
+                    doRewire(providers, services);
+                }
+                catch (Exception ex) {
+                    providers.remove(provider);
+                    _erroredProviders.add(provider);
+                }
+            }
+            for (ResourceProvider service : _services) {
+                services.add(service);
+
+                try {
+                    doRewire(providers, services);
+                }
+                catch (Exception ex) {
+                    services.remove(service);
+                    _erroredServices.add(service);
+                }
+            }
+
+            _enabled = false;
+
+            for (ServiceTuple<?> erroredProvider : _erroredProviders) {
+                CachingServiceReference<?> cachingServiceReference =
+                    erroredProvider.getCachingServiceReference();
+                _providers.remove(erroredProvider);
+                _ariesJaxrsServiceRuntime.addErroredExtension(
+                    cachingServiceReference);
+                _applicationExtensionRegistry.unregisterExtensionInApplication(
+                    _applicationName, cachingServiceReference);
+            }
+            for (ResourceProvider erroredService : _erroredServices) {
+                _services.remove(erroredService);
+                _ariesJaxrsServiceRuntime.addErroredEndpoint(
+                    ((ServiceReferenceResourceProvider)erroredService).
+                        getImmutableServiceReference());
+            }
+
+            _enabled = true;
+
+            rewire();
+        }
     }
 
     public void close() {
@@ -175,19 +237,41 @@ public class CxfJaxrsServiceRegistrator {
     }
 
     public synchronized void remove(ResourceProvider resourceProvider) {
+        if (_erroredServices.remove(resourceProvider)) {
+            _ariesJaxrsServiceRuntime.removeErroredEndpoint(
+                ((ServiceReferenceResourceProvider)resourceProvider).
+                    getImmutableServiceReference());
+        }
+
         _services.remove(resourceProvider);
 
         rewire();
     }
 
     public synchronized void removeProvider(ServiceTuple<?> tuple) {
+        if (_erroredProviders.remove(tuple)) {
+            _ariesJaxrsServiceRuntime.removeErroredExtension(
+                tuple.getCachingServiceReference());
+        }
+
         _providers.remove(tuple);
 
         rewire();
     }
 
-    @SuppressWarnings("serial")
     public synchronized void rewire() {
+        doRewire(_providers, _services);
+    }
+
+    private final String _applicationName;
+    private ArrayList<ServiceTuple<?>> _erroredProviders;
+    private ArrayList<ResourceProvider> _erroredServices;
+
+    @SuppressWarnings("serial")
+    private synchronized void doRewire(
+        Collection<ServiceTuple<?>> providers,
+        Collection<ResourceProvider> services) {
+
         if (!_enabled) {
             return;
         }
@@ -199,12 +283,11 @@ public class CxfJaxrsServiceRegistrator {
         }
 
         if (_server != null) {
-
             _server.destroy();
 
             _applicationTuple.refresh();
 
-            for (ServiceTuple<?> provider : _providers) {
+            for (ServiceTuple<?> provider : providers) {
                 provider.refresh();
             }
         }
@@ -244,7 +327,7 @@ public class CxfJaxrsServiceRegistrator {
 
         List<org.apache.cxf.feature.Feature> features = new ArrayList<>();
 
-        for (ServiceTuple<?> provider : _providers) {
+        for (ServiceTuple<?> provider : providers) {
             CachingServiceReference<?> cachingServiceReference =
                 provider.getCachingServiceReference();
 
@@ -302,10 +385,12 @@ public class CxfJaxrsServiceRegistrator {
             _jaxRsServerFactoryBean.setFeatures(features);
         }
 
-        for (ResourceProvider resourceProvider: _services) {
-            if (resourceProvider instanceof PrototypeServiceReferenceResourceProvider) {
+        for (ResourceProvider resourceProvider: services) {
+            if (resourceProvider instanceof
+                PrototypeServiceReferenceResourceProvider) {
+
                 PrototypeServiceReferenceResourceProvider provider =
-                    (PrototypeServiceReferenceResourceProvider) resourceProvider;
+                    (PrototypeServiceReferenceResourceProvider)resourceProvider;
                 if (!provider.isAvailable()) {
                     continue;
                 }
@@ -383,6 +468,8 @@ public class CxfJaxrsServiceRegistrator {
     private volatile boolean _enabled = false;
     private JAXRSServerFactoryBean _jaxRsServerFactoryBean;
     private Map<String, Object> _properties;
+    private AriesJaxrsServiceRuntime _ariesJaxrsServiceRuntime;
+    private ApplicationExtensionRegistry _applicationExtensionRegistry;
     private Server _server;
 
     private static Set<String> getFilterNameBindings(