diff options
author | afinkbein | 2010-03-22 19:19:44 +0000 |
---|---|---|
committer | afinkbein | 2010-03-22 19:19:44 +0000 |
commit | 2f64110f4f386a4ac0a1e5784a4a3edad79fab38 (patch) | |
tree | 4939cf96787497501a09658d1ce6d675709f79ad | |
parent | 34e419a1ca602b17c0cfcddcde797dab68b1d202 (diff) | |
download | org.eclipse.osee-2f64110f4f386a4ac0a1e5784a4a3edad79fab38.tar.gz org.eclipse.osee-2f64110f4f386a4ac0a1e5784a4a3edad79fab38.tar.xz org.eclipse.osee-2f64110f4f386a4ac0a1e5784a4a3edad79fab38.zip |
"Team Workflow" - 40MK0 - "Create a new Ote Server Launch and OteService"
11 files changed, 800 insertions, 16 deletions
diff --git a/plugins/org.eclipse.osee.ote.core/META-INF/MANIFEST.MF b/plugins/org.eclipse.osee.ote.core/META-INF/MANIFEST.MF index 2d8e08147dd..d403da06e8c 100644 --- a/plugins/org.eclipse.osee.ote.core/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.osee.ote.core/META-INF/MANIFEST.MF @@ -39,12 +39,14 @@ Require-Bundle: org.eclipse.osee.framework.jdk.core, Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-Activator: org.eclipse.osee.ote.core.internal.Activator -Import-Package: org.apache.xml.serialize, +Import-Package: javax.xml.parsers, + org.apache.xml.serialize, org.eclipse.osee.framework.core.data, + org.eclipse.osee.framework.core.util, org.eclipse.osee.framework.messaging, org.eclipse.osee.framework.messaging.id, + org.eclipse.osee.framework.plugin.core.util, + org.w3c.dom, org.xml.sax, - org.xml.sax.helpers, - org.xml.sax.ext, - javax.xml.parsers, - org.w3c.dom + org.xml.sax.ext, + org.xml.sax.helpers diff --git a/plugins/org.eclipse.osee.ote.core/OteUtil.java b/plugins/org.eclipse.osee.ote.core/OteUtil.java new file mode 100644 index 00000000000..c0226d9fe68 --- /dev/null +++ b/plugins/org.eclipse.osee.ote.core/OteUtil.java @@ -0,0 +1,21 @@ +package lba.ote.server.core; + + +public class OteUtil { + + public static String generateBundleVersionString(String bundleSpecificVersion, String symbolicName, String version, byte[] md5){ + StringBuilder sb = new StringBuilder(); + if(bundleSpecificVersion != null){ + sb.append(bundleSpecificVersion); + sb.append("_"); + } + sb.append(symbolicName); + sb.append("_"); + sb.append(version); + sb.append("_"); + for(byte b:md5){ + sb.append(String.format("%X", b)); + } + return sb.toString(); + } +} diff --git a/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/OseeURLClassLoader.java b/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/OseeURLClassLoader.java new file mode 100644 index 00000000000..5ff40cf13b4 --- /dev/null +++ b/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/OseeURLClassLoader.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2004, 2007 Boeing. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.ote.core; + +import java.net.URL; +import java.net.URLClassLoader; +import java.net.URLStreamHandlerFactory; + +/** + * @author Andrew M. Finkbeiner + */ +public class OseeURLClassLoader extends URLClassLoader { + + private final String name; + + /** + * @param urls + * @param parent + */ + public OseeURLClassLoader(String name, URL[] urls, ClassLoader parent) { + super(urls, parent); + this.name = name; + GCHelper.getGCHelper().addRefWatch(this); + + } + + /** + * @param urls + */ + public OseeURLClassLoader(String name, URL[] urls) { + super(urls); + GCHelper.getGCHelper().addRefWatch(this); + this.name = name; + } + + /** + * @param urls + * @param parent + * @param factory + */ + public OseeURLClassLoader(String name, URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) { + super(urls, parent, factory); + GCHelper.getGCHelper().addRefWatch(this); + this.name = name; + } + + @Override + public String toString() { + return this.getClass().getName() + " [ " + name + " ] "; + } +} diff --git a/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/environment/interfaces/AbstractRuntimeManager.java b/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/environment/interfaces/AbstractRuntimeManager.java new file mode 100644 index 00000000000..f53b54fa107 --- /dev/null +++ b/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/environment/interfaces/AbstractRuntimeManager.java @@ -0,0 +1,627 @@ +package org.eclipse.osee.ote.core.environment.interfaces; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; +import java.net.URLClassLoader; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Platform; +import org.eclipse.osee.framework.jdk.core.util.ChecksumUtil; +import org.eclipse.osee.framework.jdk.core.util.Lib; +import org.eclipse.osee.framework.jdk.core.util.io.MatchFilter; +import org.eclipse.osee.framework.jdk.core.util.io.streams.StreamPumper; +import org.eclipse.osee.framework.logging.OseeLog; +import org.eclipse.osee.framework.plugin.core.util.ExportClassLoader; +import org.eclipse.osee.ote.core.GCHelper; +import org.eclipse.osee.ote.core.OseeURLClassLoader; +import org.eclipse.osee.ote.core.ReturnStatus; +import org.eclipse.osee.ote.core.environment.BundleDescription; +import org.eclipse.osee.ote.core.environment.BundleResolveException; +import org.eclipse.osee.ote.core.environment.TestEnvironment; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleException; +import org.osgi.service.packageadmin.PackageAdmin; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +public class AbstractRuntimeManager implements IRuntimeLibraryManager { + + /** + * + */ + private static final String OTE_ACTIVATION_POLICY = "OTE-ActivationPolicy"; + private final Collection<Bundle> installedBundles; + private final Collection<Bundle> runningBundles; + private final Map<String, byte[]> bundleNameToMd5Map; + private final HashMap<String, File> availableJars; + private ClassLoader runtimeLibraryLoader; + private URLClassLoader scriptClassLoader; + + private volatile boolean cleanUpNeeded = true; + + private final BundleContext context; + private final PackageAdmin packageAdmin; + + + public AbstractRuntimeManager(PackageAdmin packageAdmin, BundleContext context) { + this.context = context; + this.packageAdmin = packageAdmin; + this.installedBundles = new LinkedList<Bundle>(); + this.runningBundles = new LinkedList<Bundle>(); + this.availableJars = new HashMap<String, File>(32); + this.bundleNameToMd5Map = new HashMap<String, byte[]>(); + this.runtimeLibraryLoader = null; + this.scriptClassLoader = null; + } + + private final List<RuntimeLibraryListener> listeners = new ArrayList<RuntimeLibraryListener>(); + + private String[] currentJarVersions = null; + + private URLClassLoader loader = null; + + protected URLClassLoader getClassLoader(String[] versions) throws IOException { + + ExportClassLoader classLoader = new ExportClassLoader(packageAdmin); + + ArrayList<URL> classpaths = new ArrayList<URL>(); + for (String version : versions) { + File jar = getAvailableJar(version); + if (jar != null) { + classpaths.add(jar.toURI().toURL()); + } else { + OseeLog.log(AbstractRuntimeManager.class, Level.FINE, + "The null jar file for version " + version); + } + } + loader = + new OseeURLClassLoader("Runtime Library ClassLoader", classpaths.toArray(new URL[classpaths.size()]), + classLoader); + + return loader; + } + + protected URLClassLoader getLoader() { + return loader; + } + + public boolean isMessageJarAvailable(String version) { + boolean retVal = false; + + // For efficiency, first check the already known available Jars. + // If the desired version is not available, then update that list + // and check it again. + if (availableJars.containsKey(version)) { + retVal = true; + } else { + updateAvailableJars(); + if (availableJars.containsKey(version)) { + retVal = true; + } + } + + return retVal; + } + +//TODO MAKE SURE TO CHECK BUNDLE STATE IS RESOLVED OR ACTIVE + @Override + public boolean isBundleAvailable(String symbolicName, String version, byte[] md5Digest) { + Bundle[] bundles = Platform.getBundles(symbolicName, version); + if (bundles == null) { + return false; + } + for (Bundle bundle : bundles) { + String bundleSymbolicName = bundle.getSymbolicName(); + if (bundleSymbolicName.equals(symbolicName) && bundle.getHeaders().get("Bundle-Version").equals(version)) { + if (bundleNameToMd5Map.containsKey(bundleSymbolicName)) { + // check for bundle binary equality + if (Arrays.equals(bundleNameToMd5Map.get(bundleSymbolicName), md5Digest)) { + return true; + } + } else { + // we do not have a md5 hash for this bundle so we need to create one + try { + InputStream in = new FileInputStream(FileLocator.getBundleFile(bundle)); + try { + byte[] digest = ChecksumUtil.createChecksum(in, "MD5"); + if (Arrays.equals(digest, md5Digest)) { + bundleNameToMd5Map.put(bundle.getSymbolicName(), digest); + return true; + } + } finally { + in.close(); + } + } catch (Exception e) { + OseeLog.log(AbstractRuntimeManager.class, Level.SEVERE, + "could not determine binary equality of bundles", e); + } + } + } + } + return false; + } + + @Override + public void loadBundles(Collection<BundleDescription> bundles) throws Exception { + cleanUpNeeded = true; + for (BundleDescription bundleDescription : bundles) { + + String bundleName = bundleDescription.getSymbolicName(); + try { + + boolean exists = false; + + for (Bundle bundle : runningBundles) { + if (bundle.getSymbolicName().equals(bundleName)) { + bundle.update(); + exists = true; + break; + } + } + + if (!exists) { + Bundle bundle = Platform.getBundle(bundleDescription.getSymbolicName()); + if (bundle == null) { + InputStream bundleData = getBundleInputStream(bundleDescription); + Bundle installedBundle = context.installBundle("OTE-" + bundleName, bundleData); + bundleData.close(); + bundleNameToMd5Map.put(bundleName, bundleDescription.getMd5Digest()); + installedBundles.add(installedBundle); + } + } + + } catch (Throwable th) { + OseeLog.log(AbstractRuntimeManager.class, Level.SEVERE, String.format("Unable to load [%s].", bundleName), + th); + } + } + + if (runtimeLibraryLoader == null) { + runtimeLibraryLoader = getClassLoader(new String[0]); + } + scriptClassLoader = + new OseeURLClassLoader("Script ClassLoader", Lib.getUrlFromString(new String[] {""}), + this.runtimeLibraryLoader); + transitionInstalledBundles(); + } + + /** + * @param bundleDescription + * @return + * @throws IOException + */ + private InputStream getBundleInputStream(BundleDescription bundleDescription) throws IOException { + if (bundleDescription.isSystemLibrary()) { + return acquireSystemLibraryStream(bundleDescription); + } else { + return acquireUserLibraryStream(bundleDescription); + } + } + + /** + * @param bundleDescription + * @return + * @throws IOException + */ + private InputStream acquireUserLibraryStream(BundleDescription bundleDescription) throws IOException { + return bundleDescription.getBundleData(); + } + + /** + * @param bundleDescription + * @return + * @throws IOException + */ + private InputStream acquireSystemLibraryStream(BundleDescription bundleDescription) throws IOException { + try { + File dir = getJarCache(); + File anticipatedJarFile = + new File(dir, bundleDescription.getSymbolicName() + "_" + bundleDescription.getVersion() + ".jar"); + + ensureJarFileOnDisk(bundleDescription, anticipatedJarFile); + + OseeLog.log(AbstractRuntimeManager.class, Level.FINEST, String.format("Looking for [%s] on disk.", anticipatedJarFile.getAbsolutePath())); + + return new FileInputStream(anticipatedJarFile); + } catch (Exception ex) { + OseeLog.log( + AbstractRuntimeManager.class, + Level.WARNING, + "Failed to acquire system lib from cache. " + "Fell back to direct acquisition from server with out caching", + ex); + + return bundleDescription.getBundleData(); + } + } + + private void ensureJarFileOnDisk(BundleDescription bundleDescription, File anticipatedJarFile) throws IOException, FileNotFoundException, NoSuchAlgorithmException { + // assume MD5 matches until we can check the file + boolean md5Matches = true; + + if (anticipatedJarFile.exists()) { + InputStream in = new FileInputStream(anticipatedJarFile); + byte[] diskMd5Digest = ChecksumUtil.createChecksum(in, "MD5"); + in.close(); + + md5Matches = Arrays.equals(diskMd5Digest, bundleDescription.getMd5Digest()); + } + + if (!md5Matches || !anticipatedJarFile.exists()) { + InputStream servedBundleIn = bundleDescription.getBundleData(); + OutputStream cachedFileOut = new FileOutputStream(anticipatedJarFile); + + StreamPumper.pumpData(servedBundleIn, cachedFileOut); + + cachedFileOut.close(); + servedBundleIn.close(); + } + } + + private void initClassloadersWithNoURLs() { + if (runtimeLibraryLoader == null && scriptClassLoader == null) { + try { + runtimeLibraryLoader = getClassLoader(new String[0]); + scriptClassLoader = + new OseeURLClassLoader("Script ClassLoader", Lib.getUrlFromString(new String[] {""}), + this.runtimeLibraryLoader); + } catch (IOException ex) { + OseeLog.log(AbstractRuntimeManager.class, Level.SEVERE, ex); + } + } + } + + @Override + public void updateBundles(Collection<BundleDescription> bundles) throws BundleException, IOException { + for (BundleDescription bundle : bundles) { + for (Bundle runningBundle : runningBundles) { + if (runningBundle.getSymbolicName().equals(bundle.getSymbolicName())) { + InputStream bundleData = getBundleInputStream(bundle); + runningBundle.update(bundleData); + bundleData.close(); + bundleNameToMd5Map.put(bundle.getSymbolicName(), bundle.getMd5Digest()); + } + } + } + + packageAdmin.refreshPackages(null); + try { + Thread.sleep(10000); + } catch (InterruptedException ex) { + } + } + + /** + * checks the file system for new jar files + */ + private void updateAvailableJars() { + File dir = getJarCache(); + File[] files = dir.listFiles(new MatchFilter(".*\\.jar")); + if (files == null) { + System.out.println("path=[" + dir.getAbsolutePath() + "]"); + return; + } + for (File file : files) { + try { + String version = Lib.getJarFileVersion(file.getAbsolutePath()); + availableJars.put(version, file); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + } + + private File getJarCache() { + String path = System.getProperty("user.home") + File.separator + TestEnvironment.class.getName(); + File jarCache = new File(path, "runtimeCache"); + if (!jarCache.exists()) { + if (!jarCache.mkdirs()) { + throw new RuntimeException("Could not create JAR cache at " + jarCache.getAbsolutePath()); + } + } + if (!jarCache.isDirectory()) { + throw new IllegalStateException("the JAR cache is not a directory! Path=" + jarCache.getAbsolutePath()); + } + return jarCache; + } + + public final boolean setupClassLoaderAndJar(String[] jarVersions, String[] classpaths) throws Exception { + return configureMessages(jarVersions, classpaths); + + } + + private boolean configureMessages(String[] jarVersions, String[] classpaths) throws IOException, BundleException { + + if (!checkCurrentJarVersions(jarVersions).getStatus()) { + if (runtimeLibraryLoader != null) { + onRuntimeUnloaded(); + } + currentJarVersions = jarVersions; + Arrays.sort(currentJarVersions); + runtimeLibraryLoader = getClassLoader(jarVersions); + scriptClassLoader = + new OseeURLClassLoader("Script ClassLoader", Lib.getUrlFromString(classpaths), this.runtimeLibraryLoader); + onRuntimeLoaded(); + return true; + } + + // NOTE cheap fix here.... we need to do this the right way so that the classpaths can get + // updated.... look at resetScriptClassloader + scriptClassLoader = + new OseeURLClassLoader("Script ClassLoader", Lib.getUrlFromString(classpaths), this.runtimeLibraryLoader); + return false; + } + + /** + * @deprecated + */ + @Deprecated + @Override + public void onRuntimeLoaded() { + for (RuntimeLibraryListener listener : listeners) { + if (scriptClassLoader == null) { + listener.onPostRuntimeLibraryUpdated(ExportClassLoader.getInstance()); + } else { + listener.onPostRuntimeLibraryUpdated(scriptClassLoader); + } + } + } + + /** + * @deprecated + */ + @Deprecated + @Override + public void onRuntimeUnloaded() { + for (RuntimeLibraryListener listener : listeners) { + listener.onRuntimeLibraryUnload(); + } + } + + /** + * @throws BundleException + * @throws BundleResolveException + */ + private void transitionInstalledBundles() throws BundleException, BundleResolveException { + Iterator<Bundle> iter = installedBundles.iterator(); + + // Make sure that all installed bundles have been resolved so that + // the export class loader has access to their classes if necessary. + resolveBundles(); + + while (iter.hasNext()) { + Bundle bundle = iter.next(); + + try { + String oteActivationPolicy = (String) bundle.getHeaders().get(OTE_ACTIVATION_POLICY); + if ("early".equalsIgnoreCase(oteActivationPolicy)) { + bundle.start(); + } + + // We got here because bundle.start did not exception + runningBundles.add(bundle); + } catch (BundleException ex) { + throw new BundleException("Error trying to start bundle " + bundle.getSymbolicName() + ": " + ex, ex); + } finally { + iter.remove(); + } + } + } + + /** + * @throws BundleException + * @throws BundleResolveException + */ + private void resolveBundles() throws BundleResolveException { + // Note: This is done one by one for simpler debugging when some + // bundles don't resolve + + Collection<BundleException> resolveExceptions = new LinkedList<BundleException>(); + Bundle[] bundleArray = new Bundle[1]; + for (Bundle bundle : installedBundles) { + // Prior calls to resolveBundles may have forced this bundle + // to resolve so don't waste time recalling the resolve + if (bundle.getState() != Bundle.INSTALLED) { + continue; + } + bundleArray[0] = bundle; + boolean resolved = packageAdmin.resolveBundles(bundleArray); + if (!resolved) { + try { + bundle.start(); + + // If resolve failed then the call to start should have forced a BundleException + // and this code should never be reached + OseeLog.log(AbstractRuntimeManager.class, Level.SEVERE, + "Forced to start bundle " + bundle.getSymbolicName() + " to get it resolved, should never occur!"); + } catch (BundleException ex) { + resolveExceptions.add(new BundleException( + "Error trying to resolve bundle " + bundle.getSymbolicName() + ": " + ex, ex)); + } + } + } + + if (!resolveExceptions.isEmpty()) { + throw new BundleResolveException("Unable to resolve all runtime bundles", resolveExceptions); + } + } + + private ReturnStatus checkCurrentJarVersions(String[] jarVersions) { + computeRunningJarVersions(); + if (this.currentJarVersions == null) { + return new ReturnStatus("No jar's currently loaded", false); + } + List<String> nonMatchingVersions = new ArrayList<String>(); + for (String version : jarVersions) { + if (Arrays.binarySearch(this.currentJarVersions, version) < 0) { + nonMatchingVersions.add(version); + } + } + if (nonMatchingVersions.size() > 0) { + return new ReturnStatus( + String.format( + "Bundle versions [%s] were not found in the currently configured environment that is running with [%s].", + Arrays.deepToString(nonMatchingVersions.toArray()), Arrays.deepToString(currentJarVersions)), + false); + } + return new ReturnStatus(String.format("Jar Versions [%s] are already loaded.", Arrays.deepToString(jarVersions)), + true); + } + + private void computeRunningJarVersions() { + List<String> versions = new ArrayList<String>(); + for (Bundle bundle : runningBundles) { + String versionStr = + OteUtil.generateBundleVersionString((String) bundle.getHeaders().get("Implementation-Version"), + bundle.getSymbolicName(), (String) bundle.getHeaders().get("Bundle-Version"), + bundleNameToMd5Map.get(bundle.getSymbolicName())); + versions.add(versionStr); + } + if (versions.size() > 0) { + currentJarVersions = versions.toArray(new String[versions.size()]); + Arrays.sort(currentJarVersions); + } + } + + public ReturnStatus isRunningJarVersions(String[] versions) { + return checkCurrentJarVersions(versions); + } + + public void addJarToClassLoader(byte[] jarData) throws IOException { + File dir = getJarCache(); + File jar = File.createTempFile("runtimeLibrary_", ".jar", dir); + Lib.writeBytesToFile(jarData, jar); + availableJars.put(Lib.getJarFileVersion(jar.getAbsolutePath()), jar); + } + + public void resetScriptLoader(String[] classPaths) throws Exception { + cleanUpNeeded = true; + initClassloadersWithNoURLs(); + if (scriptClassLoader == null) { + throw new IllegalStateException("Script Class Loader not yet created"); + } + if (scriptClassLoader != null) { + // TODO do we need some cleanup here + } + scriptClassLoader = + new OseeURLClassLoader("Script ClassLoader", Lib.getUrlFromString(classPaths), this.runtimeLibraryLoader); + } + + public Class<?> loadFromScriptClassLoader(String path) throws ClassNotFoundException { + cleanUpNeeded = true; + initClassloadersWithNoURLs(); + if (scriptClassLoader == null) { + throw new IllegalStateException("Script Class Loader not yet created"); + } + Class<?> scriptClass = scriptClassLoader.loadClass(path); + GCHelper.getGCHelper().addRefWatch(scriptClass); + return scriptClass; + } + + public Class<?> loadFromRuntimeLibraryLoader(String path) throws ClassNotFoundException { + cleanUpNeeded = true; + initClassloadersWithNoURLs(); + if (runtimeLibraryLoader == null) { + throw new IllegalStateException("The message/runtime library loader has not been configured"); + } + Class<?> clazz = runtimeLibraryLoader.loadClass(path); + GCHelper.getGCHelper().addRefWatch(clazz); + return clazz; + } + + public void cleanup() { + if (!cleanUpNeeded) { + return; + } + cleanUpNeeded = false; + if (runtimeLibraryLoader != null) { + try { + onRuntimeUnloaded(); + } catch (Throwable th) { + OseeLog.log(AbstractRuntimeManager.class, Level.SEVERE, th); + } + } + + for (Bundle bundle : installedBundles) { + try { + bundle.uninstall(); + } catch (BundleException ex) { + OseeLog.log(AbstractRuntimeManager.class, Level.SEVERE, ex); + } + } + installedBundles.clear(); + + for (Bundle bundle : runningBundles) { + try { + bundle.stop(); + bundle.uninstall(); + } catch (BundleException ex) { + OseeLog.log(AbstractRuntimeManager.class, Level.SEVERE, ex); + } + } + runningBundles.clear(); + bundleNameToMd5Map.clear(); + if (packageAdmin != null) { + packageAdmin.refreshPackages(null); + } + + runtimeLibraryLoader = null; + scriptClassLoader = null; + availableJars.clear(); + } + + protected File getAvailableJar(String version) { + return availableJars.get(version); + } + + public Element toXml(Document doc) { + Element el = doc.createElement("RuntimeVersions"); + + if (currentJarVersions != null) { + for (String version : currentJarVersions) { + Element versionEl = doc.createElement("Version"); + versionEl.appendChild(doc.createTextNode(version)); + el.appendChild(versionEl); + } + } + for (Bundle bundle : runningBundles) { + String version = (String) bundle.getHeaders().get("Bundle-Version"); + if (version != null) { + Element versionEl = doc.createElement("Version"); + versionEl.appendChild(doc.createTextNode(bundle.getSymbolicName() + version)); + el.appendChild(versionEl); + } + String implVersion = (String) bundle.getHeaders().get("Implementation-Version"); + if (implVersion != null) { + Element versionEl = doc.createElement("Version"); + versionEl.appendChild(doc.createTextNode(bundle.getSymbolicName() + implVersion)); + el.appendChild(versionEl); + } + } + return el; + } + + public void addRuntimeLibraryListener(RuntimeLibraryListener listener) { + listeners.add(listener); + } + + public void removeRuntimeLibraryListener(RuntimeLibraryListener listener) { + listeners.remove(listener); + } + +} diff --git a/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/environment/interfaces/IHostTestEnvironment.java b/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/environment/interfaces/IHostTestEnvironment.java index 9bbdd2eec3b..9f9aae6d1c7 100644 --- a/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/environment/interfaces/IHostTestEnvironment.java +++ b/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/environment/interfaces/IHostTestEnvironment.java @@ -12,10 +12,11 @@ package org.eclipse.osee.ote.core.environment.interfaces; import java.rmi.Remote; import java.rmi.RemoteException; - +import java.util.Collection; import org.eclipse.osee.framework.jdk.core.util.EnhancedProperties; import org.eclipse.osee.ote.core.ConnectionRequestResult; import org.eclipse.osee.ote.core.IRemoteUserSession; +import org.eclipse.osee.ote.core.environment.BundleDescription; import org.eclipse.osee.ote.core.environment.TestEnvironmentConfig; /**
@@ -28,5 +29,14 @@ public interface IHostTestEnvironment extends Remote { ConnectionRequestResult requestEnvironment(IRemoteUserSession session, TestEnvironmentConfig config) throws RemoteException;
- EnhancedProperties getProperties() throws RemoteException;
+ EnhancedProperties getProperties() throws RemoteException; + + boolean isBundleAvailable(String symbolicName, String version, byte[] md5Digest) throws RemoteException; + + void sendRuntimeBundle(Collection<BundleDescription> bundles) throws RemoteException; + + void updateRuntimeBundle(Collection<BundleDescription> bundles) throws RemoteException; + + void cleanupRuntimeBundles() throws RemoteException; +
}
diff --git a/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/environment/interfaces/OteUtil.java b/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/environment/interfaces/OteUtil.java new file mode 100644 index 00000000000..0de29bd13ad --- /dev/null +++ b/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/environment/interfaces/OteUtil.java @@ -0,0 +1,19 @@ +package org.eclipse.osee.ote.core.environment.interfaces;
+public class OteUtil {
+
+ public static String generateBundleVersionString(String bundleSpecificVersion, String symbolicName, String version, byte[] md5){
+ StringBuilder sb = new StringBuilder();
+ if(bundleSpecificVersion != null){
+ sb.append(bundleSpecificVersion);
+ sb.append("_");
+ }
+ sb.append(symbolicName);
+ sb.append("_");
+ sb.append(version);
+ sb.append("_");
+ for(byte b:md5){
+ sb.append(String.format("%X", b));
+ }
+ return sb.toString();
+ }
+}
\ No newline at end of file diff --git a/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/environment/interfaces/RuntimeManagerHandler.java b/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/environment/interfaces/RuntimeManagerHandler.java new file mode 100644 index 00000000000..c4229c39ec4 --- /dev/null +++ b/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/environment/interfaces/RuntimeManagerHandler.java @@ -0,0 +1,39 @@ +/*
+ * Created on Mar 18, 2010
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ote.core.environment.interfaces;
+
+import java.util.Map;
+import org.eclipse.osee.framework.core.util.AbstractTrackingHandler;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+/**
+ * @author b1528444
+ *
+ */
+public class RuntimeManagerHandler extends AbstractTrackingHandler {
+ private final static Class<?>[] SERVICE_DEPENDENCIES =
+ new Class<?>[] {PackageAdmin.class};
+ private ServiceRegistration serviceRegistration;
+
+ @Override
+ public Class<?>[] getDependencies() {
+ return SERVICE_DEPENDENCIES;
+ }
+
+ @Override
+ public void onActivate(BundleContext context, Map<Class<?>, Object> services) {
+ PackageAdmin packageAdmin = getService(PackageAdmin.class, services);
+ AbstractRuntimeManager runtimeManager = new AbstractRuntimeManager(packageAdmin, context);
+ serviceRegistration = context.registerService(IRuntimeLibraryManager.class.getName(), runtimeManager, null);
+ }
+
+ @Override
+ public void onDeActivate() {
+ serviceRegistration.unregister();
+ }
+}
diff --git a/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/framework/command/BaseCommandManager.java b/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/framework/command/BaseCommandManager.java index 24bcc0f2558..3091109d687 100644 --- a/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/framework/command/BaseCommandManager.java +++ b/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/framework/command/BaseCommandManager.java @@ -18,6 +18,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; import org.eclipse.osee.ote.core.environment.TestEnvironment; import org.eclipse.osee.ote.core.framework.thread.OteThreadManager; +import org.eclipse.osee.ote.core.internal.Activator; public class BaseCommandManager implements ICommandManager { @@ -33,7 +34,7 @@ public class BaseCommandManager implements ICommandManager { } public ICommandHandle addCommand(ITestServerCommand cmd, TestEnvironment context) throws ExportException { - Future<ITestCommandResult> result = commands.submit(new TestCallableWrapper(this, cmd, context)); + Future<ITestCommandResult> result = commands.submit(new TestCallableWrapper(this, cmd, context, Activator.getInstance().getOteStatusBoard())); cmdMap.put(cmd, result); return cmd.createCommandHandle(result, context); } diff --git a/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/framework/command/ITestServerCommand.java b/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/framework/command/ITestServerCommand.java index d1507092650..05ada01254d 100644 --- a/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/framework/command/ITestServerCommand.java +++ b/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/framework/command/ITestServerCommand.java @@ -14,6 +14,7 @@ import java.rmi.server.ExportException; import java.util.concurrent.Future; import org.eclipse.osee.ote.core.environment.TestEnvironment; import org.eclipse.osee.ote.core.environment.UserTestSessionKey; +import org.eclipse.osee.ote.core.environment.status.OTEStatusBoard; public interface ITestServerCommand { @@ -21,7 +22,7 @@ public interface ITestServerCommand { ICommandHandle createCommandHandle(Future<ITestCommandResult> result, ITestContext context) throws ExportException; - ITestCommandResult execute(TestEnvironment context) throws Exception; + ITestCommandResult execute(TestEnvironment context, OTEStatusBoard statusBoard) throws Exception; String getGUID(); } diff --git a/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/framework/command/TestCallableWrapper.java b/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/framework/command/TestCallableWrapper.java index ef057e81cd5..159a4c46992 100644 --- a/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/framework/command/TestCallableWrapper.java +++ b/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/framework/command/TestCallableWrapper.java @@ -14,25 +14,27 @@ import java.util.concurrent.Callable; import java.util.logging.Level; import org.eclipse.osee.framework.logging.OseeLog; import org.eclipse.osee.ote.core.environment.TestEnvironment; +import org.eclipse.osee.ote.core.environment.status.OTEStatusBoard; public class TestCallableWrapper implements Callable<ITestCommandResult> { - private ITestServerCommand cmd; - private TestEnvironment context; - private BaseCommandManager cmdManager; + private final ITestServerCommand cmd; + private final TestEnvironment context; + private final BaseCommandManager cmdManager; + private final OTEStatusBoard statusBoard; - - public TestCallableWrapper( BaseCommandManager cmdManager, ITestServerCommand cmd, TestEnvironment context) { + public TestCallableWrapper( BaseCommandManager cmdManager, ITestServerCommand cmd, TestEnvironment context, OTEStatusBoard statusBoard) { this.cmd = cmd; this.context = context; this.cmdManager = cmdManager; + this.statusBoard = statusBoard; } public ITestCommandResult call() throws Exception { ITestCommandResult result; try{ context.setActiveUser(cmd.getUserSessionKey()); - result = cmd.execute(context); + result = cmd.execute(context, statusBoard); if(result.getThrowable() != null){ OseeLog.log(TestCallableWrapper.class, Level.SEVERE, result.getThrowable()); } diff --git a/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/internal/Activator.java b/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/internal/Activator.java index 9d1424b7b5c..b53d30aabf9 100644 --- a/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/internal/Activator.java +++ b/plugins/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/internal/Activator.java @@ -52,7 +52,7 @@ public class Activator implements BundleActivator, RuntimeLibraryListener { private StandardShell stdShell; private ServiceRegistration consoleCommandRegistration; private ServiceRegistration commandDistributerRegistration; - + public void start(BundleContext context) throws Exception { activator = this; statusBoard = new StatusBoard(); @@ -69,6 +69,9 @@ public class Activator implements BundleActivator, RuntimeLibraryListener { commandDistributer = new CommandDistributerImpl(); commandDistributerRegistration = context.registerService(CommandDistributer.class.getName(), commandDistributer, new Hashtable()); + + + } public void stop(BundleContext context) throws Exception { |