소스 검색

AMBARI-784. Add Resource download API on the server. (mahadev)

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/branches/AMBARI-666@1392745 13f79535-47bb-0310-9956-ffa450edef68
Mahadev Konar 12 년 전
부모
커밋
4a2969dd26

+ 2 - 0
AMBARI-666-CHANGES.txt

@@ -12,6 +12,8 @@ AMBARI-666 branch (unreleased changes)
 
   NEW FEATURES
 
+  AMBARI-784. Add Resource download API on the server. (mahadev)
+
   AMBARI-781. Registration unit test. (jitendra)
 
   AMBARI-754. Heartbeat handler: Registration response should query component 

+ 21 - 0
ambari-server/src/main/assemblies/empty.xml

@@ -0,0 +1,21 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you 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.
+-->
+<assembly>
+    <id>empty</id>
+    <formats/>
+</assembly>

+ 8 - 1
ambari-server/src/main/assemblies/server.xml

@@ -28,7 +28,6 @@
       <source>${project.build.directory}/${artifact.artifactId}-${artifact.version}.jar</source>
       <outputDirectory>ambari-server-${project.version}/lib</outputDirectory>
     </file>
-
   </files>
   <fileSets>
     <!-- Distro files, readme, licenses, etc -->
@@ -60,6 +59,14 @@
       </includes>
     </fileSet>
 
+    <fileSet>
+      <directory>src/main/assemblies</directory>
+      <outputDirectory>/ambari-server-${project.version}/res</outputDirectory>
+      <excludes>
+        <exclude>*</exclude>
+      </excludes>
+    </fileSet>
+
   </fileSets>
   <dependencySets>
     <dependencySet>

+ 4 - 0
ambari-server/src/main/java/org/apache/ambari/server/AmbariException.java

@@ -26,4 +26,8 @@ public class AmbariException extends IOException {
   public AmbariException(String message) {
     super(message);
   }
+
+  public AmbariException(String message, Throwable cause) {
+    super(message, cause);
+  }
 }

+ 3 - 1
ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java

