/* * (C) Copyright 2014 Nuxeo SA (http://nuxeo.com/) and others. * * Licensed 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. * * Contributors: * Antoine Taillefer <ataillefer@nuxeo.com> */ package org.nuxeo.ecm.automation.server.jaxrs.batch; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import java.util.UUID; import javax.inject.Inject; import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.IOUtils; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.map.ObjectMapper; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.nuxeo.ecm.automation.client.Session; import org.nuxeo.ecm.automation.client.model.Blob; import org.nuxeo.ecm.automation.core.operations.blob.GetDocumentBlob; import org.nuxeo.ecm.automation.test.EmbeddedAutomationServerFeature; import org.nuxeo.ecm.core.api.CoreSession; import org.nuxeo.ecm.core.api.DocumentModel; import org.nuxeo.ecm.core.api.NuxeoException; import org.nuxeo.runtime.api.Framework; import org.nuxeo.runtime.test.runner.Features; import org.nuxeo.runtime.test.runner.FeaturesRunner; import org.nuxeo.runtime.test.runner.Jetty; import org.nuxeo.runtime.test.runner.RuntimeHarness; import org.nuxeo.runtime.transaction.TransactionHelper; import org.nuxeo.transientstore.test.TransientStoreFeature; /** * Tests file upload with the {@link BatchResource}. * <p> * Uses {@link URLConnection}. * * @author Antoine Taillefer * @deprecated since 7.4 * @see {@link BatchUploadTest} */ @Deprecated @RunWith(FeaturesRunner.class) @Features({ TransientStoreFeature.class, EmbeddedAutomationServerFeature.class }) @Jetty(port = 18080) public class TestBatchResource { @Inject protected RuntimeHarness harness; @Inject protected CoreSession session; @Inject protected Session clientSession; protected ObjectMapper mapper; protected String uploadURL = "http://localhost:18080/automation/batch/upload"; protected String fileIndex = "0"; protected String fileName = "New file.txt"; protected String mimeType = "text/plain"; protected String content = "This is the content of a new file."; @Before public void doBefore() throws Exception { mapper = new ObjectMapper(); } @Test(expected = NuxeoException.class) public void testBatchUploadClientGeneratedIdNotAllowed() throws IOException { String batchId = UUID.randomUUID().toString(); batchUpload(uploadURL, batchId, fileIndex, fileName, mimeType, content); } @Test public void testBatchUploadClientGeneratedIdAllowed() throws Exception { harness.deployContrib("org.nuxeo.ecm.automation.test.test", "test-batchmanager-client-generated-id-allowed-contrib.xml"); String batchId = UUID.randomUUID().toString(); String responseBatchId = batchUpload(uploadURL, batchId, fileIndex, fileName, mimeType, content); assertEquals(batchId, responseBatchId); harness.undeployContrib("org.nuxeo.ecm.automation.test.test", "test-batchmanager-client-generated-id-allowed-contrib.xml"); } @Test public void testBatchUploadServerGeneratedId() throws IOException { String batchId = Framework.getService(BatchManager.class).initBatch(); assertEquals(batchId, batchUpload(uploadURL, batchId, fileIndex, fileName, mimeType, content)); } @Test public void testBatchUpload() throws Exception { // Create a File document DocumentModel file = session.createDocumentModel("/", "testFile", "File"); file = session.createDocument(file); TransactionHelper.commitOrRollbackTransaction(); TransactionHelper.startTransaction(); // Upload a blob and attach it to the document String executeURL = "http://localhost:18080/automation/batch/execute"; String docPath = file.getPathAsString(); String batchId = batchUpload(uploadURL, null, fileIndex, fileName, mimeType, content); batchExecuteAttachBlob(executeURL, batchId, fileIndex, docPath); // Get blob from document and check its content Blob blob = (Blob) clientSession.newRequest(GetDocumentBlob.ID).setInput(file.getPathAsString()).execute(); assertNotNull(blob); String blobString = new String(IOUtils.toByteArray(blob.getStream())); assertEquals("This is the content of a new file.", blobString); } protected String batchUpload(String urlStr, String batchId, String fileIndex, String fileName, String mimeType, String content) throws IOException { URL url = new URL(urlStr); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); try { // Set request headers byte[] bytes = content.getBytes(); String fileSize = Integer.toString(bytes.length); conn.setRequestProperty("Authorization", getAuthHeader("Administrator", "Administrator")); if (batchId != null) { conn.setRequestProperty("X-Batch-Id", batchId); } conn.setRequestProperty("X-File-Idx", fileIndex); conn.setRequestProperty("X-File-Name", fileName); conn.setRequestProperty("X-File-Size", fileSize); conn.setRequestProperty("X-File-Type", mimeType); conn.setRequestProperty("Content-Type", "application/octet-stream"); conn.setRequestProperty("Content-Length", fileSize); // Write bytes conn.setDoOutput(true); try (OutputStream os = conn.getOutputStream()) { IOUtils.write(content, os); } if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) { throw new NuxeoException("Batch upload request failed with status code " + conn.getResponseCode()); } // Read response and return batch id try (InputStream is = conn.getInputStream()) { JsonNode node = mapper.readTree(is); return node.get("batchId").getValueAsText(); } } finally { conn.disconnect(); } } protected boolean batchExecuteAttachBlob(String urlStr, String batchId, String fileIndex, String docPath) throws IOException { URL url = new URL(urlStr); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); try { // Set request headers conn.setRequestProperty("Authorization", getAuthHeader("Administrator", "Administrator")); conn.setRequestProperty("Content-Type", "application/json+nxrequest"); conn.setRequestProperty("Accept", "application/json+nxentity, */*"); conn.setRequestProperty("X-NXDocumentProperties", "*"); // Write JSON data conn.setDoOutput(true); String JSONData = String.format( "{\"params\": {\"operationId\": \"%s\", \"batchId\": \"%s\", \"fileIdx\": \"%s\", \"document\": \"%s\"}}", "Blob.Attach", batchId, fileIndex, docPath); try (OutputStream os = conn.getOutputStream()) { IOUtils.write(JSONData, os); } // Consume response and return true if OK try (InputStream is = conn.getInputStream()) { IOUtils.toByteArray(is); return conn.getResponseCode() == HttpURLConnection.HTTP_OK; } } finally { conn.disconnect(); } } protected String getAuthHeader(String userName, String password) { return "Basic " + new String(Base64.encodeBase64((userName + ":" + password).getBytes())); } }