You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2011/01/07 16:51:28 UTC
svn commit: r1056364 - in /karaf/trunk/features/core/src:
main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java
test/java/org/apache/karaf/features/internal/FeaturesServiceImplTest.java
Author: gnodet
Date: Fri Jan 7 15:51:27 2011
New Revision: 1056364
URL: http://svn.apache.org/viewvc?rev=1056364&view=rev
Log:
[KARAF-358] When the feature service calls refresh(), it should wait for the refresh to happen before returning
Modified:
karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java
karaf/trunk/features/core/src/test/java/org/apache/karaf/features/internal/FeaturesServiceImplTest.java
Modified: karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java
URL: http://svn.apache.org/viewvc/karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java?rev=1056364&r1=1056363&r2=1056364&view=diff
==============================================================================
--- karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java (original)
+++ karaf/trunk/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java Fri Jan 7 15:51:27 2011
@@ -16,12 +16,46 @@
*/
package org.apache.karaf.features.internal;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.*;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
import org.apache.felix.utils.manifest.Clause;
import org.apache.felix.utils.manifest.Parser;
import org.apache.felix.utils.version.VersionRange;
import org.apache.felix.utils.version.VersionTable;
-import org.apache.karaf.features.*;
-import org.osgi.framework.*;
+import org.apache.karaf.features.BundleInfo;
+import org.apache.karaf.features.ConfigFileInfo;
+import org.apache.karaf.features.Feature;
+import org.apache.karaf.features.FeatureEvent;
+import org.apache.karaf.features.FeaturesListener;
+import org.apache.karaf.features.FeaturesService;
+import org.apache.karaf.features.Repository;
+import org.apache.karaf.features.RepositoryEvent;
+import org.apache.karaf.features.Resolver;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.Version;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.packageadmin.PackageAdmin;
@@ -30,18 +64,6 @@ import org.osgi.util.tracker.ServiceTrac
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.*;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.*;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.jar.JarInputStream;
-import java.util.jar.Manifest;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
import static java.lang.String.format;
/**
@@ -51,7 +73,7 @@ import static java.lang.String.format;
* installing the needed bundles.
*
*/
-public class FeaturesServiceImpl implements FeaturesService {
+public class FeaturesServiceImpl implements FeaturesService, FrameworkListener {
public static final String CONFIG_KEY = "org.apache.karaf.features.configKey";
@@ -71,6 +93,8 @@ public class FeaturesServiceImpl impleme
private List<FeaturesListener> listeners = new CopyOnWriteArrayList<FeaturesListener>();
private ThreadLocal<Repository> repo = new ThreadLocal<Repository>();
private EventAdminListener eventAdminListener;
+ private final Object refreshLock = new Object();
+ private long refreshTimeout = 5000;
public FeaturesServiceImpl() {
}
@@ -115,6 +139,14 @@ public class FeaturesServiceImpl impleme
this.resolverTimeout = resolverTimeout;
}
+ public long getRefreshTimeout() {
+ return refreshTimeout;
+ }
+
+ public void setRefreshTimeout(long refreshTimeout) {
+ this.refreshTimeout = refreshTimeout;
+ }
+
public void registerListener(FeaturesListener listener) {
listeners.add(listener);
for (Repository repository : listRepositories()) {
@@ -269,7 +301,7 @@ public class FeaturesServiceImpl impleme
}
if (refresh) {
LOGGER.info("Refreshing bundles: {}", sb.toString());
- getPackageAdmin().refreshPackages(bundlesToRefresh.toArray(new Bundle[bundlesToRefresh.size()]));
+ refreshPackages(bundlesToRefresh.toArray(new Bundle[bundlesToRefresh.size()]));
}
}
}
@@ -729,9 +761,7 @@ public class FeaturesServiceImpl impleme
b.uninstall();
}
}
- if (getPackageAdmin() != null) {
- getPackageAdmin().refreshPackages(null);
- }
+ refreshPackages(null);
callListeners(new FeatureEvent(feature, FeatureEvent.EventType.FeatureInstalled, false));
saveState();
}
@@ -820,6 +850,9 @@ public class FeaturesServiceImpl impleme
}
public void start() throws Exception {
+ // Register FrameworkEventListener
+ bundleContext.addFrameworkListener(this);
+ // Register EventAdmin listener
EventAdminListener listener = null;
try {
getClass().getClassLoader().loadClass("org.osgi.service.event.EventAdmin");
@@ -829,6 +862,7 @@ public class FeaturesServiceImpl impleme
LOGGER.debug("EventAdmin package is not available, just don't use it");
}
this.eventAdminListener = listener;
+ // Load State
if (!loadState()) {
if (uris != null) {
for (URI uri : uris) {
@@ -841,6 +875,7 @@ public class FeaturesServiceImpl impleme
}
saveState();
}
+ // Install boot features
if (boot != null && !bootFeaturesInstalled) {
new Thread() {
public void run() {
@@ -873,12 +908,30 @@ public class FeaturesServiceImpl impleme
}
public void stop() throws Exception {
+ bundleContext.removeFrameworkListener(this);
uris = new HashSet<URI>(repositories.keySet());
while (!repositories.isEmpty()) {
internalRemoveRepository(repositories.keySet().iterator().next());
}
}
+ public void frameworkEvent(FrameworkEvent event) {
+ if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED) {
+ synchronized (refreshLock) {
+ refreshLock.notifyAll();
+ }
+ }
+ }
+
+ protected void refreshPackages(Bundle[] bundles) throws InterruptedException {
+ if (getPackageAdmin() != null) {
+ synchronized (refreshLock) {
+ getPackageAdmin().refreshPackages(bundles);
+ refreshLock.wait(refreshTimeout);
+ }
+ }
+ }
+
protected String[] parsePid(String pid) {
int n = pid.indexOf('-');
if (n > 0) {
Modified: karaf/trunk/features/core/src/test/java/org/apache/karaf/features/internal/FeaturesServiceImplTest.java
URL: http://svn.apache.org/viewvc/karaf/trunk/features/core/src/test/java/org/apache/karaf/features/internal/FeaturesServiceImplTest.java?rev=1056364&r1=1056363&r2=1056364&view=diff
==============================================================================
--- karaf/trunk/features/core/src/test/java/org/apache/karaf/features/internal/FeaturesServiceImplTest.java (original)
+++ karaf/trunk/features/core/src/test/java/org/apache/karaf/features/internal/FeaturesServiceImplTest.java Fri Jan 7 15:51:27 2011
@@ -27,6 +27,7 @@ import org.apache.karaf.features.Feature
import org.apache.felix.utils.manifest.Clause;
import org.easymock.EasyMock;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkListener;
import static org.easymock.EasyMock.*;
@@ -102,6 +103,8 @@ public class FeaturesServiceImplTest ext
public void testStartDoesNotFailWithOneInvalidUri() {
BundleContext bundleContext = EasyMock.createMock(BundleContext.class);
expect(bundleContext.getDataFile(EasyMock.<String>anyObject())).andReturn(dataFile).anyTimes();
+ bundleContext.addFrameworkListener(EasyMock.<FrameworkListener>anyObject());
+ bundleContext.removeFrameworkListener(EasyMock.<FrameworkListener>anyObject());
replay(bundleContext);
FeaturesServiceImpl service = new FeaturesServiceImpl();
service.setBundleContext(bundleContext);