/** * 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.view.filebrowser; import static org.easymock.EasyMock.createNiceMock; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.replay; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileWriter; import java.io.InputStream; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import org.apache.ambari.view.ViewContext; import org.apache.ambari.view.ViewResourceHandler; import org.apache.ambari.view.commons.hdfs.FileOperationService; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileUtil; import org.apache.hadoop.hdfs.MiniDFSCluster; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Injector; import com.sun.jersey.core.header.FormDataContentDisposition; import com.sun.jersey.multipart.FormDataBodyPart; public class FilebrowserTest{ private ViewResourceHandler handler; private ViewContext context; private HttpHeaders httpHeaders; private UriInfo uriInfo; private Map<String, String> properties; private FileBrowserService fileBrowserService; private MiniDFSCluster hdfsCluster; public static final String BASE_URI = "http://localhost:8084/myapp/"; @Before public void setUp() throws Exception { handler = createNiceMock(ViewResourceHandler.class); context = createNiceMock(ViewContext.class); httpHeaders = createNiceMock(HttpHeaders.class); uriInfo = createNiceMock(UriInfo.class); properties = new HashMap<String, String>(); File baseDir = new File("./target/hdfs/" + "FilebrowserTest") .getAbsoluteFile(); FileUtil.fullyDelete(baseDir); Configuration conf = new Configuration(); conf.set(MiniDFSCluster.HDFS_MINIDFS_BASEDIR, baseDir.getAbsolutePath()); conf.set("hadoop.proxyuser." + System.getProperty("user.name") + ".groups", "*"); conf.set("hadoop.proxyuser." + System.getProperty("user.name") + ".hosts", "*"); MiniDFSCluster.Builder builder = new MiniDFSCluster.Builder(conf); hdfsCluster = builder.build(); String hdfsURI = hdfsCluster.getURI() + "/"; properties.put("webhdfs.url", hdfsURI); expect(context.getProperties()).andReturn(properties).anyTimes(); expect(context.getUsername()).andReturn(System.getProperty("user.name")).anyTimes(); replay(handler, context, httpHeaders, uriInfo); fileBrowserService = getService(FileBrowserService.class, handler, context); FileOperationService.MkdirRequest request = new FileOperationService.MkdirRequest(); request.path = "/tmp"; fileBrowserService.fileOps().mkdir(request); } @After public void tearDown() { hdfsCluster.shutdown(); } @Test public void testListDir() throws Exception { FileOperationService.MkdirRequest request = new FileOperationService.MkdirRequest(); request.path = "/tmp1"; fileBrowserService.fileOps().mkdir(request); Response response = fileBrowserService.fileOps().listdir("/"); JSONObject responseObject = (JSONObject) response.getEntity(); JSONArray statuses = (JSONArray) responseObject.get("files"); System.out.println(response.getEntity()); Assert.assertEquals(200, response.getStatus()); Assert.assertTrue(statuses.size() > 0); System.out.println(statuses); } private Response uploadFile(String path, String fileName, String fileExtension, String fileContent) throws Exception { File tempFile = File.createTempFile(fileName, fileExtension); BufferedWriter bw = new BufferedWriter(new FileWriter(tempFile)); bw.write(fileContent); bw.close(); InputStream content = new FileInputStream(tempFile); FormDataBodyPart inputStreamBody = new FormDataBodyPart( FormDataContentDisposition.name("file") .fileName(fileName + fileExtension).build(), content, MediaType.APPLICATION_OCTET_STREAM_TYPE); Response response = fileBrowserService.upload().uploadFile(content, inputStreamBody.getFormDataContentDisposition(), "/tmp/"); return response; } @Test public void testUploadFile() throws Exception { Response response = uploadFile("/tmp/", "testUpload", ".tmp", "Hello world"); Assert.assertEquals(200, response.getStatus()); Response listdir = fileBrowserService.fileOps().listdir("/tmp"); JSONObject responseObject = (JSONObject) listdir.getEntity(); JSONArray statuses = (JSONArray) responseObject.get("files"); System.out.println(statuses.size()); Response response2 = fileBrowserService.download().browse("/tmp/testUpload.tmp", false, false, httpHeaders, uriInfo); Assert.assertEquals(200, response2.getStatus()); } private void createDirectoryWithFiles(String dirPath) throws Exception { FileOperationService.MkdirRequest request = new FileOperationService.MkdirRequest(); request.path = dirPath; File file = new File(dirPath); String fileName = file.getName(); fileBrowserService.fileOps().mkdir(request); for (int i = 0; i < 10; i++) { uploadFile(dirPath, fileName + i, ".txt", "Hello world" + i); } } @Test public void testStreamingGzip() throws Exception { String gzipDir = "/tmp/testGzip"; createDirectoryWithFiles(gzipDir); DownloadService.DownloadRequest dr = new DownloadService.DownloadRequest(); dr.entries = new String[] { gzipDir }; Response result = fileBrowserService.download().downloadGZip(dr); } @Test public void testStreamingDownloadGzipName() throws Exception { String gzipDir = "/tmp/testGzip1"; createDirectoryWithFiles(gzipDir); // test download 1 folder validateDownloadZipName(new String[]{gzipDir}, "testGzip1.zip" ); // test download 1 folder validateDownloadZipName(new String[]{gzipDir + "/testGzip11.txt"}, "testGzip11.txt.zip" ); String gzipDir2 = "/tmp/testGzip2"; createDirectoryWithFiles(gzipDir2); // test download 2 folders validateDownloadZipName(new String[] { gzipDir, gzipDir2 }, "hdfs.zip" ); // test download 2 files of same folder validateDownloadZipName(new String[] { gzipDir + "/testGzip11", gzipDir + "/testGzip12" }, "hdfs.zip" ); // test download 2 files of different folder -- although I think UI does not allow it validateDownloadZipName(new String[] { gzipDir + "/testGzip11", gzipDir2 + "/testGzip21" }, "hdfs.zip" ); } private void validateDownloadZipName(String[] entries, String downloadedFileName) { DownloadService.DownloadRequest dr = new DownloadService.DownloadRequest(); dr.entries = entries; Response result = fileBrowserService.download().downloadGZip(dr); List<Object> contentDisposition = result.getMetadata().get("Content-Disposition"); Assert.assertEquals("inline; filename=\"" + downloadedFileName +"\"",contentDisposition.get(0)); } @Test public void testUsername() throws Exception { Assert.assertEquals(System.getProperty("user.name"), fileBrowserService.upload().getDoAsUsername(context)); properties.put("webhdfs.username", "test-user"); Assert.assertEquals("test-user", fileBrowserService.upload().getDoAsUsername(context)); } private static <T> T getService(Class<T> clazz, final ViewResourceHandler viewResourceHandler, final ViewContext viewInstanceContext) { Injector viewInstanceInjector = Guice.createInjector(new AbstractModule() { @Override protected void configure() { bind(ViewResourceHandler.class).toInstance(viewResourceHandler); bind(ViewContext.class).toInstance(viewInstanceContext); } }); return viewInstanceInjector.getInstance(clazz); } }