Skip to content

Commit

Permalink
Fix NoSuchFileException when deleting binary fields - Fixes #235
Browse files Browse the repository at this point in the history
  • Loading branch information
Johannes Schüth committed Dec 15, 2017
1 parent 49b0c0f commit 7f982b8
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 25 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.adoc
Expand Up @@ -4,6 +4,8 @@

== 0.11.7 (TBD)

icon:check[] Storage: Binary field deletion has been made more resilient and will no longer fail if the referenced binary data is not stored within used binary storage. link:https://github.com/gentics/mesh/issues/235[#235]

icon:plus[] REST: The `hostname` and `ssl` properties have been added to the project create request. This information will be directly added to the initial release of the project. The properties can thus be changed by updating the project.

icon:plus[] REST: The link resolver mechanism was enhanced to also consider the `hostname` and `ssl` flag of the release of the node which is linked.
Expand Down
@@ -1,44 +1,46 @@
package com.gentics.mesh.core.field.binary;

import static com.gentics.mesh.test.TestDataProvider.PROJECT_NAME;
import static com.gentics.mesh.test.ClientHelper.call;
import static com.gentics.mesh.test.TestDataProvider.PROJECT_NAME;
import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST;
import static io.netty.handler.codec.http.HttpResponseStatus.CONFLICT;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import com.gentics.mesh.core.rest.admin.migration.MigrationStatus;
import com.gentics.mesh.core.rest.graphql.GraphQLRequest;
import com.gentics.mesh.core.rest.graphql.GraphQLResponse;
import com.gentics.mesh.core.rest.node.NodeCreateRequest;
import com.gentics.mesh.core.rest.schema.impl.SchemaResponse;
import com.gentics.mesh.core.rest.schema.impl.SchemaUpdateRequest;
import com.gentics.mesh.json.JsonUtil;

import io.vertx.core.json.JsonObject;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.junit.Before;
import org.junit.Test;

import com.syncleus.ferma.tx.Tx;
import com.gentics.mesh.Mesh;
import com.gentics.mesh.core.data.NodeGraphFieldContainer;
import com.gentics.mesh.core.data.node.Node;
import com.gentics.mesh.core.field.AbstractFieldEndpointTest;
import com.gentics.mesh.core.rest.admin.migration.MigrationStatus;
import com.gentics.mesh.core.rest.graphql.GraphQLRequest;
import com.gentics.mesh.core.rest.graphql.GraphQLResponse;
import com.gentics.mesh.core.rest.node.NodeCreateRequest;
import com.gentics.mesh.core.rest.node.NodeResponse;
import com.gentics.mesh.core.rest.node.field.BinaryField;
import com.gentics.mesh.core.rest.node.field.impl.BinaryFieldImpl;
import com.gentics.mesh.core.rest.schema.BinaryFieldSchema;
import com.gentics.mesh.core.rest.schema.SchemaModel;
import com.gentics.mesh.core.rest.schema.impl.BinaryFieldSchemaImpl;
import com.gentics.mesh.core.rest.schema.impl.SchemaResponse;
import com.gentics.mesh.core.rest.schema.impl.SchemaUpdateRequest;
import com.gentics.mesh.json.JsonUtil;
import com.gentics.mesh.parameter.impl.VersioningParametersImpl;
import com.gentics.mesh.test.TestSize;
import com.gentics.mesh.test.context.MeshTestSetting;
import com.gentics.mesh.util.VersionNumber;
import com.syncleus.ferma.tx.Tx;

import io.vertx.core.buffer.Buffer;
import io.vertx.core.json.JsonObject;
import io.vertx.test.core.TestUtils;

