From 8427cd79166fdf3dc985b69f0bbcbe1ea7ac43f4 Mon Sep 17 00:00:00 2001 From: tison Date: Sun, 28 May 2023 01:18:59 +0800 Subject: [PATCH] feat(bindings/java): implement Operator#delete Signed-off-by: tison --- .../java/org/apache/opendal/Operator.java | 8 ++- bindings/java/src/operator.rs | 35 +++++++++++ .../java/org/apache/opendal/OperatorTest.java | 61 +++++++++++++++++++ 3 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 bindings/java/src/test/java/org/apache/opendal/OperatorTest.java diff --git a/bindings/java/src/main/java/org/apache/opendal/Operator.java b/bindings/java/src/main/java/org/apache/opendal/Operator.java index 1a9fc64eebc5..499d76d233ec 100644 --- a/bindings/java/src/main/java/org/apache/opendal/Operator.java +++ b/bindings/java/src/main/java/org/apache/opendal/Operator.java @@ -66,7 +66,6 @@ private long requestId() { final long requestId = Math.abs(UUID.randomUUID().getLeastSignificantBits()); final CompletableFuture prev = registry.putIfAbsent(requestId, f); if (prev == null) { - return requestId; } } @@ -131,6 +130,11 @@ public CompletableFuture read(String path) { return registry().take(requestId); } + public CompletableFuture delete(String path) { + final long requestId = delete(nativeHandle, path); + return registry().take(requestId); + } + @Override protected native void disposeInternal(long handle); @@ -140,5 +144,7 @@ public CompletableFuture read(String path) { private static native long write(long nativeHandle, String path, String content); + private static native long delete(long nativeHandle, String path); + private static native long stat(long nativeHandle, String path); } diff --git a/bindings/java/src/operator.rs b/bindings/java/src/operator.rs index 8a375e06844b..b7e260019b35 100644 --- a/bindings/java/src/operator.rs +++ b/bindings/java/src/operator.rs @@ -182,6 +182,41 @@ async fn do_read<'local>(op: &mut Operator, path: String) -> Result jlong { + intern_delete(&mut env, op, path).unwrap_or_else(|e| { + e.throw(&mut env); + 0 + }) +} + +fn intern_delete(env: &mut JNIEnv, op: *mut Operator, path: JString) -> Result { + let op = unsafe { &mut *op }; + let id = request_id(env)?; + + let path = env.get_string(&path)?.to_str()?.to_string(); + + let runtime = unsafe { RUNTIME.get_unchecked() }; + runtime.spawn(async move { + let result = do_delete(op, path).await; + complete_future(id, result.map(|_| JValueOwned::Void)) + }); + + Ok(id) +} + +async fn do_delete(op: &mut Operator, path: String) -> Result<()> { + Ok(op.delete(&path).await?) +} + fn request_id(env: &mut JNIEnv) -> Result { let registry = env .call_static_method( diff --git a/bindings/java/src/test/java/org/apache/opendal/OperatorTest.java b/bindings/java/src/test/java/org/apache/opendal/OperatorTest.java new file mode 100644 index 000000000000..f7cc00c17b4d --- /dev/null +++ b/bindings/java/src/test/java/org/apache/opendal/OperatorTest.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.opendal; + +import static org.assertj.core.api.Assertions.assertThat; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CompletionException; +import org.apache.opendal.exception.OpenDALException; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class OperatorTest { + private Operator op; + + @BeforeEach + public void init() { + Map params = new HashMap<>(); + params.put("root", "/tmp"); + this.op = new Operator("Memory", params); + } + + @AfterEach + public void clean() { + this.op.close(); + } + + @Test + public void testCreateAndDelete() { + op.write("testCreateAndDelete", "Odin").join(); + assertThat(op.read("testCreateAndDelete").join()).isEqualTo("Odin"); + op.delete("testCreateAndDelete"); + op.stat("testCreateAndDelete") + .handle((r, e) -> { + assertThat(r).isNull(); + assertThat(e).isInstanceOf(CompletionException.class).hasCauseInstanceOf(OpenDALException.class); + OpenDALException.Code code = ((OpenDALException) e.getCause()).getCode(); + assertThat(code).isEqualTo(OpenDALException.Code.NotFound); + return null; + }) + .join(); + } +}