/* * ProActive Parallel Suite(TM): * The Open Source library for parallel and distributed * Workflows & Scheduling, Orchestration, Cloud Automation * and Big Data Analysis on Enterprise Grids & Clouds. * * Copyright (c) 2007 - 2017 ActiveEon * Contact: contact@activeeon.com * * This library is free software: you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation: version 3 of * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * If needed, contact us to obtain a release under GPL Version 2 or 3 * or a different license than the AGPL. */ package functionaltests; import java.io.File; import java.io.InputStream; import java.net.URI; import java.net.URLEncoder; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import javax.ws.rs.core.MediaType; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.mime.MultipartEntity; import org.apache.http.entity.mime.content.InputStreamBody; import org.apache.http.entity.mime.content.StringBody; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.ow2.proactive.scheduler.common.Scheduler; import org.ow2.proactive.scheduler.common.SchedulerConstants; import org.ow2.proactive.scheduler.common.SchedulerState; import org.ow2.proactive.scheduler.common.job.JobId; import org.ow2.proactive.scheduler.common.job.JobState; /** * RestSchedulerPushPullFileTest * <p/> * This test tries to push and pull a file to the Global and User space * * @author The ProActive Team */ public class RestSchedulerPushPullFileTest extends AbstractRestFuncTestCase { @Rule public TemporaryFolder tmpFolder = new TemporaryFolder(); @BeforeClass public static void beforeClass() throws Exception { init(); } @Before public void setUp() throws Exception { Scheduler scheduler = RestFuncTHelper.getScheduler(); SchedulerState state = scheduler.getState(); List<JobState> jobStates = new ArrayList<>(); jobStates.addAll(state.getPendingJobs()); jobStates.addAll(state.getRunningJobs()); jobStates.addAll(state.getFinishedJobs()); for (JobState jobState : jobStates) { JobId jobId = jobState.getId(); scheduler.killJob(jobId); scheduler.removeJob(jobId); } } @Test public void testPushPull() throws Exception { Scheduler scheduler = RestFuncTHelper.getScheduler(); String[] destPaths = { "another", "test/push/pull" }; String[] spacesNames = { SchedulerConstants.GLOBALSPACE_NAME, SchedulerConstants.USERSPACE_NAME }; String[] spacesUris = { scheduler.getGlobalSpaceURIs().get(0), scheduler.getUserSpaceURIs().get(0) }; for (String destPath : destPaths) { for (int i = 0; i < spacesNames.length; i++) { String spaceName = spacesNames[i]; String spacePath = (new File(new URI(spacesUris[i]))).getAbsolutePath(); testIt(spaceName, spacePath, destPath, true); // if URL is not encoded then the path appended to the URL will be interpreted // as if it is part of the URL. This will produce something like // 'http://localhost:8080/rest/scheduler/dataspace/USERSPACE//' // that contains a double slash at the end of the URL, which is now detected as invalid // by Resteasy. Consequently, it will produce an error on server side (error 500 received on client side) // for this reason the next line has been commented and a new test added below // testIt(spaceName, spacePath, destPath, false); } } } @Test public void testFailureWithNonEncodedParametersInUrlPath() throws Exception { String destPath = "testNonEncoded"; String pullListUrl = getResourceUrl("dataspace/" + SchedulerConstants.GLOBALSPACE_NAME + "/" + destPath); HttpGet reqPullList = new HttpGet(pullListUrl); setSessionHeader(reqPullList); HttpResponse response = executeUriRequest(reqPullList); assertEquals(500, response.getStatusLine().getStatusCode()); } public void testIt(String spaceName, String spacePath, String destPath, boolean encode) throws Exception { File testPushFile = RestFuncTHelper.getDefaultJobXmlfile(); // you can test pushing pulling a big file : // testPushFile = new File("path_to_a_big_file"); File destFile = new File(new File(spacePath, destPath), testPushFile.getName()); if (destFile.exists()) { destFile.delete(); } // PUSHING THE FILE String pushfileUrl = getResourceUrl("dataspace/" + spaceName + "/" + (encode ? URLEncoder.encode(destPath, "UTF-8") : destPath.replace("\\", "/"))); // either we encode or we test human readable path (with no special character inside) HttpPost reqPush = new HttpPost(pushfileUrl); setSessionHeader(reqPush); // we push a xml job as a simple test MultipartEntity multipartEntity = new MultipartEntity(); multipartEntity.addPart("fileName", new StringBody(testPushFile.getName())); multipartEntity.addPart("fileContent", new InputStreamBody(FileUtils.openInputStream(testPushFile), MediaType.APPLICATION_OCTET_STREAM, null)); reqPush.setEntity(multipartEntity); HttpResponse response = executeUriRequest(reqPush); System.out.println(response.getStatusLine()); assertHttpStatusOK(response); Assert.assertTrue(destFile + " exists for " + spaceName, destFile.exists()); Assert.assertTrue("Original file and result are equals for " + spaceName, FileUtils.contentEquals(testPushFile, destFile)); // LISTING THE TARGET DIRECTORY String pullListUrl = getResourceUrl("dataspace/" + spaceName + "/" + (encode ? URLEncoder.encode(destPath, "UTF-8") : destPath.replace("\\", "/"))); HttpGet reqPullList = new HttpGet(pullListUrl); setSessionHeader(reqPullList); HttpResponse response2 = executeUriRequest(reqPullList); System.out.println(response2.getStatusLine()); assertHttpStatusOK(response2); InputStream is = response2.getEntity().getContent(); List<String> lines = IOUtils.readLines(is); HashSet<String> content = new HashSet<>(lines); System.out.println(lines); Assert.assertTrue("Pushed file correctly listed", content.contains(testPushFile.getName())); // PULLING THE FILE String pullfileUrl = getResourceUrl("dataspace/" + spaceName + "/" + (encode ? URLEncoder.encode(destPath + "/" + testPushFile.getName(), "UTF-8") : destPath.replace("\\", "/") + "/" + testPushFile.getName())); HttpGet reqPull = new HttpGet(pullfileUrl); setSessionHeader(reqPull); HttpResponse response3 = executeUriRequest(reqPull); System.out.println(response3.getStatusLine()); assertHttpStatusOK(response3); InputStream is2 = response3.getEntity().getContent(); File answerFile = tmpFolder.newFile(); FileUtils.copyInputStreamToFile(is2, answerFile); Assert.assertTrue("Original file and result are equals for " + spaceName, FileUtils.contentEquals(answerFile, testPushFile)); // DELETING THE HIERARCHY String rootPath = destPath.substring(0, destPath.contains("/") ? destPath.indexOf("/") : destPath.length()); String deleteUrl = getResourceUrl("dataspace/" + spaceName + "/" + (encode ? URLEncoder.encode(rootPath, "UTF-8") : rootPath.replace("\\", "/"))); HttpDelete reqDelete = new HttpDelete(deleteUrl); setSessionHeader(reqDelete); HttpResponse response4 = executeUriRequest(reqDelete); System.out.println(response4.getStatusLine()); assertHttpStatusOK(response4); Assert.assertTrue(destFile + " still exist", !destFile.exists()); } }