@MeshTestSetting(useElasticsearch = false, testSize = TestSize.PROJECT_AND_NODE, startServer = true)
Expand Down Expand Up @@ -85,9 +87,9 @@ public void testUpdateNodeFieldWithField() {
@Test
public void testVersionConflictUpload() {
// 1. Upload a binary field
String uuid = db().tx(() -> folder("2015").getUuid());
String uuid = tx(() -> folder("2015").getUuid());
Buffer buffer = TestUtils.randomBuffer(1000);
VersionNumber version = db().tx(() -> folder("2015").getGraphFieldContainer("en").getVersion());
VersionNumber version = tx(() -> folder("2015").getGraphFieldContainer("en").getVersion());
NodeResponse responseA = call(() -> client().updateNodeBinaryField(PROJECT_NAME, uuid, "en", version.toString(), FIELD_NAME, buffer,
"filename.txt", "application/binary"));

Expand All @@ -108,9 +110,9 @@ public void testVersionConflictUpload() {
public void testUpdateSameValue() {
try (Tx tx = tx()) {
// 1. Upload a binary field
String uuid = db().tx(() -> folder("2015").getUuid());
String uuid = tx(() -> folder("2015").getUuid());
Buffer buffer = TestUtils.randomBuffer(1000);
VersionNumber version = db().tx(() -> folder("2015").getGraphFieldContainer("en").getVersion());
VersionNumber version = tx(() -> folder("2015").getGraphFieldContainer("en").getVersion());
call(() -> client().updateNodeBinaryField(PROJECT_NAME, uuid, "en", version.toString(), FIELD_NAME, buffer, "filename.txt",
"application/binary"));

Expand All @@ -134,8 +136,8 @@ public void testUpdateSetNull() {
Node node = folder("2015");

// 1. Upload a binary field
String uuid = db().tx(() -> folder("2015").getUuid());
VersionNumber version = db().tx(() -> folder("2015").getGraphFieldContainer("en").getVersion());
String uuid = tx(() -> folder("2015").getUuid());
VersionNumber version = tx(() -> folder("2015").getGraphFieldContainer("en").getVersion());

call(() -> client().updateNodeBinaryField(PROJECT_NAME, uuid, "en", version.toString(), FIELD_NAME, buffer, filename, "application/binary"));

Expand All @@ -158,19 +160,36 @@ public void testUpdateSetNull() {

// 3. Set the field to null one more time and assert that no new version was created
NodeResponse thirdResponse = updateNode(FIELD_NAME, null);
assertEquals("The field does not change and thus the version should not be bumped.", thirdResponse.getVersion(),
secondResponse.getVersion());
assertEquals("The field does not change and thus the version should not be bumped.", thirdResponse.getVersion(), secondResponse
.getVersion());
}
}

@Test
public void testUpdateDelete() throws IOException {
// 1. Upload a binary field
String uuid = tx(() -> folder("2015").getUuid());
Buffer buffer = TestUtils.randomBuffer(1000);
VersionNumber version = tx(() -> folder("2015").getGraphFieldContainer("en").getVersion());
call(() -> client().updateNodeBinaryField(PROJECT_NAME, uuid, "en", version.toString(), FIELD_NAME, buffer, "filename.txt",
"application/binary"));

// Clear the local binary storage directory to simulate a storage inconsistency
FileUtils.deleteDirectory(new File(Mesh.mesh().getOptions().getUploadOptions().getDirectory()));

// 2. Delete the node
call(() -> client().deleteNode(PROJECT_NAME, uuid));

}

@Test
@Override
public void testUpdateSetEmpty() {
try (Tx tx = tx()) {
// 1. Upload a binary field
String uuid = db().tx(() -> folder("2015").getUuid());
String uuid = tx(() -> folder("2015").getUuid());
Buffer buffer = TestUtils.randomBuffer(1000);
VersionNumber version = db().tx(() -> folder("2015").getGraphFieldContainer("en").getVersion());
VersionNumber version = tx(() -> folder("2015").getGraphFieldContainer("en").getVersion());
call(() -> client().updateNodeBinaryField(PROJECT_NAME, uuid, "en", version.toString(), FIELD_NAME, buffer, "filename.txt",
"application/binary"));

Expand All @@ -190,7 +209,7 @@ public void testUpdateSetEmptyFilename() {
String uuid = tx(() -> folder("2015").getUuid());
// 1. Upload a binary field
Buffer buffer = TestUtils.randomBuffer(1000);
VersionNumber version = db().tx(() -> folder("2015").getGraphFieldContainer("en").getVersion());
VersionNumber version = tx(() -> folder("2015").getGraphFieldContainer("en").getVersion());
call(() -> client().updateNodeBinaryField(PROJECT_NAME, uuid, "en", version.toString(), FIELD_NAME, buffer, "filename.txt",
"application/binary"));

Expand All @@ -217,9 +236,10 @@ public void testBinaryDisplayField() throws Exception {
NodeResponse nodeResponse1 = call(() -> client().createNode(PROJECT_NAME, nodeCreateRequest));

call(() -> client().updateNodeBinaryField(PROJECT_NAME, nodeResponse1.getUuid(), "en", nodeResponse1.getVersion(), "binary", buffer, fileName,
"application/binary"));
"application/binary"));

SchemaResponse binarySchema = call(() -> client().findSchemas(PROJECT_NAME)).getData().stream().filter(s -> s.getName().equals("binary_content")).findFirst().get();
SchemaResponse binarySchema = call(() -> client().findSchemas(PROJECT_NAME)).getData().stream().filter(s -> s.getName().equals(
"binary_content")).findFirst().get();
SchemaUpdateRequest schemaUpdateRequest = JsonUtil.readValue(binarySchema.toJson(), SchemaUpdateRequest.class);
schemaUpdateRequest.setDisplayField("binary");
waitForJobs(() -> {
Expand Down
Expand Up @@ -4,6 +4,7 @@
import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST;

import java.io.File;
import java.nio.file.NoSuchFileException;

import javax.inject.Inject;
import javax.inject.Singleton;
Expand Down Expand Up @@ -113,7 +114,18 @@ public static String getSegmentedPath(String binaryUuid) {
@Override
public Completable delete(String binaryUuid) {
String path = getFilePath(binaryUuid);
return FileSystem.newInstance(Mesh.vertx().fileSystem()).rxDelete(path).toCompletable();
return FileSystem.newInstance(Mesh.vertx().fileSystem())

.rxDelete(path).toCompletable()
// Dont fail if the file is not even in the local storage
.onErrorComplete(e -> {
Throwable cause = e.getCause();
if (cause != null) {
return cause instanceof NoSuchFileException;
} else {
return e instanceof NoSuchFileException;
}
});
}

}

0 comments on commit 7f982b8

Please sign in to comment.