@@ -52,6 +52,7 @@ public class Configuration {
   public static final String SRVR_CRT_PASS_KEY = "security.server.crt_pass";
   public static final String PASSPHRASE_ENV_KEY = "security.server.passphrase_env_var";
   public static final String PASSPHRASE_KEY = "security.server.passphrase";
+  public static final String RESOURCES_DIR_KEY = "resources.dir";
 
   public static final String CLIENT_SECURITY_KEY = "client.security";
   public static final String LDAP_USE_SSL_KEY = "authorization.ldap.useSSL";
@@ -70,6 +71,7 @@ public class Configuration {
   public static final String KSTR_NAME_DEFAULT = "keystore.p12";
   private static final String SRVR_CRT_PASS_FILE_DEFAULT ="pass.txt";
   private static final String PASSPHRASE_ENV_DEFAULT = "AMBARI_PASSPHRASE";
+  private static final String RESOURCES_DIR_DEFAULT = "res";
 
 
   private static final String CLIENT_SECURITY_DEFAULT = "local";
@@ -120,7 +122,7 @@ public class Configuration {
 	configsMap.put(PASSPHRASE_KEY, System.getenv(configsMap.get(PASSPHRASE_ENV_KEY)));
     configsMap.put(CLIENT_SECURITY_KEY, properties.getProperty(CLIENT_SECURITY_KEY, CLIENT_SECURITY_DEFAULT));
     configsMap.put(LDAP_USER_DEFAULT_ROLE_KEY, properties.getProperty(LDAP_USER_DEFAULT_ROLE_KEY, LDAP_USER_DEFAULT_ROLE_DEFAULT));
-
+    configsMap.put(RESOURCES_DIR_KEY, properties.getProperty(RESOURCES_DIR_KEY, RESOURCES_DIR_DEFAULT));
     try {
         File passFile = new File(configsMap.get(SRVR_KSTR_DIR_KEY) + File.separator
             + configsMap.get(SRVR_CRT_PASS_FILE_KEY));

+ 8 - 0
ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java

@@ -170,6 +170,14 @@ public class AmbariServer {
       root.addServlet(cert, "/certs/*");
       certs.setInitOrder(5);
 
+      ServletHolder resources = new ServletHolder(ServletContainer.class);
+      resources.setInitParameter("com.sun.jersey.config.property.resourceConfigClass",
+        "com.sun.jersey.api.core.PackagesResourceConfig");
+      resources.setInitParameter("com.sun.jersey.config.property.packages",
+        "org.apache.ambari.server.resources.api.rest");
+      root.addServlet(resources, "/resources/*");
+      resources.setInitOrder(6);
+
       server.setStopAtShutdown(true);
 
       springAppContext.start();

+ 3 - 0
ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java

@@ -17,6 +17,7 @@
  */
 package org.apache.ambari.server.controller;
 import org.apache.ambari.server.agent.rest.AgentResource;
+import org.apache.ambari.server.resources.api.rest.GetResource;
 import org.apache.ambari.server.security.unsecured.rest.CertificateDownload;
 import org.apache.ambari.server.security.unsecured.rest.CertificateSign;
 
@@ -30,8 +31,10 @@ public class ControllerModule extends AbstractModule {
 
   @Override
   protected void configure() {
+
     requestStaticInjection(AgentResource.class);
     requestStaticInjection(CertificateDownload.class);
     requestStaticInjection(CertificateSign.class);
+    requestStaticInjection(GetResource.class);
   }
 }

+ 48 - 0
ambari-server/src/main/java/org/apache/ambari/server/resources/ResourceManager.java

@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.ambari.server.resources;
+
+import java.io.File;
+
+import org.apache.ambari.server.configuration.Configuration;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+/**
+ * Resource manager.
+ */
+@Singleton
+public class ResourceManager {
+  private static Log LOG = LogFactory.getLog(ResourceManager.class);
+	
+  @Inject Configuration configs;
+  /**
+  * Returns resource file.
+  * @param resourcePath relational path to file
+  * @return resource file
+  */
+  public File getResource(String resourcePath) {
+    String resDir = configs.getConfigsMap().get(Configuration.RESOURCES_DIR_KEY);
+    String resourcePathIndep = resourcePath.replaceAll("/", File.separator);
+    File resourceFile = new File(resDir + File.separator + resourcePathIndep);
+    return resourceFile;
+  }
+}

+ 67 - 0
ambari-server/src/main/java/org/apache/ambari/server/resources/api/rest/GetResource.java

@@ -0,0 +1,67 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.ambari.server.resources.api.rest;
+
+
+import java.io.File;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.ambari.server.resources.ResourceManager;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.google.inject.Inject;
+
+/**
+ * Resource api.
+ */
+@Path("/")
+public class GetResource {
+  private static Log LOG = LogFactory.getLog(GetResource.class);
+
+  private static ResourceManager resMan;
+
+  @Inject
+  static void init(ResourceManager instance) {
+	  resMan = instance;
+  }
+
+
+  @GET
+  @Path("{resourcePath:.*}")
+  @Consumes(MediaType.TEXT_PLAIN)
+  @Produces(MediaType.APPLICATION_OCTET_STREAM)
+  public Response getResource(@PathParam("resourcePath") String resourcePath, @Context HttpServletRequest req) {
+    File resourceFile = resMan.getResource(resourcePath);
+
+    if (!resourceFile.exists())
+    	return Response.status(HttpServletResponse.SC_NOT_FOUND).build();
+
+    return Response.ok(resourceFile).build();
+  }
+}

+ 5 - 1
ambari-server/src/main/java/org/apache/ambari/server/security/SecurityFilter.java

@@ -49,7 +49,6 @@ public class SecurityFilter implements Filter {
 
     System.out.println("req url:" + reqUrl);
 
-    //req.getC
 	
     if (serReq.getLocalPort() == AmbariServer.CLIENT_ONE_WAY) {
       if (isRequestAllowed(reqUrl))
@@ -78,6 +77,11 @@ public class SecurityFilter implements Filter {
 		 if (isMatch)
 			 return true;
 		
+		 isMatch = Pattern.matches("https://[A-z]*:[0-9]*/resources/.*", reqUrl);
+		
+		 if (isMatch)
+			 return true;
+		
 	} catch (Exception e) {
 	}
 	return false;

+ 62 - 0
ambari-server/src/main/python/ambari-server.py

@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+
+'''
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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.
+'''
+
+import optparse
+import argparse
+import sys
+import subprocess
+
+SETUP_ACTION = "setup"
+START_ACTION = "start"
+STOP_ACTION = "stop"
+SETUP_CMD = "sudo -u postgres psql -f setup_db.sql"
+
+
+def setup():
+  command = SETUP_CMD
+  process = subprocess.Popen(command.split(' '),
+                             stdout=subprocess.PIPE,
+                             stderr=subprocess.PIPE)
+  process.communicate()
+
+def main():
+  parser = argparse.ArgumentParser()
+  parser.add_argument("action", help="action to perform with ambari server")
+  parser.add_argument('-postgreuser', '--postgreuser', default='root',
+                      help="User in postgresql to run init scripts")
+  parser.add_argument('-postgrepass', '--postgrepass')
+  args = parser.parse_args()
+
+  action = args.action
+  if action == SETUP_ACTION:
+    setup()
+  elif action == START_ACTION:
+    print START_ACTION
+  elif action == STOP_ACTION:
+    print STOP_ACTION
+  else:
+    print "Incorrect action"
+    sys.exit(2)
+    
+
+    
+    
+if __name__ == "__main__":
+  main()

+ 0 - 0
ambari-server/src/main/resources/db/index.txt


+ 92 - 0
ambari-server/src/test/java/org/apache/ambari/server/resources/TestResources.java

@@ -0,0 +1,92 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.ambari.server.resources;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+import junit.framework.TestCase;
+
+import org.apache.ambari.server.configuration.Configuration;
+import org.apache.commons.io.FileUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+
+public class TestResources extends TestCase {
+	
+  private static ResourceManager resMan;
+  private static final String RESOURCE_FILE_NAME = "resource.ext";
+  private static final String RESOURCE_FILE_CONTENT = "CONTENT";
+  Injector injector;
+  private TemporaryFolder tempFolder = new TemporaryFolder();
+  private File resourceFile;
+
+  private class ResourceModule extends AbstractModule {
+  @Override
+    protected void configure() {
+	  requestStaticInjection(TestResources.class);
+	}
+  }
+
+  @Inject
+  static void init(ResourceManager instance) {
+    resMan = instance;
+  }
+
+  @Before
+  public void setUp() throws IOException {
+	tempFolder.create();
+	
+    System.setProperty(Configuration.AMBARI_CONF_VAR, tempFolder.getRoot().getAbsolutePath());
+	Properties props = new Properties();
+	props.setProperty(Configuration.SRVR_KSTR_DIR_KEY, tempFolder.getRoot().getAbsolutePath());
+	props.setProperty(Configuration.RESOURCES_DIR_KEY, tempFolder.getRoot().getAbsolutePath());
+	FileOutputStream out = new FileOutputStream(tempFolder.getRoot().getAbsolutePath() + File.separator + Configuration.CONFIG_FILE);
+	props.store(out, "");
+	out.close();
+    resourceFile = tempFolder.newFile(RESOURCE_FILE_NAME);
+    FileUtils.write(resourceFile, RESOURCE_FILE_CONTENT);
+    injector = Guice.createInjector(new ResourceModule());
+    resMan = injector.getInstance(ResourceManager.class);
+  }
+	
+  @After
+  public void tearDown() throws IOException {
+    resourceFile.delete();
+	tempFolder.delete();
+  }
+	
+  @Test
+  public void testGetResource() throws Exception {
+    File resFile = resMan.getResource(resourceFile.getName());
+    assertTrue(resFile.exists());
+    String resContent = FileUtils.readFileToString(resFile);
+    assertEquals(resContent, RESOURCE_FILE_CONTENT);
+  }
+
+}