/*
* RESTHeart - the Web API for MongoDB
* Copyright (C) SoftInstigate Srl
*
* This program 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, either version 3 of the
* License, or (at your option) any later version.
*
* 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/>.
*/
package org.restheart.handlers.files;
import com.eclipsesource.json.JsonObject;
import io.undertow.util.Headers;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.UnknownHostException;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.fluent.Request;
import org.apache.http.client.fluent.Response;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.util.EntityUtils;
import org.bson.BsonString;
import org.bson.types.ObjectId;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.restheart.test.integration.HttpClientAbstactIT;
import org.restheart.hal.Representation;
import org.restheart.utils.HttpStatus;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
*
* @author Maurizio Turatti {@literal <maurizio@softinstigate.com>}
*/
public class GetFileHandlerIT extends HttpClientAbstactIT {
@Rule
public TemporaryFolder tempFolder = new TemporaryFolder();
public static final String FILENAME = "RESTHeart_documentation.pdf";
public static final String BUCKET = "mybucket";
public static Object ID = "myfile";
public GetFileHandlerIT() {
}
@Test
public void testGetFile() throws Exception {
createBucket();
ObjectId fileId = createFile();
String url = dbTmpUri + "/" + BUCKET + ".files/" + fileId.toString() + "/binary";
Response resp = adminExecutor.execute(Request.Get(url));
HttpResponse httpResp = resp.returnResponse();
assertNotNull(httpResp);
HttpEntity entity = httpResp.getEntity();
assertNotNull(entity);
StatusLine statusLine = httpResp.getStatusLine();
assertNotNull(statusLine);
assertEquals("check status code", HttpStatus.SC_OK, statusLine.getStatusCode());
assertNotNull("content type not null", entity.getContentType());
File tempFile = tempFolder.newFile(FILENAME);
FileOutputStream fos = new FileOutputStream(tempFile);
entity.writeTo(fos);
assertTrue(tempFile.length() > 0);
}
@Test
public void testPostFile() throws Exception {
createBucket();
ObjectId fileId = createFile();
}
@Test
public void testEmptyBucket() throws Exception {
createBucket();
// test that GET /db includes the rh:bucket array
Response resp = adminExecutor.execute(Request.Get(dbTmpUri));
HttpResponse httpResp = resp.returnResponse();
assertNotNull(httpResp);
HttpEntity entity = httpResp.getEntity();
assertNotNull(entity);
StatusLine statusLine = httpResp.getStatusLine();
assertNotNull(statusLine);
assertEquals("check status code", HttpStatus.SC_OK, statusLine.getStatusCode());
assertNotNull("content type not null", entity.getContentType());
assertEquals("check content type", Representation.HAL_JSON_MEDIA_TYPE, entity.getContentType().getValue());
String content = EntityUtils.toString(entity);
JsonObject json = null;
try {
json = JsonObject.readFrom(content);
} catch (Throwable t) {
fail("parsing received json");
}
assertNotNull(json.get("_returned"));
assertTrue(json.get("_returned").isNumber());
assertTrue(json.getInt("_returned", 0) > 0);
assertNotNull(json.get("_embedded"));
assertTrue(json.get("_embedded").isObject());
assertNotNull(json.get("_embedded").asObject().get("rh:bucket"));
assertTrue(json.get("_embedded").asObject().get("rh:bucket").isArray());
assertTrue(!json.get("_embedded").asObject().get("rh:bucket").asArray().isEmpty());
}
@Test
public void testBucketWithFile() throws Exception {
createBucket();
ObjectId fileId = createFile();
// test that GET /db/bucket.files includes the file
String bucketUrl = dbTmpUri + "/" + BUCKET + ".files";
Response resp = adminExecutor.execute(Request.Get(bucketUrl));
HttpResponse httpResp = resp.returnResponse();
assertNotNull(httpResp);
HttpEntity entity = httpResp.getEntity();
assertNotNull(entity);
StatusLine statusLine = httpResp.getStatusLine();
assertNotNull(statusLine);
assertEquals("check status code", HttpStatus.SC_OK, statusLine.getStatusCode());
assertNotNull("content type not null", entity.getContentType());
assertEquals("check content type", Representation.HAL_JSON_MEDIA_TYPE, entity.getContentType().getValue());
String content = EntityUtils.toString(entity);
JsonObject json = null;
try {
json = JsonObject.readFrom(content);
} catch (Throwable t) {
fail("parsing received json");
}
assertNotNull(json.get("_returned"));
assertTrue(json.get("_returned").isNumber());
assertTrue(json.getInt("_returned", 0) > 0);
assertNotNull(json.get("_embedded"));
assertTrue(json.get("_embedded").isObject());
assertNotNull(json.get("_embedded").asObject().get("rh:file"));
assertTrue(json.get("_embedded").asObject().get("rh:file").isArray());
}
@Test
public void testPutFile() throws Exception {
createBucket();
String id = "test";
createFilePut(id);
// test that GET /db/bucket.files includes the file
String fileUrl = dbTmpUri + "/" + BUCKET + ".files/" +id;
Response resp = adminExecutor.execute(Request.Get(fileUrl));
HttpResponse httpResp = resp.returnResponse();
assertNotNull(httpResp);
HttpEntity entity = httpResp.getEntity();
assertNotNull(entity);
StatusLine statusLine = httpResp.getStatusLine();
assertNotNull(statusLine);
assertEquals("check status code", HttpStatus.SC_OK, statusLine.getStatusCode());
assertNotNull("content type not null", entity.getContentType());
assertEquals("check content type", Representation.HAL_JSON_MEDIA_TYPE, entity.getContentType().getValue());
String content = EntityUtils.toString(entity);
JsonObject json = null;
try {
json = JsonObject.readFrom(content);
} catch (Throwable t) {
fail("parsing received json");
}
assertNotNull(json.get("_id"));
assertNotNull(json.get("metadata"));
}
private void createBucket() throws IOException {
// create db
Response resp = adminExecutor.execute(Request.Put(dbTmpUri)
.addHeader(Headers.CONTENT_TYPE_STRING, Representation.HAL_JSON_MEDIA_TYPE));
HttpResponse httpResp = resp.returnResponse();
assertNotNull(httpResp);
StatusLine statusLine = httpResp.getStatusLine();
assertNotNull(statusLine);
assertEquals("check status code", HttpStatus.SC_CREATED, statusLine.getStatusCode());
// create bucket
String bucketUrl = dbTmpUri + "/" + BUCKET + ".files/";
resp = adminExecutor.execute(Request.Put(bucketUrl)
.addHeader(Headers.CONTENT_TYPE_STRING, Representation.HAL_JSON_MEDIA_TYPE));
httpResp = resp.returnResponse();
assertNotNull(httpResp);
statusLine = httpResp.getStatusLine();
assertNotNull(statusLine);
assertEquals("check status code", HttpStatus.SC_CREATED, statusLine.getStatusCode());
}
private ObjectId createFile() throws UnknownHostException, IOException {
String bucketUrl = dbTmpUri + "/" + BUCKET + ".files/";
InputStream is = GetFileHandlerIT.class.getResourceAsStream("/" + FILENAME);
HttpEntity entity = MultipartEntityBuilder
.create()
.addBinaryBody("file", is, ContentType.create("application/octet-stream"), FILENAME)
.addTextBody("metadata", "{\"type\": \"documentation\"}")
.build();
Response resp = adminExecutor.execute(Request.Post(bucketUrl)
.body(entity));
HttpResponse httpResp = resp.returnResponse();
assertNotNull(httpResp);
StatusLine statusLine = httpResp.getStatusLine();
assertNotNull(statusLine);
assertEquals("check status code", HttpStatus.SC_CREATED, statusLine.getStatusCode());
Header[] hs = httpResp.getHeaders("Location");
if (hs == null || hs.length < 1) {
return null;
} else {
String loc = hs[0].getValue();
String id = loc.substring(loc.lastIndexOf("/") + 1);
return new ObjectId(id);
}
}
private void createFilePut(String id) throws UnknownHostException, IOException {
String bucketUrl = dbTmpUri + "/" + BUCKET + ".files/" + id;
InputStream is = GetFileHandlerIT.class.getResourceAsStream("/" + FILENAME);
HttpEntity entity = MultipartEntityBuilder
.create()
.addBinaryBody("file", is, ContentType.create("application/octet-stream"), FILENAME)
.addTextBody("metadata", "{\"type\": \"documentation\"}")
.build();
Response resp = adminExecutor.execute(Request.Put(bucketUrl)
.body(entity));
HttpResponse httpResp = resp.returnResponse();
assertNotNull(httpResp);
StatusLine statusLine = httpResp.getStatusLine();
assertNotNull(statusLine);
assertEquals("check status code", HttpStatus.SC_CREATED, statusLine.getStatusCode());
}
}