You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by tb...@apache.org on 2015/05/26 19:02:35 UTC
ambari git commit: AMBARI-11208 - Views : expose extra classpath
setting (tbeerbower)
Repository: ambari
Updated Branches:
refs/heads/trunk 2302764c3 -> 591ab4810
AMBARI-11208 - Views : expose extra classpath setting (tbeerbower)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/591ab481
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/591ab481
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/591ab481
Branch: refs/heads/trunk
Commit: 591ab48101065da7561115391b747991d4e47d2d
Parents: 2302764
Author: tbeerbower <tb...@hortonworks.com>
Authored: Tue May 26 13:01:05 2015 -0400
Committer: tbeerbower <tb...@hortonworks.com>
Committed: Tue May 26 13:01:14 2015 -0400
----------------------------------------------------------------------
.../ambari/server/view/ViewClassLoader.java | 29 +++++++++++++-------
.../ambari/server/view/ViewExtractor.java | 13 +++++----
.../server/view/configuration/ViewConfig.java | 18 ++++++++++++
.../ambari/server/view/ViewClassLoaderTest.java | 16 +++++++----
.../ambari/server/view/ViewRegistryTest.java | 12 ++++----
.../view/configuration/ViewConfigTest.java | 21 ++++++++++++++
ambari-views/src/main/resources/view.xsd | 18 +++++++++++-
7 files changed, 99 insertions(+), 28 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/591ab481/ambari-server/src/main/java/org/apache/ambari/server/view/ViewClassLoader.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewClassLoader.java b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewClassLoader.java
index b7cb594..f339b9a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewClassLoader.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewClassLoader.java
@@ -18,6 +18,7 @@
package org.apache.ambari.server.view;
+import org.apache.ambari.server.view.configuration.ViewConfig;
import org.eclipse.jetty.webapp.WebAppClassLoader;
import org.eclipse.jetty.webapp.WebAppContext;
@@ -38,10 +39,11 @@ public class ViewClassLoader extends WebAppClassLoader {
* The URLs will be searched in the order specified for classes and resources before searching
* the parent class loader.
*
- * @param urls the URLs from which to load classes and resources
+ * @param viewConfig the view configuration
+ * @param urls the URLs from which to load classes and resources
*/
- public ViewClassLoader(URL[] urls) throws IOException {
- this(null, urls);
+ public ViewClassLoader(ViewConfig viewConfig, URL[] urls) throws IOException {
+ this(viewConfig, null, urls);
}
/**
@@ -49,11 +51,12 @@ public class ViewClassLoader extends WebAppClassLoader {
* The URLs will be searched in the order specified for classes and resources before searching the specified
* parent class loader.
*
- * @param parent the parent class loader
- * @param urls the URLs from which to load classes and resources
+ * @param viewConfig the view configuration
+ * @param parent the parent class loader
+ * @param urls the URLs from which to load classes and resources
*/
- public ViewClassLoader(ClassLoader parent, URL[] urls) throws IOException {
- super(parent, getInitContext());
+ public ViewClassLoader(ViewConfig viewConfig, ClassLoader parent, URL[] urls) throws IOException {
+ super(parent, getInitContext(viewConfig));
for (URL url : urls) {
addURL(url);
@@ -64,9 +67,8 @@ public class ViewClassLoader extends WebAppClassLoader {
// ----- helper methods ----------------------------------------------------
// Get a context to initialize the class loader.
- private static WebAppContext getInitContext() {
- // For now we are using defaults or setting the values for things like parent loader priority and
- // system classes. In the future we may allow overrides at the view level.
+ private static WebAppContext getInitContext(ViewConfig viewConfig) {
+
WebAppContext webAppContext = new WebAppContext();
// add com.google.inject as system classes to allow for injection in view components using the google annotation
@@ -74,6 +76,13 @@ public class ViewClassLoader extends WebAppClassLoader {
// add org.slf4j as system classes to avoid linkage errors
webAppContext.addSystemClass("org.slf4j.");
+ // set the class loader settings from the configuration
+ if (viewConfig != null) {
+ String extraClasspath = viewConfig.getExtraClasspath();
+ if (extraClasspath != null) {
+ webAppContext.setExtraClasspath(extraClasspath);
+ }
+ }
return webAppContext;
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/591ab481/ambari-server/src/main/java/org/apache/ambari/server/view/ViewExtractor.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewExtractor.java b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewExtractor.java
index 43efc7d..3350726 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewExtractor.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewExtractor.java
@@ -19,6 +19,7 @@
package org.apache.ambari.server.view;
import org.apache.ambari.server.orm.entities.ViewEntity;
+import org.apache.ambari.server.view.configuration.ViewConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -26,7 +27,6 @@ import javax.inject.Inject;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
-import java.net.MalformedURLException;
import java.net.URL;
import java.util.LinkedList;
import java.util.List;
@@ -151,7 +151,10 @@ public class ViewExtractor {
throw new ExtractionException(msg);
}
}
- return getArchiveClassLoader(archiveDir);
+
+ ViewConfig viewConfig = archiveUtility.getViewConfigFromExtractedArchive(archivePath, false);
+
+ return getArchiveClassLoader(viewConfig, archiveDir);
} catch (Exception e) {
String msg = "Caught exception trying to extract the view archive " + archivePath + ".";
@@ -180,8 +183,8 @@ public class ViewExtractor {
// ----- archiveUtility methods ----------------------------------------------------
// get a class loader for the given archive directory
- private ClassLoader getArchiveClassLoader(File archiveDir)
- throws MalformedURLException, IOException {
+ private ClassLoader getArchiveClassLoader(ViewConfig viewConfig, File archiveDir)
+ throws IOException {
String archivePath = archiveDir.getAbsolutePath();
List<URL> urlList = new LinkedList<URL>();
@@ -210,7 +213,7 @@ public class ViewExtractor {
// include the archive directory
urlList.add(archiveDir.toURI().toURL());
- return new ViewClassLoader(urlList.toArray(new URL[urlList.size()]));
+ return new ViewClassLoader(viewConfig, urlList.toArray(new URL[urlList.size()]));
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/591ab481/ambari-server/src/main/java/org/apache/ambari/server/view/configuration/ViewConfig.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/configuration/ViewConfig.java b/ambari-server/src/main/java/org/apache/ambari/server/view/configuration/ViewConfig.java
index 6164bb7..f9b898d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/view/configuration/ViewConfig.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/configuration/ViewConfig.java
@@ -27,6 +27,7 @@ import org.apache.commons.lang.StringUtils;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.Collections;
@@ -86,6 +87,13 @@ public class ViewConfig {
private boolean system;
/**
+ * The list of extra classpath elements.
+ */
+ @XmlElementWrapper
+ @XmlElement(name="path")
+ private List<String> classpath;
+
+ /**
* The main view class name.
*/
@XmlElement(name="view-class")
@@ -236,6 +244,16 @@ public class ViewConfig {
}
/**
+ * Get the extra classpath as a comma separated path of filenames or URLs pointing to
+ * directories or jar files.
+ *
+ * @return the extra classpath
+ */
+ public String getExtraClasspath() {
+ return classpath == null ? null : StringUtils.join(classpath, ",");
+ }
+
+ /**
* Get the view class name.
*
* @return the view class name
http://git-wip-us.apache.org/repos/asf/ambari/blob/591ab481/ambari-server/src/test/java/org/apache/ambari/server/view/ViewClassLoaderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/view/ViewClassLoaderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewClassLoaderTest.java
index 8e22c49..ed701fd 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/view/ViewClassLoaderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewClassLoaderTest.java
@@ -19,12 +19,14 @@
package org.apache.ambari.server.view;
import junit.framework.Assert;
+import org.apache.ambari.server.view.configuration.ViewConfig;
import org.junit.Test;
import java.io.File;
import java.net.URL;
import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
@@ -38,17 +40,18 @@ public class ViewClassLoaderTest {
public void testGetResource() throws Exception {
ClassLoader parentClassLoader = createMock(ClassLoader.class);
URL parentResource = new File("parent-resource").toURI().toURL();
+ ViewConfig viewConfig = createNiceMock(ViewConfig.class);
expect(parentClassLoader.getResource("parent-resource")).andReturn(parentResource).once();
- replay(parentClassLoader);
+ replay(parentClassLoader, viewConfig);
File file = new File("./src/test/resources");
URL testURL = file.toURI().toURL();
URL[] urls = new URL[]{testURL};
- ViewClassLoader classLoader = new ViewClassLoader(parentClassLoader, urls);
+ ViewClassLoader classLoader = new ViewClassLoader(viewConfig, parentClassLoader, urls);
URL url = classLoader.getResource("ambari.properties");
@@ -59,13 +62,14 @@ public class ViewClassLoaderTest {
Assert.assertNotNull(url);
Assert.assertSame(parentResource, url);
- verify(parentClassLoader);
+ verify(parentClassLoader, viewConfig);
}
@Test
public void testLoadClass() throws Exception {
TestClassLoader parentClassLoader = createMock(TestClassLoader.class);
Class parentClass = Object.class;
+ ViewConfig viewConfig = createNiceMock(ViewConfig.class);
expect(parentClassLoader.getPackage("org.apache.ambari.server.view")).andReturn(null).anyTimes();
expect(parentClassLoader.loadClass("java.lang.Object")).andReturn(parentClass).anyTimes();
@@ -74,14 +78,14 @@ public class ViewClassLoaderTest {
expect(parentClassLoader.loadClass("com.google.inject.AbstractModule")).andReturn(parentClass).once();
expect(parentClassLoader.loadClass("org.slf4j.LoggerFactory")).andReturn(parentClass).once();
- replay(parentClassLoader);
+ replay(parentClassLoader, viewConfig);
File file = new File("./target/test-classes");
URL testURL = file.toURI().toURL();
URL[] urls = new URL[]{testURL};
- ViewClassLoader classLoader = new ViewClassLoader(parentClassLoader, urls);
+ ViewClassLoader classLoader = new ViewClassLoader(viewConfig, parentClassLoader, urls);
Class clazz = classLoader.loadClass("org.apache.ambari.server.view.ViewClassLoaderTest");
@@ -110,7 +114,7 @@ public class ViewClassLoaderTest {
Assert.assertNotNull(clazz);
Assert.assertSame(parentClass, clazz);
- verify(parentClassLoader);
+ verify(parentClassLoader, viewConfig);
}
public class TestClassLoader extends ClassLoader {
http://git-wip-us.apache.org/repos/asf/ambari/blob/591ab481/ambari-server/src/test/java/org/apache/ambari/server/view/ViewRegistryTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/view/ViewRegistryTest.java b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewRegistryTest.java
index a0ee6b3..c66a9ce 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/view/ViewRegistryTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewRegistryTest.java
@@ -493,26 +493,26 @@ public class ViewRegistryTest {
jarFiles.put(viewArchive, viewJarFile);
// set expectations
- expect(configuration.getViewsDir()).andReturn(viewDir);
+ expect(configuration.getViewsDir()).andReturn(viewDir).anyTimes();
if (System.getProperty("os.name").contains("Windows")) {
- expect(viewDir.getAbsolutePath()).andReturn("\\var\\lib\\ambari-server\\resources\\views");
+ expect(viewDir.getAbsolutePath()).andReturn("\\var\\lib\\ambari-server\\resources\\views").anyTimes();
}
else {
- expect(viewDir.getAbsolutePath()).andReturn("/var/lib/ambari-server/resources/views");
+ expect(viewDir.getAbsolutePath()).andReturn("/var/lib/ambari-server/resources/views").anyTimes();
}
expect(configuration.getViewExtractionThreadPoolCoreSize()).andReturn(2).anyTimes();
expect(configuration.getViewExtractionThreadPoolMaxSize()).andReturn(3).anyTimes();
expect(configuration.getViewExtractionThreadPoolTimeout()).andReturn(10000L).anyTimes();
- expect(viewDir.listFiles()).andReturn(new File[]{viewArchive});
+ expect(viewDir.listFiles()).andReturn(new File[]{viewArchive}).anyTimes();
expect(viewArchive.isDirectory()).andReturn(false);
if (System.getProperty("os.name").contains("Windows")) {
- expect(viewArchive.getAbsolutePath()).andReturn("\\var\\lib\\ambari-server\\resources\\views\\work\\MY_VIEW{1.0.0}");
+ expect(viewArchive.getAbsolutePath()).andReturn("\\var\\lib\\ambari-server\\resources\\views\\work\\MY_VIEW{1.0.0}").anyTimes();
}
else {
- expect(viewArchive.getAbsolutePath()).andReturn("/var/lib/ambari-server/resources/views/work/MY_VIEW{1.0.0}");
+ expect(viewArchive.getAbsolutePath()).andReturn("/var/lib/ambari-server/resources/views/work/MY_VIEW{1.0.0}").anyTimes();
}
expect(archiveDir.exists()).andReturn(false);
http://git-wip-us.apache.org/repos/asf/ambari/blob/591ab481/ambari-server/src/test/java/org/apache/ambari/server/view/configuration/ViewConfigTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/view/configuration/ViewConfigTest.java b/ambari-server/src/test/java/org/apache/ambari/server/view/configuration/ViewConfigTest.java
index beb8bde..2391ad6 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/view/configuration/ViewConfigTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/view/configuration/ViewConfigTest.java
@@ -165,6 +165,16 @@ public class ViewConfigTest {
" <max-ambari-version>2.0.0</max-ambari-version>\n" +
"</view>";
+ private static String EXTRA_CLASSPATH_XML = "<view>\n" +
+ " <name>MY_VIEW</name>\n" +
+ " <label>My View!</label>\n" +
+ " <version>1.0.0</version>\n" +
+ " <classpath>" +
+ " <path>/var/lib/</path>" +
+ " <path>/tmp/foo.jar</path>" +
+ " </classpath>\n" +
+ "</view>";
+
@Test
public void testGetName() throws Exception {
ViewConfig config = getConfig();
@@ -281,6 +291,17 @@ public class ViewConfigTest {
}
@Test
+ public void testGetExtraClasspath() throws Exception {
+ ViewConfig config = getConfig(system_xml);
+
+ Assert.assertNull(config.getExtraClasspath());
+
+ config = getConfig(EXTRA_CLASSPATH_XML);
+
+ Assert.assertEquals("/var/lib/,/tmp/foo.jar", config.getExtraClasspath());
+ }
+
+ @Test
public void testGetMinAmbariVersion() throws Exception {
ViewConfig config = getConfig();
Assert.assertNull(config.getMinAmbariVersion());
http://git-wip-us.apache.org/repos/asf/ambari/blob/591ab481/ambari-views/src/main/resources/view.xsd
----------------------------------------------------------------------
diff --git a/ambari-views/src/main/resources/view.xsd b/ambari-views/src/main/resources/view.xsd
index 37737c1..46adf27 100644
--- a/ambari-views/src/main/resources/view.xsd
+++ b/ambari-views/src/main/resources/view.xsd
@@ -250,7 +250,18 @@
</xs:extension>
</xs:complexContent>
</xs:complexType>
-
+ <xs:complexType name="PathType">
+ <xs:annotation>
+ <xs:documentation>Defines a single classpath.</xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element type="xs:string" name="path" minOccurs="0" maxOccurs="unbounded">
+ <xs:annotation>
+ <xs:documentation>The path of a filename or URL pointing to a directory or jar file. A directory path should end with '/'.</xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
<xs:element name="view">
<xs:annotation>
<xs:documentation>Defines a view.</xs:documentation>
@@ -306,6 +317,11 @@
<xs:documentation>Indicates whether or not this is a system view.</xs:documentation>
</xs:annotation>
</xs:element>
+ <xs:element type="PathType" name="classpath" minOccurs="0" maxOccurs="1">
+ <xs:annotation>
+ <xs:documentation>Extra class path entries for this view. A directory path should end with '/'.</xs:documentation>
+ </xs:annotation>
+ </xs:element>
<xs:element type="xs:string" name="view-class" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>The View class to receive framework events.</xs:documentation>