unDeletedKeys) {
+ omResponse.setSuccess(false);
+ StringBuffer errorMsg = new StringBuffer();
+ DeleteKeysResponse.Builder resp = DeleteKeysResponse.newBuilder();
+ for (OmKeyInfo key : unDeletedKeys) {
+ if(key != null) {
+ resp.addUnDeletedKeys(key.getProtobuf());
+ }
+ }
+ if (errorMsg != null) {
+ omResponse.setMessage(errorMsg.toString());
+ }
+ // TODO: Currently all delete operations in OzoneBucket.java are void. Here
+ // we put the List of unDeletedKeys into Response. These KeyInfo can be
+ // used to continue deletion if client support delete retry.
+ omResponse.setDeleteKeysResponse(resp.build());
+ omResponse.setStatus(OzoneManagerRatisUtils.exceptionToResponseStatus(ex));
+ return omResponse.build();
+ }
+
/**
* Add the client response to double buffer and set the flush future.
* For responses which has status set to REPLAY it is a no-op.
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeysDeleteRequest.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeysDeleteRequest.java
new file mode 100644
index 000000000000..b5e8dc8cbc41
--- /dev/null
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeysDeleteRequest.java
@@ -0,0 +1,214 @@
+/**
+ * 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.hadoop.ozone.om.request.key;
+
+import com.google.common.base.Preconditions;
+import org.apache.hadoop.ozone.audit.AuditLogger;
+import org.apache.hadoop.ozone.audit.OMAction;
+import org.apache.hadoop.ozone.om.OMMetadataManager;
+import org.apache.hadoop.ozone.om.OMMetrics;
+import org.apache.hadoop.ozone.om.OzoneManager;
+import org.apache.hadoop.ozone.om.exceptions.OMException;
+import org.apache.hadoop.ozone.om.exceptions.OMReplayException;
+import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
+import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerDoubleBufferHelper;
+import org.apache.hadoop.ozone.om.request.util.OmResponseUtil;
+import org.apache.hadoop.ozone.om.response.OMClientResponse;
+import org.apache.hadoop.ozone.om.response.key.OMKeyDeleteResponse;
+import org.apache.hadoop.ozone.om.response.key.OMKeysDeleteResponse;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
+ .DeleteKeysRequest;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
+ .DeleteKeysResponse;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
+ .OMRequest;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
+ .OMResponse;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
+ .KeyArgs;
+import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer;
+import org.apache.hadoop.ozone.security.acl.OzoneObj;
+import org.apache.hadoop.util.Time;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.KEY_NOT_FOUND;
+
+/**
+ * Handles DeleteKey request.
+ */
+public class OMKeysDeleteRequest extends OMKeyRequest {
+
+ private static final Logger LOG =
+ LoggerFactory.getLogger(OMKeysDeleteRequest.class);
+
+ public OMKeysDeleteRequest(OMRequest omRequest) {
+ super(omRequest);
+ }
+
+ @Override
+ public OMRequest preExecute(OzoneManager ozoneManager) throws IOException {
+ DeleteKeysRequest deleteKeyRequest =
+ getOmRequest().getDeleteKeysRequest();
+ Preconditions.checkNotNull(deleteKeyRequest);
+ List newKeyArgsList = new ArrayList<>();
+ for (KeyArgs keyArgs : deleteKeyRequest.getKeyArgsList()) {
+ newKeyArgsList.add(
+ keyArgs.toBuilder().setModificationTime(Time.now()).build());
+ }
+ DeleteKeysRequest newDeleteKeyRequest = DeleteKeysRequest
+ .newBuilder().addAllKeyArgs(newKeyArgsList).build();
+
+ return getOmRequest().toBuilder()
+ .setDeleteKeysRequest(newDeleteKeyRequest)
+ .setUserInfo(getUserInfo()).build();
+ }
+
+ @Override
+ @SuppressWarnings("methodlength")
+ public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager,
+ long trxnLogIndex, OzoneManagerDoubleBufferHelper omDoubleBufferHelper) {
+ DeleteKeysRequest deleteKeyRequest =
+ getOmRequest().getDeleteKeysRequest();
+
+ List deleteKeyArgsList = deleteKeyRequest.getKeyArgsList();
+ Set unDeletedKeys = new HashSet<>();
+ IOException exception = null;
+ OMClientResponse omClientResponse = null;
+ Result result = null;
+
+ OMMetrics omMetrics = ozoneManager.getMetrics();
+ omMetrics.incNumKeyDeletes();
+ Map auditMap = null;
+ String volumeName = "";
+ String bucketName = "";
+ String keyName = "";
+ List omKeyInfoList = new ArrayList<>();
+
+ AuditLogger auditLogger = ozoneManager.getAuditLogger();
+ OzoneManagerProtocolProtos.UserInfo userInfo =
+ getOmRequest().getUserInfo();
+
+ OMResponse.Builder omResponse = OmResponseUtil.getOMResponseBuilder(
+ getOmRequest());
+ OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
+ try {
+ for (KeyArgs deleteKeyArgs : deleteKeyArgsList) {
+ volumeName = deleteKeyArgs.getVolumeName();
+ bucketName = deleteKeyArgs.getBucketName();
+ keyName = deleteKeyArgs.getKeyName();
+ String objectKey = omMetadataManager.getOzoneKey(volumeName, bucketName,
+ keyName);
+ OmKeyInfo omKeyInfo = omMetadataManager.getKeyTable().get(objectKey);
+ omKeyInfoList.add(omKeyInfo);
+ unDeletedKeys.add(omKeyInfo);
+ }
+
+ // Check if any of the key in the batch cannot be deleted. If exists the
+ // batch will delete failed.
+ for (KeyArgs deleteKeyArgs : deleteKeyArgsList) {
+ volumeName = deleteKeyArgs.getVolumeName();
+ bucketName = deleteKeyArgs.getBucketName();
+ keyName = deleteKeyArgs.getKeyName();
+ auditMap = buildKeyArgsAuditMap(deleteKeyArgs);
+ // check Acl
+ checkKeyAcls(ozoneManager, volumeName, bucketName, keyName,
+ IAccessAuthorizer.ACLType.DELETE, OzoneObj.ResourceType.KEY);
+
+ String objectKey = omMetadataManager.getOzoneKey(
+ volumeName, bucketName, keyName);
+
+ // Validate bucket and volume exists or not.
+ validateBucketAndVolume(omMetadataManager, volumeName, bucketName);
+
+ OmKeyInfo omKeyInfo = omMetadataManager.getKeyTable().get(objectKey);
+
+ if (omKeyInfo == null) {
+ throw new OMException("Key not found: " + keyName, KEY_NOT_FOUND);
+ }
+
+ // Check if this transaction is a replay of ratis logs.
+ if (isReplay(ozoneManager, omKeyInfo, trxnLogIndex)) {
+ // Replay implies the response has already been returned to
+ // the client. So take no further action and return a dummy
+ // OMClientResponse.
+ throw new OMReplayException();
+ }
+ }
+
+ omClientResponse = new OMKeysDeleteResponse(omResponse
+ .setDeleteKeysResponse(DeleteKeysResponse.newBuilder()).build(),
+ omKeyInfoList, trxnLogIndex, ozoneManager.isRatisEnabled());
+ result = Result.SUCCESS;
+ } catch (IOException ex) {
+ if (ex instanceof OMReplayException) {
+ result = Result.REPLAY;
+ omClientResponse = new OMKeyDeleteResponse(createReplayOMResponse(
+ omResponse));
+ } else {
+ result = Result.FAILURE;
+ exception = ex;
+
+ omClientResponse = new OMKeyDeleteResponse(
+ createOperationKeysErrorOMResponse(omResponse, exception,
+ unDeletedKeys));
+ }
+
+ } finally {
+ addResponseToDoubleBuffer(trxnLogIndex, omClientResponse,
+ omDoubleBufferHelper);
+ }
+
+ // Performing audit logging outside of the lock.
+ if (result != Result.REPLAY) {
+ auditLog(auditLogger, buildAuditMessage(
+ OMAction.DELETE_KEY, auditMap, exception, userInfo));
+ }
+
+ switch (result) {
+ case SUCCESS:
+ omMetrics.decNumKeys();
+ LOG.debug("Key deleted. Volume:{}, Bucket:{}, Key:{}", volumeName,
+ bucketName, keyName);
+ break;
+ case REPLAY:
+ LOG.debug("Replayed Transaction {} ignored. Request: {}",
+ trxnLogIndex, deleteKeyRequest);
+ break;
+ case FAILURE:
+ omMetrics.incNumKeyDeleteFails();
+ LOG.error("Key delete failed. Volume:{}, Bucket:{}, Key{}." +
+ " Exception:{}", volumeName, bucketName, keyName, exception);
+ break;
+ default:
+ LOG.error("Unrecognized Result for OMKeyDeleteRequest: {}",
+ deleteKeyRequest);
+ }
+
+ return omClientResponse;
+ }
+}
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/key/OMKeysDeleteResponse.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/key/OMKeysDeleteResponse.java
new file mode 100644
index 000000000000..15231addaaef
--- /dev/null
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/key/OMKeysDeleteResponse.java
@@ -0,0 +1,130 @@
+/**
+ * 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.hadoop.ozone.om.response.key;
+
+import com.google.common.base.Optional;
+import org.apache.hadoop.hdds.utils.db.BatchOperation;
+import org.apache.hadoop.hdds.utils.db.cache.CacheKey;
+import org.apache.hadoop.hdds.utils.db.cache.CacheValue;
+import org.apache.hadoop.ozone.OmUtils;
+import org.apache.hadoop.ozone.om.OMMetadataManager;
+import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
+import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo;
+import org.apache.hadoop.ozone.om.response.OMClientResponse;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse;
+
+import javax.annotation.Nonnull;
+import java.io.IOException;
+import java.util.List;
+
+import static org.apache.hadoop.ozone.om.lock.OzoneManagerLock.Resource.BUCKET_LOCK;
+
+/**
+ * Response for DeleteKey request.
+ */
+public class OMKeysDeleteResponse extends OMClientResponse {
+ private List omKeyInfoList;
+ private boolean isRatisEnabled;
+ private long trxnLogIndex;
+
+ public OMKeysDeleteResponse(@Nonnull OMResponse omResponse,
+ @Nonnull List omKeyInfoList,
+ long trxnLogIndex, boolean isRatisEnabled) {
+ super(omResponse);
+ this.omKeyInfoList = omKeyInfoList;
+ this.isRatisEnabled = isRatisEnabled;
+ this.trxnLogIndex = trxnLogIndex;
+ }
+
+ /**
+ * For when the request is not successful or it is a replay transaction.
+ * For a successful request, the other constructor should be used.
+ */
+ public OMKeysDeleteResponse(@Nonnull OMResponse omResponse) {
+ super(omResponse);
+ checkStatusNotOK();
+ }
+
+ @Override
+ public void addToDBBatch(OMMetadataManager omMetadataManager,
+ BatchOperation batchOperation) throws IOException {
+
+ for (OmKeyInfo omKeyInfo : omKeyInfoList) {
+ // Set the UpdateID to current transactionLogIndex
+ omKeyInfo.setUpdateID(trxnLogIndex, isRatisEnabled);
+
+ // For OmResponse with failure, this should do nothing. This method is
+ // not called in failure scenario in OM code.
+ if (getOMResponse().getStatus() == OzoneManagerProtocolProtos.Status.OK) {
+ boolean acquiredLock = false;
+ String volumeName = "";
+ String bucketName = "";
+
+ try {
+ volumeName = omKeyInfo.getVolumeName();
+ bucketName = omKeyInfo.getBucketName();
+ String keyName = omKeyInfo.getKeyName();
+ acquiredLock =
+ omMetadataManager.getLock().acquireWriteLock(BUCKET_LOCK,
+ volumeName, bucketName);
+ // Update table cache.
+ omMetadataManager.getKeyTable().addCacheEntry(
+ new CacheKey<>(omMetadataManager.getOzoneKey(
+ volumeName, bucketName, keyName)),
+ new CacheValue<>(Optional.absent(), trxnLogIndex));
+
+ String ozoneKey = omMetadataManager.getOzoneKey(
+ omKeyInfo.getVolumeName(), omKeyInfo.getBucketName(),
+ omKeyInfo.getKeyName());
+ omMetadataManager.getKeyTable().deleteWithBatch(batchOperation,
+ ozoneKey);
+ // If a deleted key is put in the table where a key with the same
+ // name already exists, then the old deleted key information would
+ // be lost. To avoid this, first check if a key with same name
+ // exists. deletedTable in OM Metadata stores . The RepeatedOmKeyInfo is the structure that
+ // allows us to store a list of OmKeyInfo that can be tied to same
+ // key name. For a keyName if RepeatedOMKeyInfo structure is null,
+ // we create a new instance, if it is not null, then we simply add
+ // to the list and store this instance in deletedTable.
+ RepeatedOmKeyInfo repeatedOmKeyInfo =
+ omMetadataManager.getDeletedTable().get(ozoneKey);
+ repeatedOmKeyInfo = OmUtils.prepareKeyForDelete(
+ omKeyInfo, repeatedOmKeyInfo, omKeyInfo.getUpdateID(),
+ isRatisEnabled);
+ omMetadataManager.getDeletedTable().putWithBatch(batchOperation,
+ ozoneKey, repeatedOmKeyInfo);
+ if (acquiredLock) {
+ omMetadataManager.getLock().releaseWriteLock(
+ BUCKET_LOCK, volumeName, bucketName);
+ acquiredLock = false;
+ }
+ } finally {
+ if (acquiredLock) {
+ omMetadataManager.getLock()
+ .releaseWriteLock(BUCKET_LOCK, volumeName,
+ bucketName);
+ }
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicOzoneClientAdapterImpl.java b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicOzoneClientAdapterImpl.java
index defe3c1f48c0..a2f4c174b964 100644
--- a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicOzoneClientAdapterImpl.java
+++ b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicOzoneClientAdapterImpl.java
@@ -273,6 +273,25 @@ public boolean deleteObject(String keyName) {
}
}
+ /**
+ * Helper method to delete an object specified by key name in bucket.
+ *
+ * @param keyNameList key name list to be deleted
+ * @return true if the key is deleted, false otherwise
+ */
+ @Override
+ public boolean deleteObjects(List keyNameList) {
+ LOG.trace("issuing delete for key {}", keyNameList);
+ try {
+ incrementCounter(Statistic.OBJECTS_DELETED);
+ bucket.deleteKeys(keyNameList);
+ return true;
+ } catch (IOException ioe) {
+ LOG.error("delete key failed {}", ioe.getMessage());
+ return false;
+ }
+ }
+
public FileStatusAdapter getFileStatus(String key, URI uri,
Path qualifiedPath, String userName)
throws IOException {
diff --git a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicOzoneFileSystem.java b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicOzoneFileSystem.java
index 632ef4cbfa8e..f0df9b27a348 100644
--- a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicOzoneFileSystem.java
+++ b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicOzoneFileSystem.java
@@ -19,6 +19,7 @@
package org.apache.hadoop.fs.ozone;
import com.google.common.base.Preconditions;
+
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.BlockLocation;
import org.apache.hadoop.fs.CreateFlag;
@@ -49,6 +50,7 @@
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
+import java.util.ArrayList;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.LinkedList;
@@ -61,6 +63,8 @@
import static org.apache.hadoop.fs.ozone.Constants.LISTING_PAGE_SIZE;
import static org.apache.hadoop.fs.ozone.Constants.OZONE_DEFAULT_USER;
import static org.apache.hadoop.fs.ozone.Constants.OZONE_USER_DIR;
+import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_FS_ITERATE_BATCH_SIZE;
+import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_FS_ITERATE_BATCH_SIZE_DEFAULT;
import static org.apache.hadoop.ozone.OzoneConsts.OZONE_URI_DELIMITER;
import static org.apache.hadoop.ozone.OzoneConsts.OZONE_URI_SCHEME;
@@ -269,9 +273,12 @@ private class RenameIterator extends OzoneListingIterator {
}
@Override
- boolean processKey(String key) throws IOException {
- String newKeyName = dstKey.concat(key.substring(srcKey.length()));
- adapter.renameKey(key, newKeyName);
+ boolean processKey(List keyList) throws IOException {
+ // TODO RenameKey needs to be changed to batch operation
+ for(String key : keyList) {
+ String newKeyName = dstKey.concat(key.substring(srcKey.length()));
+ adapter.renameKey(key, newKeyName);
+ }
return true;
}
}
@@ -404,17 +411,12 @@ && listStatus(f).length != 0) {
}
@Override
- boolean processKey(String key) throws IOException {
- if (key.equals("")) {
- LOG.trace("Skipping deleting root directory");
- return true;
- } else {
- LOG.trace("deleting key:{}", key);
- boolean succeed = adapter.deleteObject(key);
- // if recursive delete is requested ignore the return value of
- // deleteObject and issue deletes for other keys.
- return recursive || succeed;
- }
+ boolean processKey(List key) throws IOException {
+ LOG.trace("deleting key:{}", key);
+ boolean succeed = adapter.deleteObjects(key);
+ // if recursive delete is requested ignore the return value of
+ // deleteObject and issue deletes for other keys.
+ return recursive || succeed;
}
}
@@ -474,7 +476,9 @@ public boolean delete(Path f, boolean recursive) throws IOException {
result = innerDelete(f, recursive);
} else {
LOG.debug("delete: Path is a file: {}", f);
- result = adapter.deleteObject(key);
+ List keyList = new ArrayList<>();
+ keyList.add(key);
+ result = adapter.deleteObjects(keyList);
}
if (result) {
@@ -729,7 +733,7 @@ private abstract class OzoneListingIterator {
* @return true if we should continue iteration of keys, false otherwise.
* @throws IOException
*/
- abstract boolean processKey(String key) throws IOException;
+ abstract boolean processKey(List key) throws IOException;
/**
* Iterates thorugh all the keys prefixed with the input path's key and
@@ -743,19 +747,35 @@ private abstract class OzoneListingIterator {
*/
boolean iterate() throws IOException {
LOG.trace("Iterating path {}", path);
+ List keyList = new ArrayList<>();
+ int batchSize = getConf().getInt(OZONE_FS_ITERATE_BATCH_SIZE,
+ OZONE_FS_ITERATE_BATCH_SIZE_DEFAULT);
if (status.isDirectory()) {
LOG.trace("Iterating directory:{}", pathKey);
while (keyIterator.hasNext()) {
BasicKeyInfo key = keyIterator.next();
LOG.trace("iterating key:{}", key.getName());
- if (!processKey(key.getName())) {
+ if (!key.getName().equals("")) {
+ keyList.add(key.getName());
+ }
+ if (keyList.size() >= batchSize) {
+ if (!processKey(keyList)) {
+ return false;
+ } else {
+ keyList.clear();
+ }
+ }
+ }
+ if (keyList.size() > 0) {
+ if (!processKey(keyList)) {
return false;
}
}
return true;
} else {
LOG.trace("iterating file:{}", path);
- return processKey(pathKey);
+ keyList.add(pathKey);
+ return processKey(keyList);
}
}
diff --git a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicRootedOzoneClientAdapterImpl.java b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicRootedOzoneClientAdapterImpl.java
index 9eb86896ce54..b4bb16f06721 100644
--- a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicRootedOzoneClientAdapterImpl.java
+++ b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicRootedOzoneClientAdapterImpl.java
@@ -453,6 +453,19 @@ public boolean deleteObject(String path) {
}
}
+ /**
+ * Helper method to delete an object specified by key name in bucket.
+ *
+ * @param pathList key name list to be deleted
+ * @return true if the key is deleted, false otherwise
+ */
+ @Override
+ public boolean deleteObjects(List pathList) {
+ // TODO: we will support deleteObjects in ofs.
+ LOG.error("ofs currently does not support deleteObjects");
+ return false;
+ }
+
/**
* Package-private helper function to reduce calls to getBucket().
* @param bucket Bucket to operate in.
diff --git a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/OzoneClientAdapter.java b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/OzoneClientAdapter.java
index 97dc5b31b20e..2b76c22c4d56 100644
--- a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/OzoneClientAdapter.java
+++ b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/OzoneClientAdapter.java
@@ -53,6 +53,8 @@ OzoneFSOutputStream createFile(String key, short replication,
boolean deleteObject(String keyName);
+ boolean deleteObjects(List keyName);
+
Iterator listKeys(String pathKey);
List listStatus(String keyName, boolean recursive,