Skip to content

Commit

Permalink
Merge pull request #37 from swisspush/recursive_delete
Browse files Browse the repository at this point in the history
Recursive delete
  • Loading branch information
mcweba authored May 16, 2017
2 parents 0f5519d + eb89e6e commit 47cd788
Show file tree
Hide file tree
Showing 35 changed files with 1,290 additions and 289 deletions.
2 changes: 0 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
language: java
jdk:
- oraclejdk8
env:
- EXTERNAL_REDIS=true
services:
- redis-server
script:
Expand Down
30 changes: 27 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

[![Build Status](https://travis-ci.org/swisspush/vertx-rest-storage.svg?branch=master)](https://travis-ci.org/swisspush/vertx-rest-storage)
[![codecov](https://codecov.io/gh/swisspush/vertx-rest-storage/branch/master/graph/badge.svg)](https://codecov.io/gh/swisspush/vertx-rest-storage)
[![](https://img.shields.io/github/issues-raw/swisspush/rest-storage.svg)](https://github.com/swisspush/vertx-rest-storage/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20)
[![GitHub contributors](https://img.shields.io/github/contributors/swisspush/rest-storage.svg)](https://github.com/swisspush/vertx-rest-storage/graphs/contributors)

[![GitHub release](https://img.shields.io/github/release/swisspush/rest-storage.svg)](https://github.com/swisspush/vertx-rest-storage/releases/latest)
[![Maven Central](https://img.shields.io/maven-central/v/org.swisspush/rest-storage.svg)]()

Persistence for REST resources in the filesystem or a redis database.
Expand All @@ -24,9 +28,15 @@ Runs either as a module or can be integrated into an existing application by ins

## Run it
1. clone the repository.
1. run `gradle build -x test`
1. run the fatjar with `java -jar build/libs/rest-storage-x.x.x-all.jar
1. you get a rest-storage, that stores to the filesystem in the directory where you started it. If you want to use the rest-storage with redis, you have to pass the configuration over a json file with `-conf conf.json`
2. Install and start Redis
* Debian/Ubuntu: `apt-get install redis-server`
* Fedora/RedHat/CentOS: `yum install redis`
* OS X: `brew install redis`
* [Windows](https://github.com/MSOpenTech/redis/releases/download/win-2.8.2400/Redis-x64-2.8.2400.zip)
* [Other](http://redis.io/download)
3. run `gradle build -x test`
4. run the fatjar with `java -jar build/libs/rest-storage-x.x.x-all.jar
5. you get a rest-storage, that stores to the filesystem in the directory where you started it. If you want to use the rest-storage with redis, you have to pass the configuration over a json file with `-conf conf.json`

## Features
### GET
Expand Down Expand Up @@ -71,6 +81,19 @@ The returned json response look like this:
}
```

### DELETE
Invoking DELETE request on a leave (document) deletes the resource.
> DELETE /storage/resources/resource_1
Invoking DELETE request on a collection deletes the collection and all its childern.
> DELETE /storage/resources/
#### Parameters

| Parameter | Description |
|:--------- | :----------- |
| recursive | When configuration property _confirmCollectionDelete_ is set to _true_, the url parameter _recursive=true_ has to be added to delete collections. |

### StorageExpand

The StorageExpand feature expands the hierarchical resources and returns them as a single concatenated json resource.
Expand Down Expand Up @@ -154,6 +177,7 @@ The following configuration values are available:
| prefix | common | / | The part of the URL path before this handler (aka "context path" in JEE terminology) |
| storageAddress | common | resource-storage | The eventbus address the mod listens to. |
| editorConfig | common | | Additional configuration values for the editor |
| confirmCollectionDelete | common | false | When set to _true_, an additional _recursive=true_ url parameter has to be set to delete collections |
| redisHost | redis | localhost | The host where redis is running on |
| redisPort | redis | 6379 | The port where redis is running on |
| expirablePrefix | redis | rest-storage:expirable | The prefix for expirable data redis keys |
Expand Down
Binary file removed redis/cygwin1.dll
Binary file not shown.
Binary file removed redis/redis-server.exe
Binary file not shown.
32 changes: 23 additions & 9 deletions src/main/java/org/swisspush/reststorage/FileSystemStorage.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
import io.vertx.core.file.FileProps;
import io.vertx.core.file.FileSystem;
import io.vertx.core.file.OpenOptions;
import io.vertx.core.logging.Logger;
import io.vertx.core.logging.LoggerFactory;
import org.swisspush.reststorage.util.LockMode;

import java.io.File;
import java.io.IOException;
import java.nio.file.DirectoryNotEmptyException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
Expand All @@ -19,6 +22,8 @@ public class FileSystemStorage implements Storage {
private String root;
private Vertx vertx;

private Logger log = LoggerFactory.getLogger(FileSystemStorage.class);

public FileSystemStorage(Vertx vertx, String root) {
this.vertx = vertx;
this.root = root;
Expand Down Expand Up @@ -132,7 +137,8 @@ public void put(String path, String etag, boolean merge, long expire, String loc

@Override
public void put(String path, String etag, boolean merge, long expire, String lockOwner, LockMode lockMode, long lockExpire, boolean storeCompressed, Handler<Resource> handler) {
throw new UnsupportedOperationException("Method 'put' with compressing resource is not yet implemented for the FileSystemStorage");
log.warn("PUT with storeCompressed option is not yet implemented in file system storage. Ignoring storeCompressed option value");
put(path, etag, merge, expire, "", LockMode.SILENT, 0, handler);
}

private void putFile(final Handler<Resource> handler, final String fullPath) {
Expand All @@ -152,19 +158,27 @@ private void putFile(final Handler<Resource> handler, final String fullPath) {
}

@Override
public void delete(String path, final Handler<Resource> handler) {
delete(path, "", LockMode.SILENT, 0, handler);
}

@Override
public void delete(String path, String lockOwner, LockMode lockMode, long lockExpire, final Handler<Resource> handler ) {
public void delete(String path, String lockOwner, LockMode lockMode, long lockExpire, boolean confirmCollectionDelete,
boolean deleteRecursive, final Handler<Resource> handler ) {
final String fullPath = canonicalize(path);

boolean deleteRecursiveInFileSystem = true;
if(confirmCollectionDelete && !deleteRecursive){
deleteRecursiveInFileSystem = false;
}
boolean finalDeleteRecursiveInFileSystem = deleteRecursiveInFileSystem;

fileSystem().exists(fullPath, event -> {
if (event.result()) {
fileSystem().deleteRecursive(fullPath, true, event1 -> {
fileSystem().deleteRecursive(fullPath, finalDeleteRecursiveInFileSystem, event1 -> {
Resource resource = new Resource();
if (event1.failed()) {
resource.exists = false;
if(event1.cause().getCause() != null && event1.cause().getCause() instanceof DirectoryNotEmptyException){
resource.error = true;
resource.errorMessage = "directory not empty. Use recursive=true parameter to delete";
} else {
resource.exists = false;
}
}
handler.handle(resource);
});
Expand Down
23 changes: 17 additions & 6 deletions src/main/java/org/swisspush/reststorage/RedisStorage.java
Original file line number Diff line number Diff line change
Expand Up @@ -772,12 +772,8 @@ public void exec(final int executionCounter) {
}

@Override
public void delete(String path, final Handler<Resource> handler) {
delete(path, "", LockMode.SILENT, 0, handler);
}

@Override
public void delete(String path, String lockOwner, LockMode lockMode, long lockExpire, final Handler<Resource> handler ) {
public void delete(String path, String lockOwner, LockMode lockMode, long lockExpire, boolean confirmCollectionDelete,
boolean deleteRecursive, final Handler<Resource> handler ) {
final String key = encodePath(path);
List<String> keys = Collections.singletonList(key);

Expand All @@ -791,6 +787,8 @@ public void delete(String path, String lockOwner, LockMode lockMode, long lockEx
expirableSet,
String.valueOf(System.currentTimeMillis()),
MAX_EXPIRE_IN_MILLIS,
confirmCollectionDelete ? "true" : "false",
deleteRecursive ? "true" : "false",
redisLockPrefix,
lockOwner,
lockMode.text(),
Expand Down Expand Up @@ -836,6 +834,10 @@ public void exec(final int executionCounter) {
if (log.isTraceEnabled()) {
log.trace("RedisStorage delete result: " + result);
}
if ("notEmpty".equals(result)) {
notEmpty(handler);
return;
}
if ("notFound".equals(result)) {
notFound(handler);
return;
Expand Down Expand Up @@ -868,6 +870,8 @@ public void cleanupRecursive(final Handler<DocumentResource> handler, final long
expirableSet,
"0",
MAX_EXPIRE_IN_MILLIS,
"false",
"true",
String.valueOf(System.currentTimeMillis()),
String.valueOf(bulkSize)
);
Expand Down Expand Up @@ -951,6 +955,13 @@ private void notFound(Handler<Resource> handler) {
handler.handle(r);
}

private void notEmpty(Handler<Resource> handler) {
Resource r = new Resource();
r.error = true;
r.errorMessage = "directory not empty. Use recursive=true parameter to delete";
handler.handle(r);
}

private void notModified(Handler<Resource> handler){
Resource r = new Resource();
r.modified = false;
Expand Down
Loading

0 comments on commit 47cd788

Please sign in to comment.