]> git.argeo.org Git - gpl/argeo-slc.git/blobdiff - runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/BundlesManager.java
Make services lookup more robust
[gpl/argeo-slc.git] / runtime / org.argeo.slc.support.osgi / src / main / java / org / argeo / slc / osgi / BundlesManager.java
index e24b7223b7736299125d5aae7f6ddd29b5a4d0f6..7d96ae4c9e6d5487e7dddae839cc4716dae452fe 100644 (file)
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2007-2012 Mathieu Baudier
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package org.argeo.slc.osgi;
 
 import org.apache.commons.logging.Log;
@@ -22,6 +37,7 @@ import org.springframework.osgi.context.event.OsgiBundleApplicationContextListen
 import org.springframework.osgi.context.event.OsgiBundleContextClosedEvent;
 import org.springframework.osgi.context.event.OsgiBundleContextFailedEvent;
 import org.springframework.osgi.context.event.OsgiBundleContextRefreshedEvent;
+import org.springframework.osgi.util.OsgiBundleUtils;
 import org.springframework.osgi.util.OsgiFilterUtils;
 import org.springframework.util.Assert;
 
@@ -32,8 +48,8 @@ public class BundlesManager implements BundleContextAware, FrameworkListener,
 
        private BundleContext bundleContext;
 
-       private Long defaultTimeout = 10000l;
-       private Long pollingPeriod = 100l;
+       private Long defaultTimeout = 30 * 1000l;
+       private Long pollingPeriod = 200l;
 
        // Refresh sync objects
        private final Object refreshedPackageSem = new Object();
@@ -62,7 +78,7 @@ public class BundlesManager implements BundleContextAware, FrameworkListener,
                        startSynchronous(bundle);
 
                        long aStart = System.currentTimeMillis();
-                       if (log.isDebugEnabled()) {
+                       if (log.isTraceEnabled()) {
                                log.debug("OSGi upgrade performed in " + (aStart - begin)
                                                + "ms for bundle " + osgiBundle);
                                log.debug(" stop \t: " + (bUpdate - bStop) + "ms");
@@ -83,19 +99,18 @@ public class BundlesManager implements BundleContextAware, FrameworkListener,
                        long aAppContext = System.currentTimeMillis();
                        long end = aAppContext;
 
-                       if (log.isDebugEnabled()) {
+                       if (log.isTraceEnabled()) {
                                log.debug("Application context refresh performed in "
                                                + (aAppContext - bAppContext) + "ms for bundle "
                                                + osgiBundle);
-                               log.debug(" TOTAL\t: " + (aAppContext - bAppContext) + "ms");
                        }
 
-                       if (log.isDebugEnabled()) {
-                               log.debug("Bundle " + bundle.getSymbolicName()
-                                               + " ready to be used at latest version."
-                                               + " (upgrade performed in " + (end - begin) + "ms).");
-                               log.debug(" TOTAL\t: " + (end - begin) + "ms");
+                       if (log.isDebugEnabled())
+                               log.debug("Bundle '" + bundle.getSymbolicName()
+                                               + "' upgraded and ready " + " (upgrade performed in "
+                                               + (end - begin) + "ms).");
 
+                       if (log.isTraceEnabled()) {
                                ApplicationContext applicationContext = (ApplicationContext) bundleContext
                                                .getService(sr);
                                int beanDefCount = applicationContext.getBeanDefinitionCount();
@@ -252,7 +267,7 @@ public class BundlesManager implements BundleContextAware, FrameworkListener,
                try {
                        Thread.sleep(pollingPeriod);
                } catch (InterruptedException e) {
-                       // silent
+                       throw new SlcException("Polling interrupted");
                }
        }
 
@@ -265,11 +280,16 @@ public class BundlesManager implements BundleContextAware, FrameworkListener,
        }
 
        @SuppressWarnings(value = { "unchecked" })
-       public <T> T getSingleService(Class<T> clss, String filter) {
+       public <T> T getSingleService(Class<T> clss, String filter,
+                       Boolean synchronous) {
                Assert.isTrue(OsgiFilterUtils.isValidFilter(filter), "valid filter");
                ServiceReference[] sfs;
                try {
-                       sfs = bundleContext.getServiceReferences(clss.getName(), filter);
+                       if (synchronous)
+                               sfs = getServiceRefSynchronous(clss.getName(), filter);
+                       else
+                               sfs = bundleContext
+                                               .getServiceReferences(clss.getName(), filter);
                } catch (InvalidSyntaxException e) {
                        throw new SlcException("Cannot retrieve service reference for "
                                        + filter, e);
@@ -283,15 +303,20 @@ public class BundlesManager implements BundleContextAware, FrameworkListener,
                return (T) bundleContext.getService(sfs[0]);
        }
 
-       public <T> T getSingleServiceStrict(Class<T> clss, String filter) {
-               T service = getSingleService(clss, filter);
+       public <T> T getSingleServiceStrict(Class<T> clss, String filter,
+                       Boolean synchronous) {
+               T service = getSingleService(clss, filter, synchronous);
                if (service == null)
                        throw new SlcException("No execution flow found for " + filter);
                else
                        return service;
        }
 
-       /** @return the related bundle or null if not found */
+       /**
+        * @param osgiBundle
+        *            cannot be null
+        * @return the related bundle or null if not found
+        */
        public Bundle findRelatedBundle(OsgiBundle osgiBundle) {
                Bundle bundle = null;
                if (osgiBundle.getInternalBundleId() != null) {
@@ -300,19 +325,30 @@ public class BundlesManager implements BundleContextAware, FrameworkListener,
                                        osgiBundle.getName().equals(bundle.getSymbolicName()),
                                        "symbolic name consistent");
                        if (osgiBundle.getVersion() != null)
-                               Assert.isTrue(osgiBundle.getVersion().equals(
-                                               bundle.getHeaders().get(Constants.BUNDLE_VERSION)),
+                               Assert.isTrue(
+                                               osgiBundle.getVersion().equals(
+                                                               bundle.getHeaders().get(
+                                                                               Constants.BUNDLE_VERSION)),
                                                "version consistent");
-               } else {
+               } else if (osgiBundle.getVersion() == null
+                               || osgiBundle.getVersion().equals("0.0.0")) {
+                       bundle = OsgiBundleUtils.findBundleBySymbolicName(bundleContext,
+                                       osgiBundle.getName());
+               } else {// scan all bundles
                        bundles: for (Bundle b : bundleContext.getBundles()) {
+                               if (b.getSymbolicName() == null) {
+                                       log.warn("Bundle " + b + " has no symbolic name defined.");
+                                       continue bundles;
+                               }
+
                                if (b.getSymbolicName().equals(osgiBundle.getName())) {
                                        if (osgiBundle.getVersion() == null) {
                                                bundle = b;
                                                break bundles;
                                        }
 
-                                       if (b.getHeaders().get(Constants.BUNDLE_VERSION).equals(
-                                                       osgiBundle.getVersion())) {
+                                       if (b.getHeaders().get(Constants.BUNDLE_VERSION)
+                                                       .equals(osgiBundle.getVersion())) {
                                                bundle = b;
                                                osgiBundle.setInternalBundleId(b.getBundleId());
                                                break bundles;
@@ -356,8 +392,11 @@ public class BundlesManager implements BundleContextAware, FrameworkListener,
                this.defaultTimeout = defaultTimeout;
        }
 
-       /** Temporary internal access for {@link OsgiExecutionModulesManager} */
-       BundleContext getBundleContext() {
+       /**
+        * Use with caution since it may interfer with some cached information
+        * within this object
+        */
+       public BundleContext getBundleContext() {
                return bundleContext;
        }