blob: 6163b97e14285ad28caba65dca246357442beabe [file] [log] [blame]
/*
* Copyright (c) 2020 Kentyou.
* 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:
* Kentyou - initial API and implementation
*/
package org.eclipse.sensinact.gateway.core.security.test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
public class MidOSGiTest implements BundleContextProvider {
protected static final String HTTP_ROOTURL = "http://localhost:8091/sensinact";
protected static final String WS_ROOTURL = "/sensinact";
private static final String AUTO_PROCESSOR = "org.apache.felix.main.AutoProcessor";
private static final String FELIX_FRAMEWORK = "org.osgi.framework.launch.Framework";
private static final String FELIX_FRAMEWORK_FACTORY = "org.apache.felix.framework.FrameworkFactory";
private static final String BUNDLE = "org.osgi.framework.Bundle";
private static final String BUNDLE_GET_CONTEXT = "getBundleContext";
private static final String BUNDLE_STATE = "getState";
private static final String FRAMEWORK_INIT = "init";
private static final String FRAMEWORK_START = "start";
private static final String FRAMEWORK_STOP = "stop";
private static final String FRAMEWORK_FACTORY_INIT_FRAMEWORK = "newFramework";
private static final Class<?>[] FRAMEWORK_FACTORY_INIT_FRAMEWORK_TYPES = new Class<?>[] { Map.class };
protected final FilterOSGiClassLoader classloader;
private final ClassLoader current;
private Object felix;
private Class<?> frameworkClass;
BundleContext context;
public MidOSGiTest() throws MalformedURLException, IOException {
String directoryName = "./target/felix/load";
File theDir = new File(directoryName);
// if the directory does not exist, create it
if (!theDir.exists()) {
// System.out.println("creating directory: " + directoryName);
try {
theDir.mkdir();
} catch (SecurityException se) {
}
}
System.setProperty("java.security.policy", "src/test/resources/all.policy");
File manifestFile = new File("./src/test/resources/MANIFEST.MF");
this.createDynamicBundle(manifestFile, theDir,
new File[] { new File("./target/classes"), new File("./src/main/resources") });
this.current = Thread.currentThread().getContextClassLoader();
this.classloader = new FilterOSGiClassLoader(current, this,
new URL[] { new URL("file:target/felix/bundle/sensinact-felix-security.jar"),
new URL("file:target/felix/bundle/sensinact-utils.jar"),
new URL("file:target/felix/bundle/sensinact-datastore-api.jar"),
new URL("file:target/felix/bundle/sensinact-core.jar"),
new URL("file:target/felix/bundle/sensinact-generic.jar"),
new URL("file:target/felix/bundle/http.jar"),
new URL("file:target/felix/bundle/org.apache.felix.fileinstall.jar"),
new URL("file:target/felix/bundle/org.osgi.compendium.jar"),
new URL("file:target/felix/bundle/org.apache.felix.configadmin.jar"),
new URL("file:target/felix/bundle/sensinact-northbound-access.jar"),
new URL("file:target/felix/bundle/javax.servlet-api.jar"),
new URL("file:target/felix/bundle/org.apache.felix.http.api.jar"),
new URL("file:target/felix/bundle/org.apache.felix.http.jetty.jar"),
new URL("file:target/felix/bundle/slider.jar"), new URL("file:target/felix/bundle/light.jar"),
new URL("file:target/felix/load/dynamicBundle.jar") });
}
/**
* Creates a new <code>JarInputStream</code> and reads the optional manifest. If
* a manifest is present and verify is true, also attempts to verify the
* signatures if the JarInputStream is signed.
*
* @param in
* the actual input stream
* @param verify
* whether or not to verify the JarInputStream if it is signed.
* @exception IOException
* if an I/O error has occurred
*/
public void createDynamicBundle(File manifestFile, File destDirectory, File... sourceDirectories)
throws IOException {
if (!destDirectory.exists()) {
return;
}
// Assume all necessary imports and variables are declared
FileOutputStream fOut = new FileOutputStream(new File(destDirectory, "dynamicBundle.jar"));
Manifest manifest = new Manifest(new FileInputStream(manifestFile));
// Create a buffer for reading the files
byte[] buf = new byte[1024];
JarOutputStream jarOut = new JarOutputStream(fOut, manifest);
FileInputStream reader = null;
int index = 0;
int length = sourceDirectories == null ? 0 : sourceDirectories.length;
for (; index < length; index++) {
File sourceDirectory = sourceDirectories[index];
if (!sourceDirectory.isDirectory()) {
continue;
}
FilesEnumerator enumerator = new FilesEnumerator(sourceDirectory);
while (enumerator.hasMoreElements()) {
File file = enumerator.nextElement();
if (file.isFile()) {
jarOut.putNextEntry(new ZipEntry(
file.getAbsolutePath().substring(sourceDirectory.getAbsolutePath().length() + 1)));
reader = new FileInputStream(file);
int len;
while ((len = reader.read(buf)) > 0) {
jarOut.write(buf, 0, len);
}
// Complete the entry
reader.close();
jarOut.closeEntry();
}
}
}
jarOut.close();
}
/**
* @inheritDoc
*
* @see org.eclipse.sensinact.gateway.nthbnd.rest.BundleContextProvider#getBundleContext()
*/
@Override
public BundleContext getBundleContext() {
return this.context;
}
@After
public void tearDown() throws Exception {
frameworkClass.getDeclaredMethod(FRAMEWORK_STOP).invoke(felix);
felix = null;
}
@SuppressWarnings({ "unchecked", "rawtypes", "serial" })
@Before
public void init() throws Exception {
Thread.currentThread().setContextClassLoader(classloader);
Map configuration = new HashMap();
configuration.put("felix.cache.rootdir", "./target/felix");
configuration.put("org.osgi.framework.storage", "felix-cache");
configuration.put("org.osgi.framework.bootdelegation", "*");
configuration.put("org.osgi.framework.system.packages.extra",
"org.eclipse.sensinact.gateway.core.security.condperm," + "com.sun.net.httpserver," + "javax.net.ssl,"
+ "javax.xml.parsers," + "javax.imageio," + "javax.management," + "javax.naming," + "javax.sql,"
+ "javax.swing," + "javax.swing.border," + "javax.swing.event," + "javax.management.modelmbean,"
+ "javax.management.remote," + "javax.security.auth," + "javax.security.cert," + "org.w3c.dom,"
+ "org.xml.sax," + "org.xml.sax.helpers," + "sun.misc," + "sun.security.action");
configuration.put("org.osgi.framework.storage.clean", "onFirstInit");
configuration.put("felix.cache.rootdir", "target/felix");
configuration.put("felix.auto.deploy.action", "install,start");
configuration.put("felix.log.level", "4");
configuration.put("felix.fileinstall.dir", "./load");
configuration.put("felix.fileinstall.bundles.new.start", "true");
if (System.getSecurityManager() == null) {
configuration.put("org.osgi.framework.security", "osgi");
}
configuration.put("felix.auto.start.1",
"file:target/felix/bundle/org.apache.felix.configadmin.jar "
+ "file:target/felix/bundle/org.osgi.compendium.jar "
+ "file:target/felix/bundle/sensinact-felix-security.jar "
+ "file:target/felix/bundle/sensinact-utils.jar "
+ "file:target/felix/bundle/sensinact-datastore-api.jar "
+ "file:target/felix/bundle/org.apache.felix.fileinstall.jar ");
configuration.put("felix.auto.start.2",
"file:target/felix/bundle/sensinact-core.jar " + "file:target/felix/bundle/sensinact-generic.jar");
configuration.put("felix.auto.start.3", "file:target/felix/bundle/javax.servlet-api.jar "
+ "file:target/felix/bundle/org.apache.felix.http.api.jar "
+ "file:target/felix/bundle/org.apache.felix.http.jetty.jar " + "file:target/felix/bundle/http.jar "
+ "file:target/felix/bundle/sensinact-northbound-access.jar");
configuration.put("felix.auto.start.4",
"file:target/felix/bundle/slider.jar " + "file:target/felix/bundle/light.jar ");
configuration.put("org.osgi.framework.startlevel.beginning", "5");
configuration.put("felix.startlevel.bundle", "5");
configuration.put("org.osgi.service.http.port", "8091");
configuration.put("org.apache.felix.http.jettyEnabled", "true");
configuration.put("org.apache.felix.http.whiteboardEnabled", "true");
configuration.put("org.eclipse.sensinact.simulated.gui.enabled", "false");
configuration.put("felix.bootdelegation.classloaders", new HashMap() {
public Object get(Object key) {
if (Bundle.class.isAssignableFrom(key.getClass())) {
return classloader;
}
return super.get(key);
}
});
Class<?> factoryClass = classloader.loadClass(FELIX_FRAMEWORK_FACTORY);
Object factory = factoryClass.newInstance();
felix = factoryClass.getDeclaredMethod(FRAMEWORK_FACTORY_INIT_FRAMEWORK, FRAMEWORK_FACTORY_INIT_FRAMEWORK_TYPES)
.invoke(factory, new Object[] { configuration });
frameworkClass = classloader.loadClass(FELIX_FRAMEWORK);
Class<?> bundleClass = classloader.loadClass(BUNDLE);
frameworkClass.getDeclaredMethod(FRAMEWORK_INIT).invoke(felix);
context = (BundleContext) bundleClass.getDeclaredMethod(BUNDLE_GET_CONTEXT).invoke(felix);
Class<?> autoProcessorClass = classloader.loadClass(AUTO_PROCESSOR);
autoProcessorClass.getDeclaredMethod("process", new Class<?>[] { Map.class, BundleContext.class }).invoke(null,
new Object[] { configuration, context });
frameworkClass.getDeclaredMethod(FRAMEWORK_START).invoke(felix);
Assert.assertTrue(bundleClass == Bundle.class);
Assert.assertTrue(((Integer) bundleClass.getDeclaredMethod(BUNDLE_STATE).invoke(felix)) == Bundle.ACTIVE);
Object httpService = context
.getService(context.getServiceReferences("org.apache.felix.http.api.ExtHttpService", null)[0]);
Assert.assertTrue(httpService != null);
Bundle bundle = context
.installBundle("file:" + new File("target/felix/load/dynamicBundle.jar").getAbsolutePath());
bundle.start();
Thread.currentThread().setContextClassLoader(current);
}
}